Submit Hint Search The Forums LinksStatsPollsHeadlinesRSS
14,000 hints and counting!

Rebuild the services menu without logging out System

I've seen a lot of people get annoyed with the fact that they have to log out and log back in in order to see any new services they've installed show up in the services menu. It turns out that there is an AppKit function that will dynamically update the services menu without making you log out. But I haven't seen this functionality incorporated into any easy-to-use tool (except several very good projects on Source Forge such as PerlPad. But those require you to be quite technical to use).

To write a small tool to do this is actually very easy: all the code that's required is below:


#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSUpdateDynamicServices();
    printf("The services menu has been rebuilt.\n");
    printf("You must restart any active applications to see changes.\n");
    [pool release];
    return 0;
}

Simply make a Foundation Tool Project in Project Builder, paste the code in, and then make sure your project is linked against both Foundation.framework and AppKit.framework and you are good to go. The result is a command-line tool that when run will rebuild the services menu. You'll see the changes right away in newly launched applications. But you won't see the changes in any open applications until you've quit and relaunched them.

Read the rest of the hint for more info on creating the project as well as some comments on how and why to use it...

[robg added detail: I've never built a Project Builder (PB) application before, and I managed to make this work. So here's some added detail which may help other PB newcomers.

Start by launching PB, and select a "Foundation Tool" project (in the "Tool" section) in the Assistant screen. Find a location and assign a name for your project (I used rbldsvcs). When the PB main window opens, in the Source folder in the left pane open the main.m file, copy and paste the above code (replacing whatever is in main.m at that point). Then Control-click on the "External Frameworks and Libraries" folder, and select Add Frameworks. The Foundation.framework was already listed, so I just had to add the AppKit.framework. I then saved the project, and clicked the Hammer icon to build the project.

When the build is done, you can switch to the Terminal and navigate into the project folder you created. You'll find a "build" directory that contains the binary code you just wrote; move this program somewhere on your path, and you can now restart the services menu quite easily:

./rbldsvcs 
The services menu has been rebuilt.
You must restart any active applications to see changes.
If I can make this work, almost anyone should be able to do so as well!]

To test this, just drag some .service bundles out of your ~/Library/Services folder, if you have any, or take an application that you know exports some service and make a Stuffed copy of it and delete the original, run the tool, launch another application, and you should not see the entries for the services you've just removed. You can reverse the process to add them back in, all without logging out.

This is useful for people who are changing the keyboard shortcuts for their services menu and want to see those changes without having to log out and log in, for people who are trying to debug which collection of services is conflicting with other services, and for developers in general.

I can also build a GUI version of the tool if the interest is high. (I personally just like using the command-line a lot more and this seemed like the right thing for the command line). But given that the core of the system code is so simple, perhaps someone with more design sense for GUIs can take this on?

    •    
  • Currently 1.75 / 5
  • 1
  • 2
  • 3
  • 4
  • 5
  (4 votes cast)
 
[11,094 views]  

Rebuild the services menu without logging out | 16 comments | Create New Account
Click here to return to the 'Rebuild the services menu without logging out' hint
The following comments are owned by whoever posted them. This site is not responsible for what they say.
Not a GUI- a service
Authored by: jecwobble on Apr 25, '03 11:04:01AM

Just a thought here, but a GUI for something like this seems a bit much- perhaps if it were included as part of some other administration GUI or Control Panel.

However, wouldn't it make more sense if this functionality existed as a menu item in the Services menu itself (i.e. a service)?



[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: bluehz on Apr 25, '03 11:11:31AM

Great hint - Thx!

And thx to robg also for explaining in a little more detail - for us
projb newbies.

Also - I have noticed it is not necessary to quit applications to
have the changes show up - you only need to restart the Finder.
If you quit the Finder and relaunch it - your changes propagate
throughout all open apps. I just confirmed this by deleting all
Bluetooth stuff from /utilities, ran rbldsvcs, then relaunched
Finder and all Bluetooth stuff was gone from Services in all open
apps.

PS - robg - why is the posting mechanism hard wrapping the
text in these post at approx 60 chars???



[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: robg on Apr 25, '03 11:44:42AM

Not sure why they're auto-wrapping; I'll put it on the list of weekend nits to look at!

-rob.



[ Reply to This | # ]
60 character hard-wrap
Authored by: gatorparrots on Apr 25, '03 11:47:08AM

This line is about or approximately sixty characters in width.
This line is about or approximately much more than sixty characters in width and I'm not seeing any hard-wrapping (using "Plain Old Text").



[ Reply to This | # ]
Another Use
Authored by: ky11x on Apr 25, '03 11:39:15AM

Kind of obvious, I suppose. But this is also a great hint for
trying out new services you download from VT before you decide
if you want to keep it. Just download the new app/service
bundle, rebuild services, try the new service out, and if you
don't like it, get rid of it and rebuild services again. All without
logging out!



[ Reply to This | # ]
Double-clickable and CLI
Authored by: englabenny on Apr 25, '03 12:12:29PM
A quick hack to get a doubleclickable app out of a unixexecutable like this (or a shell script!) is to take some small applicationbundle, like clock or something, and rip out all resources and the inner executable in Contents/MacOS/.

In that folder place your executable, and rename the App bundle to the same name. Also change the value corresponding to the key CFBundleExecutable in Contents/Info.plist correspondingly. I have used this previously to create a double-clickable shell script that starts a backround screen saver, or if it's already running, quits it.

Also note that you can compile this quick and easy in Terminal, without doing all the PB Project creation stuff. You still need DevTools, ofcourse. Just put the code in serviceupdate.m and compile it with cc serviceupdate.m -o ServicesRestart -framework Cocoa, ServicesRestart being the name of the final executable.

[ Reply to This | # ]
Rebuild the services menu using PerlPad
Authored by: magir on Apr 25, '03 02:06:06PM
If you are a Perl freak I recommend Perl-Pad. It's available at sourceforge.net and has some functionality to run Perl-Script using Services. If you take a look at the documentation you'll find a hint how to rebuild the services menu just by selecting some text and sending it to PerlPad for execution. The software is still in the alpha stage but if you're familiar with perl it's certainly worth a look.

[ Reply to This | # ]
Rebuild the services menu using PerlPad
Authored by: bluehz on Apr 26, '03 01:53:59AM

Any suggestions on getting Perl-pad to work. Installed App, and
necessary perl modules from CPAN, and CamelBones
framework... still when choosing from Services menu > perl
pad.. it locks up whatever app is in use. Launching perl pad app
itself crashes instantly.



[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: njitkoff on Apr 25, '03 03:03:26PM

I am writing a Services Preference Pane. It can do this sort of
reload as well as disable them and change their names/
command keys.

If any of you want to try it out, contact me.



[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: Zo-1 on Jun 30, '05 04:24:32AM
I'm still quite happily using Service Manager pref pane from Blacktree, 2003 (!) and I've often wondered how anyone manages without it. Instant Services updates, and keyboard shortcuts too.

If someone's writing a new one, you've got a big market.

[ Reply to This | # ]
An AppleScript frontend
Authored by: klktrk on Apr 25, '03 03:58:06PM
Once you've built your binary as per the instructions above, just make an AppleScript, like so:
set shellcmd to "/path/to/your/binary/rebuild_services"

display dialog "Are you sure you want to rebuild your services menu?" ¬
     buttons {"Cancel", "OK"} default button 2
-- ¬ is a line wrap. 

set the reply to the button returned of the result
if the reply is not "OK" then exit repeat

with timeout of 1000000 seconds
	try
		set output to do shell script shellcmd
	on error errormsg
		display dialog errormsg --in case anything goes wrong
	end try
end timeout

activate me
display dialog output


Now, save this AppleScript in your ~/Library/Scripts folder, or, for system wide access, in /Library/Scripts. Then you can rebuild your services menu just by pulling down the script.menu menu time in your menu bar and selecting this script.

[ Reply to This | # ]
An AppleScript frontend
Authored by: bluehz on Apr 25, '03 09:02:23PM

I wish there was more documentation (read "READABLE BY AVG
USER") on AppleScriptStudio and ProjectBuilder in general. This
would be the perfect kind of project I could sink my teeth in for
an afternoon and learn how to create small applications, etc.
Alas - I have tried, and tried, and tried and it just doesn't gel -
but my perl and shell scripting abilities are coming along nicely.
Now if I just knew how to pkg those up in nice apps for others.



[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: njitkoff on May 15, '03 09:52:55AM
I made a preference pane that will allow you to accomplish the same thing as well as modify the menu items and command keys of services you have avalailable. If anyone is interested in testing it, please give it a try

[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: avanham on Nov 25, '03 05:21:19PM
There is an error in the original code: The word NSUpdateDynamicservices() should have it's 's' capitalized on 'Services' and there were extra backslashes before the quote marks (eg " became \"). The corrected code is listed below. It runs on X-Code as long as you add the 'Appkit' framework to the project.

#include <Foundation/Foundation.h>
#include <AppKit/AppKit.h>

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    NSUpdateDynamicServices();
    printf("The services menu has been rebuilt.\n");
    printf("You must restart any active applications to see changes.\n");
    [pool release];
    return 0;
}


[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: smeger on Jun 29, '05 08:08:11PM

You can also do this dynamically from Terminal.app if you have Apple's developer tools installed. Do the following:

  • cd /Applications/Calculator.app/Contents/MacOS/
  • gdb ./Calculator
  • --- wait for gdb to load ---
  • run
  • --- wait for Calculator to launch ---
  • --- type control-c from within Terminal ---
  • call (void)NSUpdateDynamicServices()
  • continue
  • --- switch to Calculator ---
  • --- quit Calculator ---
  • quit


[ Reply to This | # ]
Rebuild the services menu without logging out
Authored by: Daniel Buus on Dec 04, '12 04:48:07AM
With my installation (Lion), you can trigger the rebuild without creating any new app like this. For me, it's a terminal command like this:

/System/Library/Frameworks/CoreServices.framework/Versions/A/Frameworks/LaunchServices.framework/Versions/A/Support/lsregister -kill -r -domain local -domain system -domain user

Adding it as an alias in .bashrc (syntax: alias rebuild-services='all that long line goes here') makes it easier to remember. The tip I used had a different path to the "lsregister" binary, so I had to do sudo find / -xdev -name 'lsregister' to find it :)

[ Reply to This | # ]