I'm developing a Mac OS X application and in some case it needs to copy a file to /Library/ScriptingAdditions.
And using the code below
tell application "Finder"
duplicate sourcePath to destinationPath with replacing
end tell
will prompt a dialog saying "Finder" wants to make some changes...
I would like to make the dialog saying My Application wants to make some changes....
I've read about https://developer.apple.com/library/mac/documentation/security/conceptual/authorization_concepts/01introduction/introduction.html
but it doesn't seem to work with AppleScript.
If you would use the shell instead of AppleScript, the dialog asking for the password will display the name of your own application. Here's an example that copies the file "_this is a test.xyz".
set sourcePath to "'~/desktop/_this is a test.xyz' " -- mind extra space
set destPath to path to scripting additions folder -- change this to your destination folder
set destPath to POSIX path of destPath
set destPath to "'" & destPath & "_this is a test.xyz'"
set shellScript to "cp -n " & sourcePath & destPath
do shell script shellScript with administrator privileges
Warning: don't just run this script without modification, as it will add an empty file to your scripting additions folder and you probably don't want that. This script just serves as an example to look at.
Edit:
This will only work if you can compile your app as an independent app. If you're using Python, you need to compile your Python scripts as a standalone app with a name. The password dialog will show the name of the standalone app instead of "Python".
Related
I am currently setting up an ApplescriptObjC application. Whenever I try other methods, it screws up. I'm trying to set it up where a shell script uses the mv command to move a file from the "Files" directory to the /usr/bin/ folder. I think it would go a little something like: do shell script "sudo mv " & path & "/Files/ /usr/bin/" where path would be the path to me. I have tried the path to me and posix and other stuff, just doesn't work. ![The Files folder contains a file I want to move to /usr/bin] Image of where the folder is: http://i.stack.imgur.com/jUX6w.png
First of all the folder Files in your screenshot is a virtual folder in Xcode (yellow).
You have to create a real folder (blue). The easiest way is to drag a folder in Finder to the Xcode sidebar and select "Create folder references"
To use sudo in AppleScript append with administrator privileges to the do shell script line. You will be prompted to enter an admin password.
This code moves(!) the files to /usr/bin. If you want to copy (duplicate) the files use cp -r instead of mv
set filesFolder to (current application's NSBundle's mainBundle()'s resourcePath()'s stringByAppendingPathComponent:"Languages") as text
tell application "System Events" to set filesToMove to name of files of folder filesFolder
repeat with aFile in filesToMove
do shell script "/bin/mv " & quoted form of (filesFolder & "/" & aFile) & space & "/usr/bin/" with administrator privileges
end repeat
I am packaging an application into a .app directory for "drag install" or whatever it's called and I have a weird iessue with file association.
I set my application as a viewer for .xyz files, and the system does start my app when I double click that file; the only problem is that the path of the file I clicked is nowhere in the args[], there's only one parameter that is something like ~psn_0_901340 and I think is a timestamp because it changes every time.
So... what am I supposed to do? I've been sitting here for 2 hours straight and can't find a solution.
I think what you want is an AppleScript droplet.
A shortened version of the AppleScript from that link:
on open dropped_files
set the_command to quoted form of POSIX path of (path to resource "script.sh")
set file_list to ""
repeat with file_path in dropped_files
set file_list to file_list & " " & quoted form of POSIX path of file_path
end repeat
set the_command to the_command & file_list
do shell script the_command
end open
Export as an application using Script Editor. Place script.sh in the Resources folder.
Add your file extension associations to Info.plist. You may need to launch or move the droplet before OS X notices the change & allows you to double-click files.
If you want to launch Terminal or capture the script output, see the full AppleScript.
I'm trying to build an AppleScript to launch my shell script.
Path structure is as follows
/Users/ryan/myscript/
applescript.scpt
bash.sh
My AppleScript is as follows:
tell application "Terminal"
set folder_path to path to me
set run_cmd to "/bin/bash " & folder_path & "/bash.sh"
do script run_cmd
activate
end tell
Problem is the 'path to me' is not always returning the correct path. When executed using the Mac cd/dvd autoplay behavior folder_path is equal to:
disk:System:Library:CoreServices:SystemUIServer.app:Contents:XPCServices:com.apple.systemuiserver.scriptrunner.xpc:
Is there is a better way of getting the folder path?
If this Script is in a static location, you can do this:
do shell script "/bin/bash" & POSIX path of (path to current user folder) & "myscript/bash.sh"
Path to me refers to the location of the applescript that is running. So if your script is on a disk then it will reference the location on the disk where the script is saved
if it is expected that the shell script will always exist in a folder called "myscripts" that exists in the current user folder then you could use path to current user folder and build out from there
set user_folder to path to current user folder
set folder_path to quoted form of POSIX path of (("" & user_folder & "myscript"))
tell application "Terminal"
activate
set run_cmd to "/bin/bash " & folder_path & "/bash.sh"
do script run_cmd
end tell
Is there a reason why you have to store the shell script in a separate file? Typically, you would put it inline, within the AppleScript code. As far as I know, the “do shell script” command only operates on text, not on a script at a file path. If you give it a variable that contains a path, it will try to run that path as a command. It won’t run the contents of the file as a command.
Here is an example of an AppleScript that runs an inline shell script and puts the results in TextEdit:
property theShellScript : "#!/bin/bash
echo Hello World"
tell application "TextEdit"
activate
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell
… you can of course replace the above shell script with the contents of your own shell script.
If you do need to keep the script in a separate file, the best way to do that is probably to save your AppleScript as an Application, and put the shell script within the Application bundle. “Path to me” is the path of the application that is running the script — not to the script itself — but if you save your AppleScript as an Application, then it runs its own script, and “path to me” works as you originally expected.
Here is an example of an AppleScript that runs a shell script contained within a file that is stored within its own application bundle:
property theApplicationPath : the path to me as text
property theShellScriptPath : theApplicationPath & "Contents:Resources:Scripts:bash.sh"
tell application "TextEdit"
open alias theShellScriptPath
set theShellScript to the text of document 1
set theScriptResult to do shell script theShellScript
make new document
set the text of document 1 to theScriptResult
end tell
With the above script Copy/Pasted into a new document in AppleScript Editor, hold down the Option key and choose File ▶ Save As, and in the Save dialog box, on the File Format pop up menu, choose “Application” and of course give your application a name and click Save. Then in Finder, navigate to where you Saved your application, and 2-finger tap (or right-click) on your application and choose “Show Package Contents.” That opens your application up as a folder, exposing the file system within. Put your shell script file named “bash.sh” inside the folder “Contents/Resources/Scripts” within your application and then close the window that represents your application.
Now when you run your application from anywhere in the file system, it will still be able to find and run its incorporated shell script.
here's my code:
set NCBGPath to path ("Machintosh hd:System:LIbrary:Core Services:Notification Center:Contents:Resources")
set NCBackground to {"linen.tiff"}
set themeFolder to choose folder with prompt "Choose a Theme"
tell application "Finder"
if exists file (themeFolder & NCBackground) then
copy file (themeFolder & NCBackground) to NCGBPath
end if
end tell `
What do I need to change to make it work? It should let you choose a folder, if in that folder there's a file called linen.tiff then copy that file to a set path:
/System/Library/CoreServices/Notification Center/Contents/Resources
replacing the one that already exist...
In troubles setting the path and making it work
You seem to have all of your paths messed up. You're just not using them correctly. Also the Finder does not have a "copy" command. It has a "duplicate" command though. However because you're performing the duplicate to a restricted location I would use the cp shell command instead and run it with "administrator privileges".
So the below code will do what you are trying to do (I did not test it). However I doubt it's a good idea and don't know if it will even work. Normally just replacing a file won't make a change like you're expecting without restarting notification center. Also, as I mention in the code, you're going to have a file permissions issue. Files in that folder have special permissions that your copied file will not have. Finally, it's not a good idea to touch things in the /System directory.
With all that being said, if you still want to continue then give this a try.
set NCBGPath to "/System/Library/CoreServices/Notification Center/Contents/Resources/"
set NCBackground to "linen.tiff"
set themeFolder to (choose folder with prompt "Choose a Theme") as text
set themePath to themeFolder & NCBackground
set posixNCPath to NCBGPath & NCBackground
set shouldCopy to false
tell application "Finder"
if exists file themePath then set shouldCopy to true
end tell
if shouldCopy then
do shell script "cp " & quoted form of POSIX path of themePath & space & quoted form of posixNCPath with administrator privileges
-- you probably should correct the file permissions too as the copied file probably won't have the proper owner and stuff
else
display dialog "Could not find the background file in the chosen folder."
end if
Hey I have the following AppleScript saved as a Droplet.
It is saved on a DMG file like this one http://dl.dropbox.com/u/1839051/TestDMG.dmg
The Problem is, while some can drag the template onto the Droplet and have it working, when I try to drag the template onto the droplet the crossed-out circle-symbol shows up indicating that this action is not possible. Nothing happens, the file is not copied.
Does anyone have any idea why I have this problem and how it can be fixed?
Thanks in advance guy.
on open thefiles
set outputFolder to (path to application support folder from user domain as text) & "iWork:Pages:Templates:My Templates:"
do shell script "/bin/mkdir -p " & quoted form of POSIX path of outputFolder
tell application "Finder"
duplicate thefiles to outputFolder
end tell
end open
Rather than using a droplet and having the user to drag the files onto the droplet, why not just make an installer so the user only has to double-click the installer? It would be easier and also probably avoid your problem. I also added some error handling in your code because it's just prudent to do that with shipping code. We also tell the user what happened.
NOTE: you also had an error in your code. The outputFolder is a string. The Finder requires a file specifier. To make the string into a specifier you add either the word "file" or "folder" in front of the string path. Your code may have worked but the proper way to write it is with a specifier. Other applications may not take the string path but they will all take the specifier... so get in the habit of using them instead of strings.
try
-- create the output folder if necessary
set outputFolder to (path to application support folder from user domain as text) & "iWork:Pages:Templates:My Templates:"
do shell script "/bin/mkdir -p " & quoted form of POSIX path of outputFolder
-- find the templates on the dmg disk
set myPath to path to me
tell application "Finder"
set myContainer to container of myPath
set templateFiles to (files of myContainer whose name extension is "template") as alias list
end tell
-- copy the templates to the output folder
-- NOTE: the script will error if any of the templates already exist
-- therefore we use a repeat loop and duplicate each file separately with a try block
-- around it to avoid errors in case some templates have already been installed.
tell application "Finder"
repeat with aTemplate in templateFiles
try
duplicate aTemplate to folder outputFolder
end try
end repeat
end tell
-- tell the user everything was OK
tell me to activate
display dialog "The templates were successfully installed! You may now use them in Pages." buttons {"OK"} default button 1 with title "Templates Installer" with icon note
on error
tell me to activate
display dialog "There was an error installing the templates. Please manually install them by copying them to the following folder." & return & return & (POSIX path of outputFolder) buttons {"OK"} default button 1 with title "Templates Installer"
end try
This looks to be a permissions issue, and I have to wonder if the differential between those who can and those who can't have something to do with which OS they are running. I'm running Mac OS 10.6 as an administrator and I was unable to perform the action in the DMG. But I was able to perform the action if I dragged both files out of the DMG and onto my Desktop.
If you need to install files in specific locations to the hard drive to support your project, then I would recommend making an installer (and a matching uninstaller as well) as opposed to the setup you have presented.