Search code examples
cocoaapplescriptosx-mountain-lionapplescript-objc

Retrieve list of selected files from active finder window using NSAppleScript


Does any one know how I could retrieve a list of selected files from the active finder window? I have no experience at all with AppleScript and your help will be appreciated!

I tried using the following code from another answer on SO, but I could get it to return anything at all. No error, no results, just nothing. I understand that even if it did work, then it would just get me the first file, I need the complete selection of files..

NSAppleScript *script = [[NSAppleScript alloc] initWithSource:
                          @"tell application \"Finder\"\n"
                          "set selectedItems to selection\n"
                          "if ((count of selectedItems) > 0) then\n"
                          "set selectedItem to (item 1 of selectedItems) as alias\n"
                          "container window of selectedItem\n"
                          "end if\n"
                          "end tell\n"];

if (script == nil) {
    NSLog(@"failed to create script!");
}

NSAppleEventDescriptor *result = [script executeAndReturnError:&errorMessage];
if (result) {
    // POSIX path returns trailing /'s, so standardize the path
    NSString *path = [[result stringValue] stringByStandardizingPath];
}

for (id key in errorMessage) {
    NSLog(@"key: %@, value: %@", key, [errorMessage objectForKey:key]);
}

Edit

I was printing out the error dictionary before executing the script, that is why there was no error. This is what I get when I select two files in a finder window:

2013-07-23 13:36:14.817 myAPP[12959:303] key: NSAppleScriptErrorMessage, value: Finder got an error: Can’t get container window of document file "myAPP-logo-white-n-black.png" of folder "untitled folder" of folder "Desktop" of folder "Shumais" of folder "Users" of startup disk.
2013-07-23 13:36:14.817 myAPP[12959:303] key: NSAppleScriptErrorRange, value: NSRange: {151, 16}
2013-07-23 13:36:14.817 myAPP[12959:303] key: NSAppleScriptErrorBriefMessage, value: Can’t get container window of document file "myAPP-logo-white-n-black.png" of folder "untitled folder" of folder "Desktop" of folder "Shumais" of folder "Users" of startup disk.
2013-07-23 13:36:14.818 myAPP[12959:303] key: NSAppleScriptErrorNumber, value: -1728
2013-07-23 13:36:14.818 myAPP[12959:303] key: NSAppleScriptErrorAppName, value: Finder

Thank You! Shumais


Solution

  • UPDATE 2. So I just realised that my and the other answer is getting you the container of the first file. Because for my part I red the code you supplied and corrected it rather than pay attention to you saying you need a path list

    So here is some code that get the list ( as posix paths of all the selected items in the finder.

     NSMutableArray * pathArray =[[NSMutableArray alloc ] initWithCapacity:10];
        NSDictionary* errorMessage = [NSDictionary dictionary];
        NSString *code = @"set biglist to {}\n tell application \"Finder\" to set theSeletion to (get selection)\n if (count of theSeletion) > 0 then\n repeat with i from 1 to number of items in theSeletion\n set this_item to POSIX path of (item i of theSeletion as alias)\n copy this_item to end of biglist\n end repeat\n return biglist\n  end if\n  ";
        NSLog(@"code =  %@ ",code);
        NSAppleScript *script = [[NSAppleScript alloc] initWithSource:code];
        NSAppleEventDescriptor *result = [script executeAndReturnError:&errorMessage];
    
        count = [result numberOfItems];
        for (int i = 1; i <= count; ++i) {
        NSAppleEventDescriptor *desc =  [result descriptorAtIndex:i]  ;
        id thisPath = [desc stringValue];
    
    
            [pathArray addObject:thisPath];
    
    
        }
    
        if (script == nil) {
            NSLog(@"failed to create script!");
        }
    
        for (id key in errorMessage) {
            NSLog(@"key: %@, value: %@", key, [errorMessage objectForKey:key]);
        }
    
    
          NSLog(@"pathArray =  %@ ",pathArray);
    
        [pathArray release];
    

    This will return an Array:

    pathArray = ( "/Users/Shumais/Desktop/newFolder/testdrop/image1.jpg", "/Users/Shumais/Desktop/newFolder/testdrop/image2.jpg", "/Users/Shumais/Desktop/newFolder/testdrop/image3.jpg" )

    I have left the other code as it may be useful

    UPDATED CODE. Both tested and work.

     NSDictionary* errorMessage = [NSDictionary dictionary];
        NSString *code = @"tell application \"Finder\"\n set theSeletion to (get selection)\n if (count of theSeletion) > 0 then\n return   (container of item 1 of theSeletion as alias)  as string \n end if\n end tell";
         NSLog(@"code =  %@ ",code);
        NSAppleScript *script = [[NSAppleScript alloc] initWithSource:code];
        NSAppleEventDescriptor *result = [script executeAndReturnError:&errorMessage];
    
        if (script == nil) {
            NSLog(@"failed to create script!");
        }
        if (result) {
            // POSIX path returns trailing /'s, so standardize the path
            NSString *path = [[result stringValue] stringByStandardizingPath];
    
              NSLog(@"path =  %@ ",path);
        }
    
        for (id key in errorMessage) {
            NSLog(@"key: %@, value: %@", key, [errorMessage objectForKey:key]);
        }
    

    Returns --> "Macintosh HD:Users:Shumais:Desktop:"

    Or to get the POSIX path:

     NSDictionary* errorMessage = [NSDictionary dictionary];
        NSString *code = @"tell application \"Finder\"\n set theSeletion to (get selection)\n if (count of theSeletion) > 0 then\n return POSIX path of (container of item 1 of theSeletion as alias)\n end if\n end tell";
         NSLog(@"code =  %@ ",code);
        NSAppleScript *script = [[NSAppleScript alloc] initWithSource:code];
        NSAppleEventDescriptor *result = [script executeAndReturnError:&errorMessage];
    
        if (script == nil) {
            NSLog(@"failed to create script!");
        }
        if (result) {
            // POSIX path returns trailing /'s, so standardize the path
            NSString *path = [[result stringValue] stringByStandardizingPath];
    
              NSLog(@"path =  %@ ",path);
        }
    
        for (id key in errorMessage) {
            NSLog(@"key: %@, value: %@", key, [errorMessage objectForKey:key]);
        }
    

    returns -> "/Users/Shumais/Desktop/untitled folder"