|
|
Visiting Sysytem.Runtime.Interopservices....Getting down with the Win32 API | | AS COOL as .NET can be, there is a lot of functionality that remains to be built into it. However, as with everything in programming, where there's a will there's a way. In this brief article, I'm going to show you how to use the System.Runtime.Interopservices namespace to fire a machine's screensaver programmatically.
A few months ago, my company upgraded our domain controller and put some rigorous security provisions in place. Some of the enhancements were the use of really really really strong passwords and locking the machine automatically after 15 minutes of non-use. Well, just to satisfy my intellectual curiosity, I decided to try to come up with a program that could make my computer look busy all day right before the lockout. [In practice, I would never employ a solution like this because Network Administrators have a wide arsenal of cruel punishment tools to deal with programmers circumventing their security policy--- And I've learned the hard way.
Anyway, I first considered writing a program with a timer that would reset itself each time the mouse moved or there was a key_down event. For some reason, I just didn't like this approach. So I started trying to figure out what event was being polled to tell the system to lock itself after 1minute and 30 seconds or what seemed to be that short anyway. After a little digging around, I noticed that User32.dll could be used to send a message to the OS and fire the screensaver. Now, if you have ever used COM interop in .NET, you know it's not the cleanest looking stuff you've ever seen so I decided to create a class that would simply fire the screensaver after x minutes if it wasn't already running.
The first thing you need to do when trying to programmatically manipulate the API is import System.Runtime.Interopservices (and please, don't send me email pointing out that the first thing is turning on your computer, then opening the IDE etc ;-) - I know that already).
So, I created a class that looks roughly like the following:
using System.Runtime.InteropServices;
namespace ScreenSaver
{
public class ScreenSaver
{
[DllImport("User32.DLL")]
public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
public const Int32 WM_SYSCOMMAND = 0x112;
public const Int32 SC_SCREENSAVE = 0xF140;
public SceenSaver(IntPtr windHandle)
{
//
// TODO: Add constructor logic here
//
SendMessage(windHandle , WM_SYSCOMMAND, SC_SCREENSAVE, 0);
}
}
}
| Now, this is pretty straightforward code. I declare an external function called SendMessage that takes a handle to a form, and 3 other parameters. I had found the original example of this in John Paul Mueller's book, .NET Framework Soluctions, In Search of the Lost Win32 API, and that's where I found the constants. However, since I didn't want to fire this code from a form per se, but make a class that would make the implementation cleaner, I had a problem. What was I going to pass a handle to? So In the name of experimentation, I tried passing in IntPrt.Zero which predictably failed miserably. Since that didn't work, I knew I'd need to handle of a form to get this to work. Well, that's easy enough in C#, just pass in the form's handle to the constructor of your class and viola'.
Once this is in place, one line of code can call tell you OS to fire the screensaver... SceenSaver s = new SceenSaver(this.Handle);
There are two main points that I'd like to emphasize here. The first is that .NET does a lot for you natively, but it's still maturing, and until then, Interop is necessary to do many things <Because C# supports unsafe code, it's probably a little better suited to many such tasks, but I don't want to think of opening that can of worms.> 2) A big part of finding out how to accomplish many of these tasks is knowing that they exist and finding documentation on them. Once you have that, you can wrap them in convenient and easy to use .NET classes and do a lot, with very little. With a few other lines of code (6) I think you can get this to work, but I'll leave that up to you to find out...Or you can write me at bill@devbuzz.com <sans the nospam> if you want a hint on using the screensaver to your advantage.
|
|