Copy link to clipboard
Copied
Here's a really odd one, happens on Mac OS X Lion 10.7.3 with InDesign CS5.5.
Enter the following little InDesign Script in ExtendScript Toolkit, and run it targeting InDesign CS5.5:
// Create a path of the form /Users/kris/Desktop or something similar, then resolve the path back to a File object
var fn = File(File("~").fsName + "/Desktop");
alert(fn.fsName + " exists: " + fn.exists);
If all is well, you get a dialog saying something like "/Users/kris/Desktop exists: true".
Nothing weird yet. Leave ExtendScript Toolkit running for a sec.
Now start up a Terminal window, and go to the /Volumes folder. Create a subfolder called Users (so that the folder /Volumes/Users exists on your computer).
Re-run the script.
Weirdness: I get "/Volumes/Users/kris/Desktop exists: false". Euh?
Anyone seen that before? Don't forget to remove "/Volumes/Users" again!
It is probably related to another weirdness. Run this one-liner:
alert(File("///").fsName);
You'll get "/Volumes" - but you'd expect to get "/", no?
Copy link to clipboard
Copied
Weird stuff! It happens on Snow Leopard as well...
Harbs
Copy link to clipboard
Copied
Weird.
Is this just idle experimentation? The Folder Class Folder.desktop (http://jongware.mit.edu/idcs5/pc_Folder.html) points directly to your desktop -- Windows compatible as well (I'm not sure your "~" notation is).
I don't know much about the low-level organization of Unix-style disk mountings, but isn't "/Volumes" more of a virtual construct by the OS than a physical one? Not at work today else I'd try (Dutch railroad made me wait for more than an hour last week 'cause of 1 inch of snow -- huh! "Extreme circumstances"! -- and now I have a severe headcold), but I think using plain "/" on a Windows set would bring you just to the root of the current drive, and I don't think there is a way to get a list of "mounted volumes" under Windows. The Mac solution, providing a higher-than-root-dir entry called Volumes solves this.
As for your "Users" question, well, you might be pushing against the boundaries of what's wise 😉 Folder names such as 'users' (lowercase) have special meanings in any OS, and trying to fiddle with Case Variations ("uSers", "deskTOP") may not only confuse ExtendScript -- which, remember, tries to mediate between Windows and Mac system folders -- but utlimately may bring down your Mac as well.
Copy link to clipboard
Copied
Hi Jongware!
Ignore the "~" stuff or the fact that I am using "/Users" to demonstrate it - it's my way to get the issue demonstrated in two lines.
I just tested some more: if I create any folder in the hard disk's root (e.g. /MyFolder) and put some file (e.g. test.txt) into it, there is no problem. Then, when I create the totally unrelated folder /Volumes/MyFolder, I suddenly get strange behavior, because for some odd reason, the ExtendScript path resolver prefers "/Volumes/MyFolder" instead of "/MyFolder" as a match to the expression "/MyFolder."
The thing is that "/whateveryouwant" gets resolved incorrectly on Mac OS X whenever there is a /Volumes/whateveryouwant folder. It gets resolved correctly if there is no /Volumes/whateveryouwant folder.
In other words, a constant string path gets interpreted differently dependent on the existence or non-existence of a seemingly unrelated folder. Internally, the algorithm that resolves a string path into a File or Folder object is using some incorrect logic, IMHO.
To try it out: create directory "/MyFolder", create a file "/MyFolder/text.txt" (keep in mind, we're not discussing whether that is wise or not - that's another discussion).
Now run
f = File("/MyFolder/test.txt");
alert(f.exists);
You get 'true'. Ok
Now create the directory "/Volumes/MyFolder" and re-run the same script
You get 'false'.
Now, before you say "Don't create any folders in /Volumes, then!" - the problem is that our users do this all the time! E.g. they have a USB drive called 'Users'. They insert it - KABOOM! Suddenly our scripts lose access to /Users/... because inserting that USB drive created the mount point /Volumes/Users. So, no - it's not idle experimentation. It's blood, sweat and tears 😞
Copy link to clipboard
Copied
Yeah. This seems to me a pretty major bug in ExtendScript (it's not limited to InDesign).
I'd log this bugger, and bug someone at Adobe to get this fixed. I wish I knew who to bug about that...
Harbs
Copy link to clipboard
Copied
There's a whole section about this in the Guide. Seems vaguely relevant...
Volume and drive names
A volume or drive name can be the first part of an absolute path in URI
notation. The values are interpreted
according to the platform.
Mac OS volumes
When Mac OS X starts, the startup volume is the root directory of the
file system. All other volumes,
including remote volumes, are part of the /Volumes directory. The File
and Folder objects use these
rules to interpret the first element of a path name:
➤ If the name is the name of the startup volume, discard it.
➤ If the name is a volume name, prepend /Volumes.
➤ Otherwise, leave the path as is.
Ariel
Copy link to clipboard
Copied
Interesting. Faulty logic if you ask me...
This seems to be a workable workaround assuming there's a good way of discovering the root volume name: (any suggestions on that front?)
var rootName = "Gabe";
var fn = File(File("~").fsName + "/Desktop");
alert(fn.fsName + " exists: " + fn.exists);
fn = File(fn.fsName.replace(/^\/Volumes/,"/" + rootName));
alert(fn.fsName + " exists: " + fn.exists);
Harbs
Copy link to clipboard
Copied
...assuming there's a good way of discovering the root volume name: (any suggestions on that front?)
var rootName = app.doScript("tell application \"Finder\" to return name of startup disk", ScriptLanguage.APPLESCRIPT_LANGUAGE);
Copy link to clipboard
Copied
Thanks Jeff.
Yes. That'll work nicely for InDesign. Of course only InDesign has doScript(). I suppose system() will work for the apps that support that.
I wonder if there's an environment variable which stores the startup disk name...
Harbs
Copy link to clipboard
Copied
var f = File("///").parent;
alert(f.displayName);
Copy link to clipboard
Copied
Very nice!
So I guess the "solution" is something like this:
var fn = normalizeFilePath(File(File("~").fsName + "/Desktop"));
function normalizeFilePath(file){
if(File.fs != "Macintosh"){return file}
return File(file.fsName.replace(/^\/Volumes/,"/" + File("///").parent.displayName));
}
Harbs
Copy link to clipboard
Copied
Thanks for pointing out at File and Folder handle paths differently so you can get the username from File.
Copy link to clipboard
Copied
Building on Harb's solution: a wrapper for 'new File'. Haven't tested it extensively yet, and I am not sure it's covering all the bases, so take it for what it's worth:
function newFile(filePath)
{
do
{
try
{
var retVal = new File(filePath);
if (File.fs != "Macintosh")
{
break;
}
if (retVal.fsName == filePath)
{
break;
}
var rootVolumeName = File("/").parent.displayName;
retVal = new File(retVal.fsName.replace(/^\/Volumes\//,"/" + rootVolumeName + "/"));
}
catch (error)
{
retVal = null;
}
}
while (false);
return retVal;
}
Copy link to clipboard
Copied
Funny. Nearly identical, eh!
I tried to make sure that any 'legal' accesses to /Volumes are also covered (whether ill-advised or not).
Copy link to clipboard
Copied
RorohikoKris wrote:
I tried to make sure that any 'legal' accesses to /Volumes are also covered (whether ill-advised or not).
Yeah. I noticed that. Nice touch.
Copy link to clipboard
Copied
Looks pretty good to me. The only way I can see breaking this, is if there's more bugs that'll change the file path that we don't know about...
Copy link to clipboard
Copied
I'm still a bit groggy due to aformentioned PT shenanigans (now they're discussing reduced services the entire week, can you believe it!) but is this related to last month's thread on the Illustrator forum?
"Error on opening file after upgrade to Lion" -- http://forums.adobe.com/thread/938672?tstart=0
Copy link to clipboard
Copied
[Jongware] wrote:
...but is this related to last month's thread on the Illustrator forum?
Nope. This is not Lion specific, and it has nothing to do with a file prefix. Nothing to do with openDialog() either...
Harbs
Copy link to clipboard
Copied
It seems the Folder.create() function is immune to this hack.
I can successfully reference a folder object on my desktop using the hack function:
var folder = Folder(newFile("~/Desktop/Test"));
But if you still have a Users folder in your Volumes, calling:
folder.create();
Will return true but won't create the folder on the desktop.
Where was it created? In the /Volumes/Users directory!
=> /Volumes/Users/[USERNAME]/Desktop/Test
Joris
Copy link to clipboard
Copied
Hi Joris,
Ugh! I just tried using changePath() to try to move the folder to the correct location afterwards, but it does not seem to work as I'd hoped...
Harbs
Copy link to clipboard
Copied
I guess using AppleScript to create the folder would be a workaround, but all this stuff is pretty bad...
Copy link to clipboard
Copied
Try this wrapper for new Folder(...):
function newFolder(filePath)
{
var retVal;
do
{
try
{
if (File.fs != "Macintosh")
{
break;
}
if (filePath.match(/^\/Volumes\//i) != null)
{
break;
}
if (filePath.charAt(0) == "~")
{
filePath = File("~").fsName + filePath.substr(1);
}
else if (filePath.charAt(0) != "/")
{
break;
}
var rootVolumeName = File("/").parent.displayName;
retVal = new Folder("/Volumes/" + rootVolumeName + "/" + filePath);
}
catch (error)
{
}
}
while (false);
if (retVal == null)
{
retVal = new Folder(filePath);
}
return retVal;
}
If /Volumes/Users exists on my system so it interferes with the ExtendScript file handling, then:
var folder = new Folder("~/Desktop/Test");
folder.create();
fails, but
var folder = newFolder("~/Desktop/Test");
folder.create();
succeeds
Copy link to clipboard
Copied
That works!
I modified both functions a little bit to work for the following test cases:
They also work with legal accesses, (if you actually wanted to create something at /Volumes/Users)
i.e:
You can also use them correctly in combination with File/Folder objects:
i.e:
var folder = NewFolder("~/Desktop/TestFolder");
var sameFolder = NewFolder(folder);
var folder = NewFolder("~/Desktop/TestFolder");
var file = NewFile(folder + "/TestFile.txt");
Functions:
function NewFile(in_path)
{
var file;
try
{
do
{
if (in_path instanceof File)
var path = in_path.absoluteURI;
else if (in_path instanceof Folder)
var path = in_path.absoluteURI;
else
var path = in_path;
file = new File(path)
if (File.fs != "Macintosh")
break;
var filePath = file.fsName;
if (filePath == path) // File path wasn't changed by Extendscript
break;
if (filePath.match(/^\/Volumes\//i) == null) // File path isn't a Volumes path
break;
var rootVolumeName = File("/").parent.displayName;
filePath = filePath.replace(/^\/Volumes\//,"/" + rootVolumeName + "/")
file = new File(filePath);
}
while (false);
}
catch (err)
{
file = null;
}
return file;
}
// ******************************
function NewFolder(in_path)
{
var folder;
try
{
do
{
if (in_path instanceof File)
var path = in_path.absoluteURI;
else if (in_path instanceof Folder)
var path = in_path.absoluteURI;
else
var path = in_path;
folder = new Folder(path)
if (File.fs != "Macintosh")
break;
var folderPath = folder.fsName;
if (folderPath == path) // Folder path wasn't changed by Extendscript
break;
if (path.charAt(0) == "~")
path = File("~").fsName + path.substr(1);
if (path.charAt(0) != "/") // Not an absolute path
break;
var rootVolumeName = File("/").parent.displayName;
folder = new Folder("/Volumes/" + rootVolumeName + path);
}
while (false);
}
catch (err)
{
folder = null;
}
return folder;
}
Joris
Copy link to clipboard
Copied
Great stuff!
Harbs
Copy link to clipboard
Copied
8 years later and I encounter the same problem. Thank you Kris and Joris!