Skip to content


EvilDesk 0.7 Released

Well, the bug fixes I made in the last release left me feeling empowered again, so I've followed up with a couple more features and some more bug fixes:

  • Added new MATCH CREATE window matching configuration option, which allows actions to be taken when windows are created. For example, you can cause all VMWare windows to start on a given workspace, or have your mp3 player automatically stick to all workspaces when it starts up.
  • Fixed a slit layout calculation bug.
  • Avoid blocking the flasher when the flashing app (eg: gaim 2.0 beta) hangs itself
  • Balloon tips now display the body of the balloon text, instead of the tooltip from the tray area, and will rise all the way to the top of the z-order.
  • Improved detection of deleted tray tooltips, so that balloon tips are not wiped out at the wrong time.
  • When a window was made sticky, it would remain in the minimized state on the inactive workspaces. This has now been corrected.
  • Fixed a string termination bug in the PuTTY plugin for sessions that have spaces in their names.
  • Environmental variables are now expanded when processing the MergeDirs directive in the .evdm file

EvilDesk 0.6 Released

Having finally found some time to myself, I thought it was about time that I push out a release with the changes that I've been using for the last few months. Some of these changes are based on feedback from users; keep it coming folks! :)

Feature changes in the new release include:

  • Revised plugin loading system. Slits are defined via the new SLIT directive and plugins are loaded via the new LOAD directive in the .evdm file.
  • Slit windows will hide themselves when an application goes fullscreen (and come back when it leaves fullscreen mode). I've tested this with PowerPoint (when viewing the slideshow) and PuTTY (alt-enter) and it seems to work ok.
  • Altered the gravity of the tray plugin so that it sinks below the flasher. Why? When double-clicking on the gaim tray icon, the first click would open the buddy list, causing it to flash. The flasher would bump the tray up, causing the second click to land on a different tray icon--usually the wifi icon, popping up the wireless network selector.
  • Added more internet-facing apps to the SaferExec line in the default configuration. No idea what that means? Read more on "Browsing the Web and Reading E-mail Safely as an Administrator".

Bug fixes include:

  • Fixed a race condition where windows could bleed across to the target workspace when switching workspaces.
  • Fall back to the system default icon in the task switcher and flasher if the window in question has no icon of its own.

Go get EvilDesk!

Merry Christmas!

MinimizeToTray + thunderbird == lower memory usage

Having just set up the mozilla calendar plugin to launch when I open thunderbird, I was wondering how much memory I was going to be sacrificing to the GUI god. I was very pleasantly surprised to see that thunderbird.exe was consuming less than 2MB when minimized.

I put this down to MinimizeToTray. My guess is that it's calling SetProcessWorkingSetSize(GetCurrentProcess(), 0xffffffff, 0xffffffff) to swap the process out of memory when minimized.

Yep, after a while, the memory usage creeps back up again, as thunderbird does its background bits and pieces, like checking mail.


I don't know if you're all aware of This new service, graciously provided by Emini A/S, continually builds PECL extensions against the various different branches of PHP so that you can very easily find the latest version of a given PECL extension to match the version of PHP that you're running.

Edin Kadribasic from Emini has been looking after the official Windows build of PHP (he builds our Windows distribution) for some time, and this service is his latest innovation; thanks Edin!

Upcoming PHP-on-Windows webcasts next week

One of the people that I met at ZendCon was Joe Stagner, who's been using PHP since before he started work at Microsoft. Joe gave a talk entitled "PHP Rocking in the Windows World" which went down quite well. I'm sad to say that I missed it--I got caught up talking to a bunch of people and lost track of time.

Joe is running a series of PHP-on-Windows webcasts next week on MSDN:

MSDN Webcast: Comparing PHP with ASP.NET

MSDN Webcast: Building and Running PHP Applications on Windows

MSDN Webcast: Extending PHP Applications Using Microsoft Technologies

Running PHP as a Service on Win32

[Update: I wrote some docs for the php manual]

So, you've written some kind of super-duper daemon process in PHP, perhaps using the event extension and stream_socket_server(). On Unix, it's quite a simple matter to have it run from init (or maybe inetd) when your machine starts... but doing the same on windows isn't possible without some hacks. Until now.

Last night I put together 2 new extensions for windows; the first of these is called win32service and it allows you run your PHP scripts from the "Service Control Manager" (SCM). The SCM is roughly analagous to the init process on unix, in that it runs tasks on startup and monitors their status, optionally restarting them if something goes awry.

I've included a sample service script that demonstrates minimal usage. Before you can run a script as a service, you need to register it with the SCM; in the sample, you do this by running it with the "install" argument on the command line. Once installed, you can use either the services MMC snap-in (run services.msc, or look for it under "Administrative Tools") or the good old fashined "net" command to launch or stop the service. I prefer the latter:

   net start dummyphp

The output from the command should indicate the service started correctly; use the task manager to verify this--you should see a php.exe process running as SYSTEM. This dummy service does nothing much; just sleeps and waits for the SCM to tell it to stop; lets do that now:

   net stop dummyphp

Again, the output from that command should indicate that the service stopped, and your task manager should no longer show php.exe running as SYSTEM. Now that we've proved that it works, we should remove the same from the SCM; running the script with the "uninstall" argument will do this.

It's all pretty straight-forward; the most complicated part is the win32_create_service() function; the first argument is an array that describes the service; the following keys are supported:

  • service - the short name of the service. You can't have two services with the same name.
  • display - the display name of the service.
  • user - the account name under which to run the service. If omitted, runs as the local system account
  • password - the password to match the "user" setting.
  • path - full path to the binary to run. If omitted, the full path to the currently running process will be used (typically php.exe)
  • params - command line parameters to pass to the binary. You'll probably want to specify the full path to a PHP script, plus some parameter to indicate that the script should run as a service.

(there are some more keys but they're not fully supported yet)

When it comes to actually running your service, you should call win32_start_service_ctrl_dispatcher() and pass in the name of the service. This function checks-in with the SCM; it is especially important that you do this as soon as possible in your script, as the SCM blocks while it waits for you to check-in--you can cause system-wide issues if you take too long.

While your service is running, you should periodically check to see if the SCM has requested that you stop. One way to do this is to wrap the main body of your service code in a while loop like this:

   while (WIN32_SERVICE_CONTROL_STOP != win32_get_last_control_message()) {
      // do stuff here, but try not to take more than a few seconds

If you already have an event loop, you can fold the above into your application. If you're using the event extension, you can schedule a recurrent timed event to check for the stop condition.

And that's pretty much all there is to say for now. I strongly recommend that you look through the MSDN documentation on services; it's very valuable background information.

The binaries for PHP 5 should show up under in the next couple of hours.

Enjoy :)

EvilDesk, mini release

I've pushed 0.5.1 tonight; if fixes an uninstallation buglet that could leave you without a taskbar after uninstalling EvilDesk.

The only new feature is being able to select how many workspaces the alt-tab task switcher will cycle through; you can use up to 32, with the default being 4.

Visit the ChangeLog

EvilDesk, Release 5

I've updated EvilDesk yet again this weekend. The biggest new thing is making all the hotkeys (aside from alt-tab) user configurable.

Find out more on the EvilDesk Home Page (I've added a ChangeLog section for your tracking pleasure).

EvilDesk, Release 3

[Update: Release 4 is out]

I've updated my EvilDesk and included the user-definable context menu code I mentioned in the comments of my last post.

I've also created a new home for the project, so that I can group the docs together more easily.

I will continue to publish news about updates here on my blog, so if you're already subscribed here, you needn't do anything more to keep up to date on this project.

EvilDesk, Release 4

I've updated EvilDesk again. Aside from fixing a couple of bugs here and there, it now features built-in support for "Safer" execution of internet facing applications.

Find out more on the EvilDesk Home Page (I've added a ChangeLog section for your tracking pleasure).