"path-to-me" doesn't work in an Automator service - a workaround?

I’m converting two of my AS script bundles to portable Automator Services.
I expected quick work, just open an Automator Services workflow, copy the AS script, save, done.
Alas, nothing is ever easy. To my surprise, I dicovered that:

  • service workflow bundles don’t have :Contents:Resouces: folders, just :Contents:, and don’t seem to find it if you add one.
  • worse still, it can’t handle “path-to-me” as expected. Instead of pointing to the service workflow, it points to its runner.
    note however, that “path-to-me” does behave normally in an Automator applet.
-- To test this as a service, copy the script to an Automator Service workflow and save it as "myService.workflow"
tell application "Finder"
	set MySelection to selection as alias list -- any selection will do, just to get access to the Service CM.
	set mePath to (path to me as text) -- DOESN'T WORK as expected (by me, at lest) in an Automator Service workflow.
	set the clipboard to mePath
	-- When the AS is running within the open workflow, it points to the Automator --> HD-1:Applications:Automator.app:
	-- When the AS is running within the Service, it points to its runner:
	--> HD-1:System:Library:Frameworks:AppKit.framework:Versions:C:XPCServices:WorkflowServiceRunner.xpc:
	-- This is my AS "path-to-me" workaound for an Automator Service.  It works, but only a mother can like it.
	-- ================================================================
	set myServiceName to "myService.workflow"
	-- if the service path is "Volume:Library:Services:myService.workflow"
	set ServicesPath to (path to library folder as text) & "Services:"
	set myServicePath to ServicesPath & myServiceName
	-- if the service path is "Volume:Users:username:Library:Services:myService.workflow"
	set userServicesPath to (path to library folder from user domain as text) & "Services:"
	set myUserServicePath to userServicesPath & myServiceName
	-- I use a custom icon here, as an easy way to check that the service is working.
	if exists myServicePath then
		set myItemPath to (myServicePath & ":Contents:my.icns") as alias
	else if exists myUserServicePath then
		set myItemPath to (myUserServicePath & ":Contents:my.icns") as alias
	-- ================================================================
		-- This is the usual "path-to-me" on-liner.  It works in any Script Bundle, Applet, or Droplet.
		set myItemPath to ((path to me as text) & "Contents:Resources:my.icns") as alias
	end if
	display dialog "Built path to icon" with icon myItemPath
end tell

To me, my contruption is an ugly replacement for the normal one-liner. Does anybody have a better idea?
Is there a better AS stand-in for the “path-to-me”, usable in a Service to point to the actual Service instead of its runner?

It’s not that surprising given that Services aren’t designed to need one – they are really just act as a special clipboard that passes stuff between one app and another. Any resources are normally supplied by the app implementing the service, or the actions in an Automator-based service. That doesn’t help you – the Run AppleScript action case has no mechanism of its own to include resources – but it might at least explain the why. (The “official” answer might well be that if your script requires resources, you should write it as a full AS workflow. Ugh.)

That’s more a case of misplaced expectations. “path to me” refers to the application running the script, in all cases (except when editing where its behavior is overridden by the editor – but in that case you’re not really calling the scripting addition command, it just looks like it).

Think about it: when an application runs an AS script, any scripting additions it calls are loaded into its instance of AppleScript. That instance knows what application it is loaded in, but how can it know where the script it’s running originally came from? The application has no reason (or way) to tell it – all it does is whatever the running application tells it to do.

Hi Shane, thanks for your detailed explanation.

Regarding “a full AS workflow”, how do I convert an AS script bundle into a Service workflow to be accepted by OS X as such? I don’t know how to do that. All my services to date have AS embedded in Automator workflows. I assume it is some kind of header or enclosing block. Could you point me in the right direction? Maybe, a short example?

I do need bundled resources because both scripts use a command line tool and an applet helper.
My “solution” does work by putting the resource items in the Contents folder and accessing them as in my example, but I’d prefer very much a clean As workflow solution.

Cheers, Chris

That’s what the the “Ugh” was about :frowning: You basically need to make an Automator Action in Xcode, which is a bit of a learning curve, not helped by a lack of documentation.

The easiest thing would be to stick with it. I was really just trying to explain your two “discoveries”.

Thanks Shane. I’ll stick to my ugly duckling. I may even learn to love it :stuck_out_tongue: