AppleScript error when trying to copy home folder to shared drive - macos

So, i'm working on a script that copies the home folder to a mounted shared drive folder. But i'm getting the following error:
"Handler can't handle objects of this class number -10010"
This is the code I came up with following the example of other code i've seen on here. I'm guessing that it is the way i'm telling finder to duplicate.
set vserver to ("/Volumes/sharedfolder")
set source to ("/Users/user")
tell application "Finder"
duplicate source to vserver
end tell
How else can I write this?
I've also tried running a boolean test to see if Finder saw the shared folder or my home folder and it retured false. (but only one false when it should have returned two)
tell application "Finder"
setaBoolean1 to get (exists vserver)
setaBoolean1 to get (exists source)
end tell

set vserver to ("/Volumes/sharedfolder")
The line above sets the variable vserver to a string object consisting of "/Volumes/sharedfolder". Likewise, the set source to "/Users/user" line sets source to a string object containing "/Users/user". Note that strings are not what the Finder is expecting when you're telling it to duplicate items.
The tell app Finder line is basically trying to tell the Finder to duplicate one string into another string, which it doesn't know how to do (hence the Handler can't handle objects of this class message).
What you need to do is to, instead of creating strings, create some sort of file system reference to those folders, so that the Finder knows how to deal with them.
There are numerous ways to do this, but the method I found that works (which uses the same POSIX style path format) is the following:
set vserver to POSIX file "/Volumes/sharedfolder"
set source to POSIX file "/Users/user"
tell application "Finder"
duplicate source to vserver
end tell

Related

Running into problem when using choose folder in AppleScript

So I have a folder with many files whose count changes regularly and I need to count them using AppleScript. I had a script like this in place at first:
tell application "Finder" to return count of (every file of (choose folder))
Later, while researching, I found something like this:
tell application "Finder" to return count files of (choose folder)
However neither seems to work. I can't use System Events either since the choose folder just results in an endless run loop when used inside a System Events-tell block.
The error I get is:
"Finder got an error: Expected a reference." number -1727
If you are looking to get just the count of files within the selected folder and not subfolders or files within subfolders, then use:
tell application "Finder" to return count files of container (choose folder)
If you want the full count of items within a folder, then use:
tell application "Finder" to return count items of entire contents of container (choose folder)

AppleScript: How do I set a property to a file path?

Background
I am working on an AppleScript application (ASOBJ) through Xcode and frequently access (update/retrieve) various entries from a .plist file that I have created.
Whenever I need to access the data, I use the following command:
set thePropertyListFilePath to POSIX path of (path to resource "Data.plist")
tell application "System Events"
tell property list file thePropertyListFilePath
set myAge to value of property list item "userAge" as text
end tell
end tell
The problem
My project is in development and file names / paths change all too frequently.
I want to make a property thePropertyListFilePath : [...] at the top of my project to be able to change the path and name of the file in one place, rather than multiple.
I would like to use property over set as it just works better in my case.
At the top of my code:
property thePropertyListFilePath : POSIX path of (path to resource "Data.plist")
Does not compile because:
Error: Resource not found.
Analysis
I know for a fact that the resource Data.plist is where it is supposed to be and the paths correct because it works fine from inside my top code snippet.
Leaving me with the question:
How do I set a property to a file path?
Any insight into why this error is thrown and how to correctly set the property to this (relative) file path is greatly appreciated. I am aware of this question, but it does not present an applicable solution. Cheers.
Edit
I now seem to be getting a related error:
System Events got an error: 'This
Mac:Users:myuser:Library:Developer:Xcode:DerivedData:ProjectName:Build:Products:Debug:ProjectName.app:Contents:Resources:Data.plist'
is not a property list file. (error -1728)
Some validation needs to take place before app has launched so I wrote my code in the applicationWillFinishLaunching_ section - this shouldn't present any problems.
I know that the file is there and a .plist format so I am thinking it could simply be the tell ... statements around it.
In the past, I used set currentVersion to (current application's class "NSBundle"'s mainBundle()'s objectForInfoDictionaryKey:"CFBundleShortVersionString") as text to access the version number from the Info.plist in one go. Is it possible to use a similar one-liner without the tell statements to retrieve userAge from my own plist file?
Don't do that. Never declare a property with a relative path. The value will set at compile time and will never change. That makes the benefit of the relative path useless.
Declare the property as empty string
property thePropertyListFilePath : ""
and set it in applicationDidFinishLaunching
on applicationDidFinishLaunching_(aNotification)
set thePropertyListFilePath to POSIX path of (path to resource "Data.plist")
end applicationWillFinishLaunching_
However as you are developing AppleScriptObjC I recommend the Cocoa way (longer but more efficient)
set thePropertyListFilePath to (current application's NSBundle's mainBundle()'s pathForResource_ofType_("Data", "plist")) as text

Apple script to delete files with custom label (mavericks)

I'm trying to create a simple script to delete files based on a custom label I've already assign.
I'm currently trying to limit the search for the script to a test folder, but ultimately I want the script to search in all the user folder and get all the files from several different locations. I may need authentication for the process.
But so far I have this
tell application "Finder" delete (every item of folder
"/users/ro/documents/Erase test" whose label is "test") end tell
and I get this error
error "Finder got an error: Can’t get folder
\"/users/ro/documents/Erase test\"." number -1728 from folder
"/users/ro/documents/Erase test"
As I said I don't really know much about scripts, so I don't know all the terms but I hope someone can point me in the right direction.
Saw this late.
Tested this on 10.6.8 and will jump on a Mavericks machine to test, but this should work:
set f to choose folder
tell application "Finder"
delete (every item of f whose label index is 1)
end tell
A few notes about your attempt:
1) AppleScript doesn't 'natively' understand POSIX paths (but coercion to/from is possible), so (as I have it) "choose folder" returns what is known as an alias (not to be confused with a string -- but again, coercions to/from strings/aliases are simple).
2) note that the label is recognized as "label index", which is an integer.
3) you could/should test by taking out "delete" in that line to return a list of those items.
[edit] yes, this is fine on Mavericks.

Can I put shared applescript code in a separate file and load it in various scripts?

I'm starting to poke around with Applescript and am looking at writing a few scripts for managing windows. A common task they will all need is to get the current screen size.
I've created a screen_size subroutine that seems to work, and I want to be able to share that with all my scripts. However, I can't figure out a way to put that in a separate file that I can load in my other scripts. I tried creating a separate screen_size.scpt file and use load script "screen_size.scpt", but I get an error about "can't make "screen_size.scpt" into a type file".
There has to be a way to do this, but I haven't been able to find anything online about how to do it.
EDIT:
The POSIX stuff suggested isn't working for me. I'm able to create the file object, but it refuses to convert to an alias, saying it can't find the file (looks like the POSIX file stays relative instead of expanding fully).
I found a suggestion online to use Finder, and have gotten the following working to get an alias:
tell application "Finder"
set _myPath to container of (path to me) as text
end tell
set _loadPath to (_myPath & "screen_size.scpt")
set _loadAlias to alias _loadPath
However, the next line fails with a syntax error, claiming that _loadAlias isn't a variable:
property _ScreenSize : load script _loadAlias
Every variation of this I've tried (doing the alias in the load call, etc) fails, always claiming the variable doesn't exist, even though I know it's being set and working as I can display it. What's going on? Why is it claiming a variable doesn't exist when it obviously does?
AppleScript is doing some really weird things when saving and I haven't figured out what's going on, but I ended up getting something to work.
Here's what I have:
on load_script(_scriptName)
tell application "Finder"
set _myPath to container of (path to me) as text
end tell
set _loadPath to (_myPath & _scriptName)
load script (alias _loadPath)
end load_script
set _ScreenSize to load_script("screen_size.scpt")
set _bounds to _ScreenSize's screen_size()
-- ...
The other answers were saying to set _ScreenSize as a property, but that would cause a syntax error which prevented me from ever saving the file. When I did it just using set it worked.
I wasn't ever able to get the POSIX path stuff suggested to work, but poking Finder for the path worked fine.
In order to execute an action from another script, you'll have to create an handler in the script you're going to load (in your answer you already did this with "screen_size()".
In your case this script will be "screen_size.scpt".
So "screen_size.scpt" will have to look something like this:
on screen_size()
--your actions
return [yourvalue] --the value you want to pass to the other script
end screen_size()
The script you'll load it from will have to look like this:
tell application "Finder"
set _myPath to (container of (path to me) as text & "screen_size.scpt") as alias
end tell
set _ScreenSizeScript to load script _myPath
set _bounds to _ScreenSizeScript's screen_size()
If it doesn't work, or you don't understand me completely, feel free to ask (:
Yes there is a way to do this. Load the file into a property and access it that way
property _ScreenSize : load script (alias "pathtoscript")
_ScreenSize's doStuff()
and for relative paths try this:
set p to "./screen_size.scpt"
set a to POSIX file p
so perhaps this will work:
set p to "./screen_size.scpt"
set a to POSIX file p
property _ScreenSize : load script (alias a)
_ScreenSize's doStuff()
I have people using my libraries on a daily basis, so I first ensure the library is here before calling it.
Let's say I have a library "Lib.Excel.app" (save as non-editable application with Satimage's Smile).
At the beginning of a script that makes use of it, I "load" the library by using this code :
set commonCodeFile to (path to library folder as string) & "Scripts:CommonLibraries:Lib.Excel.app"
tell application "Finder"
if not (exists (file commonCodeFile)) then error ("\"Lib.Excel\"
" & "
should be found in folder
" & "
scroll > CommonLibraries")
end tell
global cc -- make it short and easy to write :)
set cc to load script alias ccFile
Then when I have to use a function from the lib, I just call it like this :
set {what, a} to cc's veryNiceFunction()
Yes you can. You need the full path to the script however.
I believe you can still use "path to me" to get the path to the app executing the current script, and you can then modify that path to point to your sub-folder containing the scripts.
I used this technique to get around AppleScripts (former) 32k text size limits years ago for some really large/complex IRC scripting.
I think I still have all those old scripts in my G4, which is under the desk in my office at work. Sadly it's behind a Enet switch and I can't VNC into it otherwise I'd have tons of sample code to post.
You CAN load the script in a variable, but you have to declare it first.
property _ScreenSize : missing value
tell application "Finder" to set _myPath to container of (path to me) as text
set _loadPath to (_myPath & "screen_size.scpt")
set _loadAlias to alias _loadPath
set _ScreenSize to (load script _loadAlias)

AppleScript: If a file does not exist

I need some way to determine if a particular file exists. If it exists do one script if not then do another script. Here was my logic in applescript:
If exists "File:Path:To:theFile"
tell application "Finder"
open "File:Path:To:the:script"
end tell
else
tell application "Finder"
open "File:Path:To:the:Anotherscript"
end tell
end if
The only problem is that sometimes when i use the above logic the script fails saying can't find the file. I need a full proof, never fails way to see if a file exists. I'm open to using the terminal, or applescript. I'm sure someone has run into this before but I have looked all over the web for an answer but could not find one.
In your original code you're giving the exists function a string, rather than a file, even though it's the path to a file. You have to explicitly give it a file, or it treats it the same as if you had tried to do
exists "god"
or
exists "tooth fairy"
The exists command won't know what you're talking about. You could use
return exists alias "the:path:to:a:file"
but aliases don't work unless the file actually exists, so a non-existent file will create an error. You could of course catch the error and do something with it, but it's simpler to just give the exists function a file object. File objects belong to the Finder application, so:
return exists file "the:path:to:a:file" of application "Finder"
I use the following to see if an item in the Finder exists:
on FinderItemExists(thePath)
try
set thePath to thePath as alias
on error
return false
end try
return true
end FinderItemExists
I think what you're missing is conversion of the path to an alias.
This sounds like a good place for a try...on error block. I believe the following should do what you want:
tell application "Finder"
try
open "File:Path:To:the:script"
on error
open "File:Path:To:the:Anotherscript"
end try
end tell

Resources