24 Replies Latest reply on Jun 3, 2016 1:02 PM by kenpelletier

    ExtendScript Oddity with File/Folder on Mac OS X

    RorohikoKris Level 2

      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?

        • 1. Re: ExtendScript Oddity with File/Folder on Mac OS X
          Harbs. Level 6

          Weird stuff! It happens on Snow Leopard as well...

           

          Harbs

          • 2. Re: ExtendScript Oddity with File/Folder on Mac OS X
            [Jongware] Most Valuable Participant

            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.

            • 3. Re: ExtendScript Oddity with File/Folder on Mac OS X
              RorohikoKris Level 2

              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 :-(

              • 4. Re: ExtendScript Oddity with File/Folder on Mac OS X
                Harbs. Level 6

                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

                • 5. Re: ExtendScript Oddity with File/Folder on Mac OS X
                  TᴀW Adobe Community Professional & MVP

                  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

                  • 6. Re: ExtendScript Oddity with File/Folder on Mac OS X
                    Harbs. Level 6

                    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

                    • 7. Re: ExtendScript Oddity with File/Folder on Mac OS X
                      absqua Level 4

                      ...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);
                      
                      • 8. Re: ExtendScript Oddity with File/Folder on Mac OS X
                        Harbs. Level 6

                        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

                        • 9. Re: ExtendScript Oddity with File/Folder on Mac OS X
                          RorohikoKris Level 2

                          var f = File("///").parent;

                          alert(f.displayName);

                          • 10. Re: ExtendScript Oddity with File/Folder on Mac OS X
                            Harbs. Level 6

                            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

                            • 11. Re: ExtendScript Oddity with File/Folder on Mac OS X
                              RorohikoKris Level 2

                              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;

                              }



                              • 12. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                RorohikoKris Level 2

                                Funny. Nearly identical, eh!

                                 

                                I tried to make sure that any 'legal' accesses to /Volumes are also covered (whether ill-advised or not).

                                • 13. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                  Harbs. Level 6

                                  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...

                                  • 14. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                    Harbs. Level 6

                                    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.

                                    • 15. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                      [Jongware] Most Valuable Participant

                                      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

                                      • 16. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                        Harbs. Level 6

                                        [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

                                        • 17. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                          Joris Coppieters Level 1

                                          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

                                          • 18. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                            Harbs. Level 6

                                            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

                                            • 19. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                              Harbs. Level 6

                                              I guess using AppleScript to create the folder would be a workaround, but all this stuff is pretty bad...

                                              • 20. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                                RorohikoKris Level 2

                                                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

                                                • 21. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                                  Joris Coppieters Level 1

                                                  That works!

                                                   

                                                  I modified both functions a little bit to work for the following test cases:

                                                   

                                                  • NewFolder("~/Desktop/TestFolder");
                                                  • NewFolder("/Users/[USERNAME]/Desktop/TestFolder");
                                                  • NewFolder("/Volumes/[ROOTVOLUME]/Users/[USERNAME]/Desktop/TestFolder");
                                                  • NewFolder("/[ROOTVOLUME]/Users/[USERNAME]/Desktop/TestFolder");

                                                   

                                                  • NewFile("~/Desktop/TestFile.txt");
                                                  • NewFile("/Users/[USERNAME]/Desktop/TestFile.txt");
                                                  • NewFile("/Volumes/[ROOTVOLUME]/Users/[USERNAME]/Desktop/TestFile.txt");
                                                  • NewFile("/[ROOTVOLUME]/Users/[USERNAME]/Desktop/TestFile.txt");

                                                   

                                                  They also work with legal accesses, (if you actually wanted to create something at /Volumes/Users)

                                                   

                                                    i.e:

                                                  • NewFolder("/Volumes/Users/TestFolder");
                                                  • NewFile("/Volumes/Users/TestFile.txt");

                                                   

                                                  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

                                                  • 23. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                                    shopsinm Level 1

                                                    Thanks for pointing out at File and Folder handle paths differently so you can get the username from File.

                                                    • 24. Re: ExtendScript Oddity with File/Folder on Mac OS X
                                                      kenpelletier Level 1

                                                      In a really weird twist... this article helped me in my situation!

                                                       

                                                      I was getting a "Directory does not exist: /Volumes/Users/mac/desktop/render/" error every time I used terminal renderer. The problem wound up being that I have a server mount which is also called "Users" and houses user folders for folks in the office. Presumably, the path to my render folder set in AE would work fine, but in terminal presented with two /Volumes/Users paths, it chose the wrong one and errored out looking for the rest of the path. Once I unmounted this server, the terminal renderer completed with no errors. Adobe guys, there seems to be a glitch with how paths are read here, no?