Findin if file exists (without triggering prompt bos)

Hi

I have been trying to include a bit of code to determine whether a particular application exists on the system running.

However, if I do something like…

try
	tell application "System Events" to set CheckForMy_Program to (application "My Program" exists)
end try

It will always give me a prompt box asking me to locate the application if it does not find it. I just want the script to move on if it cannot find the particular application, without prompting for the application.

Any clues

Thanks

tell application "System Events"
set processList to (name of every process whose name is "My Program") as list
if processList = 0 then
-- do something here. app is not running.
end if
end tell

You may also consider using something like this, in case the app name gets changed:

tell application "System Events"
set processList to (name of every process whose name contains "My" and name contains "Program") as list
if processList = 0 then
-- do something here. app is not running.
end if
end tell

Thanks for the reponse

I am not sure it is quite what I am looking for. I am trying to get Applescript to determine if an application exists on the hard drive, not whether it is running.

I suppose I could set an alias to the particular application and catch the error if it fails.

However, I was hoping there was some work around of the script I suggested using the function “exists” but without the ensuing pop up box if the sought after application does not exist. I would ideally like the system to scour the whole hard drive for the application, in case it has simply been moved or placed for the first time but not in the applications folder.

Cheers

http://bbs.applescript.net/viewtopic.php?pid=48527

These are the droids you’re looking for.

Thanks

I think the droids may be beyond my limited abilities in Applescript.

I have no idea what “Make two methods in a class” means!

The background to my query is that I have an applescript which uses a small Applescript application I built in Xcode. I just want the script to check that the application is present before attempting to use it, and if it is not present, then do the work anyway but without the pretty interface that the Applescript application offers.

I did not think this could be that complicated:)

My first script.

Hi,

If you gave your AS Studio app a creator type, then you can use that to check for your app. For instance:

tell application “Finder”
exists application file id “ToyS” – four character creator type for Script Editor
end tell

See AS STudio reference for creating creator types and file types.

gl,

Apple recommends not using type and creator codes anymore for /new/ programs, though. Support them in existing programs, but don’t continue adding them. Bundle IDs are the new hotness. (We gotta move on eventually, right? This OS is several years old now. :-))

I didn’t use the Finder method because it requires the app to launch and have a creator code. Since the first part is messy/inconvenient, and the second is deprecated in favour or bundle identifiers, Jon’s Cocoa trick is really nice to have.

So, let’s learn some cool new stuff. :smiley:

To create these “methods in a class”, you do the following:

In your Xcode project, you make a new file in your “Other Sources” folder (easiest) called “methods.m”. It should be a Cocoa/Objective-C class file. (Xcode will ask you what kind of file to make.) It will create “methods.h” automatically for you.

methods.h should contain this data:

What this does: This will instantiate your methods so you can call them in your script by their names. (“getAppPathFromBundleID:”, “getAppPath:”)

Now you need to define what these methods do.

methods.m should contain this data:

What this does: When you call the methods, this is the code that gets executed.

Calling these Cocoa methods from AppleScript:

The first one, getAppPathFromBundleID:, will locate an app via bundle identifier (com.apple.itunes, for example). The second one, getAppPath:, does the same for creator codes (if you needed to use that). They’re called like this:

property applicationBundleID: "blah.yourcompany.yourproductname"

set applicationPath to (call method "getAppPathFromBundleID:" of class "methods" with parameter applicationBundleID)

or

property applicationCreatorType : "BLAH"

set applicationPath to (call method "getAppPath:" of class "methods" with parameter applicationCreatorID)

These will return POSIX paths of applications and place them inside the applicationPath variable.

Let me know if you need more help with this.

Hi

I tried to add a new Cocoa/Objective-C class file in the "Other Sources"folder. I copied and pasted the two blocks of code in your post. But when I try to build, I get 14 errors and 4 warnings and the build fails. Do I need to alter the text in any way to reflect details of the application? I didn’t see anything that obviously required this.

error: parse error before ‘AT_NAME’ token
error: ‘bundleID’ undeclared here (not in a function)
error: ‘thisURL’ undeclared here (not in a function)
error: initializer element is not constant
error: parse error before ‘if’
error: parse error before ‘{’ token
error: redefinition of ‘err’
error: previous definition of ‘err’ was here
error: ‘self’ undeclared here (not in a function)
error: ‘creatorCode’ undeclared here (not in a function)
error: initializer element is not constant
error: parse error before ‘if’
error: parse error before ‘{’ token
error: ‘theStr’ undeclared here (not in a function)
error: parse error before ‘for’
warning: incomplete implementation of class ‘methods’
warning: method definition for ‘+osType:’ not found
warning: method definition for ‘+getAppPath:’ not found
warning: method definition for ‘+getAppPathFromBundleID:’ not found

Model: iBook
AppleScript: Latest
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

The first block of code goes into “methods.h”. The second goes into “methods.m”.

Hi again

I also had a go at trying to assign a creator code to my application. However, I could find no guide to this in the AS STudio reference and the Xcode2.2 Help only shows how to inspect the relevant details in an aplpication but not how to assign them.

Stuck again!

Model: iBook
AppleScript: Latest
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

Thanks for the heads up on the two methods files. It was in your original post as well but I didn’t see the separate ref to h and m. Anyway, the App now builds fine.

But I am now stuck on the Script. I tried to compile


property applicationBundleID: “blah.yourcompany.yourproductname”

set applicationPath to (call method “getAppPathFromBundleID:” of class “methods” with parameter applicationBundleID)


However, it gets stuck on “method” saying that a “,” was expected but an identifier was found.

As well, I am not sure I understand what the script will do. Am I meant to fill in “blah.yourcompany.yourproductname” in the script with something meaningful? Or is that just a dummy value which the script fills out if it finds the method (ie if it finds the app containing the method “getAppPathFromBundleID:”)? Sorry if I am slow on the uptake here but my last programmining experience was 20 years ago in Z-80 assembly language:)

Model: iBook
AppleScript: Latest
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

The property value should be the bundle identifier string of the program you’re trying to locate. examples:

com.apple.itunes
net.mikey-san.sandbox
com.panic.transmit

LaunchServices keeps a database of where programs are, and you can ask it for that location information by bundle ID or creator code. getAppPathFromBundleID: and getAppPath: take the property value and ask LaunchServices where to find the program that corresponds to it.

I’m not sure why you’re getting that error, so compare it to this:

http://www.mikey-san.net/method_example.zip

I put that together as an example. It’s stripped-down, so you should be able to compare your code to a working project. If successful, when launched you will get a dialog box that gives you a POSIX path to Safari.app.

I am very grateful for your help but am at a bit of a crossroads.

I downloaded and built your example in Xcode. It works fine. I had been pasting your script examples into Script Editor and compiling them outside Xcode. Script Editor, it seems, did not understand your script example. There is no doubt a good reason for this.

But if I have understood one thing right from looking at your example, I am going to need another application (App1) to determine whether the application I am trying to target (App2) exists or not. Assuming I have understood right then I am afraid it is not a solution for me because if the user of the script I am writing has not installed the necessary (App2), then calling App1 from the script to work out if App2 is there or not, is unlikely to work. The user will no doubt have omitted to install App1 just as much as App2. I just need something inside a normal Apple Script to test if my AS Studio app exists.

I am also still unclear, in any event, as to how I get the bundle identifier string for my AS Studio app, so that I can properly define the property value.

In summary, I am left wondering whether Kel’s solution of giving my AS Studio app a creator type might not be simpler and more doable for me (even if against Apple recommendations). Can you point me in the right direction to achieve that perhaps?

Sorry that I have not been able to follow you well enough. Not enough experience my end, I fear.

Model: iBook
AppleScript: Latest
Browser: Safari 417.8
Operating System: Mac OS X (10.4)

Hi Mikey-San,

Thanks for your detailed instructions on how to create methods. I’ve always wanted to try that, but didn’t know exactly how to do it.

I was wondering about the creator codes. If your AppleScript Studio application creates documents, then how do you give these documents custom icons without using the creator type. Did Apple say what to do for custom icons?

Thanks,

Custom document icons for document-based Cocoa applications can be set in the Target Inspector:

http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide20/Contents/Resources/en.lproj/bs_targets/chapter_29_section_6.html

Also, check out the Cocoa API documentation to see what methods are already available in the system. You’d be shocked at just how much you can do with available Cocoa methods with very little effort.

You can define the bundle ID string of a program in the Target Inspector (right-click on the program in Targets and choose “Get Info”):

http://www.mikey-san.net/targetinspector.png

As your for first concern, you can simply use my example project (directly or base a project off of it) and put your normal script code inside it. Anything you’d put in a “run” handler would go into “launched”, and the rest is exactly the same as Script Editor. Now you have a single app that does what your plain script does, and it has the ability to hunt for apps via bundle ID or creator type without causing an app to launch on the user’s end. (And you’ve learned a bunch in the process. :-))

If you do that, use the Target Inspector to change the name of the program Xcode creates from “method_example” to whatever your script app’s name is. (Find it under General, Build, and Properties. In Build, scroll down to the “Product Name” field and change that.)

Does that make sense? (And in the end, if you’d rather just use the creator code method via Finder, I won’t complain anymore. At least you’ve got this under your belt for the future!)

Mikey-San

I am away for the day but will have a good look and play with the contents of your last post when I get back. I think that with what you have given me there, I should be away.

I have gained much from the exchanges we have had and thank you for your patience.

All the best

Through all of this, I now have a working solution so am reporting back.

I gave my Studio App the identifier: com.kiwilegal.progressbar (leaving creator as the default ???)

Substituting “com.kiwilegal.progressbar” for “com.apple.safari” in Mikey-San’s example code, produces the path to my App. Great.

However, I could still not work out how to incorporate Mikey-San’s code into a bare Applescript, as it refuses to compile in Script Editor. I cannot incorporate the routine into my Studio App because it would be circuitous (what use for an App whose purpose would be to check whether it itself exists on the hard drive?). Nothing wrong with Mikey-San’s example, just a lack of clarity from my end on how exactly I wanted to use the ability to check for the existence of an app.

I therefore experimented with Kel’s piece of scripting using the Finder and it works not only with creator codes but ALSO with identifiers. And running Kel’s script does not launch the app, the existence of which it is checking for. So, at the end of all this, the thing that worked for me was to give an identifier to My App in the way described by Mikey-San and then use Kel’s script to detect whether or not My App exists on the hard drive. Kel’s script will generate an error if it does not find My App. But there is NO prompt box when the App is not found. And the search is instantaneous. Hurrah!. Script as follows:

try
	tell application "Finder"
		exists application file id "com.kiwilegal.progressbar"
	end tell
on error
	display dialog "Not Found"
end try

Mikey-San, because I have not messed with the creator code, hopefully I comply with Apple’s new recommendations. I am presuming that in the above process I have set the “Bundle ID” you referred to throughout this post.

Thanks guys

No no. You’re going the wrong way. You don’t incorporate my code into a vanilla AppleScript (Script Editor cannot do this), you incorporate your vanilla AppleScript into my code.

Make sense?

Mikey-San

You make absolute sense. It is just that I do not think going the other way will work for me as a solution because I end up with an application (rather than a script which I can incorporate into the iTunes script menu).

Basically, I have a script in iTunes that tidies up tags in a particular way. I then have an application made using Xcode which is a progress bar with a couple of buttons and text boxes. The vanilla script launches the Progress Bar as part of its code. The progress bar allows the user to see how far the script has got and also allows the user to cancel out or pause the process. However, as part of my error catching routines, I want the vanilla script (1) on start up, to not try and launch the Progress Bar application if it is not installed (and deactivate it in the user settings), and (2) to prompt the user to install the Progress Bar application if he subsequently tries to activate the Progress Bar in the preference settings (only, of course, if he has not already installed the program). Without these error catching routines, if the Progress Bar application was not installed, the user would get the prompt box asking him to locate the Progress Bar application. Something I want to avoid as being messy and a show stopper to actually letting the script get on and do its work without the Progress Bar, if that is what the user wants to do.

Because of all your help, I have now managed to achieve the functionality sought:)