Introduction

Here’s the scenario. A co-worker sits down at his desk. After a few minutes, a message box pops up telling him that Windows encountered an error. Before he can respond, the box vanishes. He stresses, then figures it can be safely ignored. Then it returns. He goes to click the Cancel button, but the form jumps to a different location. He pursues it around his two monitors before it vanishes again, only to come back later.

Insert evil laugh here. But quietly, as you don't want him to know it was you who installed this small application on his machine.

This app was written using Visual Studio 2008, but should work with any version of the .NET Framework. It has been tested on Windows 7 64 bit and XP.

AppContext

The prank runs out of a descendant of ApplicationContext, which lets it run without needing a form. If you are unfamiliar with this class or have never written notification area apps, you may wish to read an earlier article of mine, Create a System Tray Application in VB.NET[^]. Start with a standard Windows application, and add this class.

The class AppContext inherits from System.Windows.Forms.ApplicationContext. Using this makes the app easier to scale, and offers us the ThreadExit event where we can guarantee things will get cleaned up no matter how the application may end. To make it possible to shut down the app (come on, even that guy in Accounting should be given an out), we create a NotifyIcon where we can access a menu.

To make this more fun, we allow for multiple monitors. Typically, monitors are arranged in a row, so our "arena" is the combined width of the monitors, and the height of the tallest. This defines the region where the form can jump.

We use a Random object to set how often the form appears, which helps to keep them guessing. For demonstration purposes, I've set this to be pretty fast, every 30 to 50 seconds, but it might be more annoying if you use 300 to 900 seconds, which would be between five to fifteen minutes.

When the app is running, an icon will appear in the notification area (sometimes called the system tray.) You (or your users, if they get curious) can right click on the icon to pull up the context menu and select Exit. That ends the application thread, which in turn triggers the ThreadExit event. This event gets called no matter how the thread ends: Windows is shutting down, the user went in through the Process Manager, and so on.

The form has its own Timer: when it expires, the timer is disabled and the form hidden. Note that the values are set using half second increments. As written, the form will vanish after 5 to 20 seconds.

The property Arena gives the boundaries as to where the form can jump, and the array Sounds() lets the form generate a random system sound every time it appears.

The form is activated from AppContext by calling the its Display method. This centers the form to the current monitor, sets the timer, plays a random sound, shows the form and starts the timer. When Time goes off, the timer is disabled and the form hidden.

The MouseEnter event is where things get interesting. When the user moves the mouse in to click on one of the buttons, the form jumps to a random location on the desktop. Hilarity ensues. If the user manages to reach the form's close button, the attempt to close the form gets canceled in the FormClosing event so nothing happens, which adds just a bit more frustration.

Putting It Together

Because this is written in VB, there are a few extra steps that (I think) C# programmers do not need to do. The first is to write our entry point.

Next, we have to tell the bootstrapper to use it instead of a starting form. This is done by going to the My Project interface, unchecking Enable application framework and selecting Sub Main as the startup object. Disabling the application framework also disables the visual styles, which is why they get turned back on manually in Main. Strictly speaking, we don't need to do this, but the form will not look right if we don't.

The last thing is to deploy the app. Assuming your chosen victim's workstation has the .NET framework already installed on it, it should just be a matter of compiling the code, copying the executable to somewhere handy, and running it.

For the Truly Evil

As written, this is an annoying but harmless prank. While I really hope you will keep it harmless, there are other ways you can make it much more annoying. One thought is to scan the user's machine for sound files, and play one at random when the form manifests. Or you could add a menu that lets you put the application thread to sleep for a few hours before waking up again. Maybe instead of a system warning, the form could display complaints like "Is it warm in here or is my processor overheating?" or offer useful suggestions like "Screw this, let's go for a beer." The possibilities are limited only by your evil, twisted imagination.

Have fun, and if you come up with a particularly fiendish variation, please let me know!

Share

About the Author

Gregory Gadow is currently a student at Central Washington University, studying for a B.S. in Actuarial Science with plans to graduate in June, 2019. He has been writing code for almost 30 years in more than a dozen programming languages. Previously, he worked for a mid-size brokerage firm as the company's programming department doing VB6, VB.Net, ASP, HTML, XML and SQL. He also held the Series 7 and Series 66 brokerage licenses.

When clicked to run the first time the program would setup a windows scheduled event to start the program for the next time. Do this so the program can’t be seen in task manager but only for a few seconds. In addition turn the background to a fake windows dreaded blue screen. An option would be to make the computer actually do a restart after so many seconds. On program finish create a new windows scheduled event.

I've actually written an app like that: it had no visual interface and, after a random amount of time (I set it for, I think, between 1 hour and 3 hours) a maximized, borderless form appeared that looked like the BSD. The "screen" had a 15 second count down to an automatic reboot; when the counter finished, a big April Fools was displayed, then the app unloaded itself.

And I'm still trying to get only the part of the baboon framework that is relevant to management: they have so much junkware and bloatware on their machines that I have to keep relevant apps as lightweight as possible.

All of the techniques I used in this app were derived from my earlier one about writing a notification area app; the only thing new here was to put it in a different context. And thank you for the complement: I have been called a hack before, but never a teacher to hackers.

Reminds me of the time I released my masterpiece program: "Sloof Lirpa". It had a fancy installer and everything. All it did when run was instruct the user to read the title of the program more closely.

Good job on this. I never knew about ApplicationContext, though I have made tray programs before. I totally can't remember what I did, though I suspect it was hackish or I ended up having a hidden form window that would be the main app window anyway so I just kept around for the app run-time.