A watchdog application
This article is taken from content omitted during technical review of the a book entitled Network programming for .NET
(Buy at Amazon UK)
(Buy at Amazon US)

When
you have a server application that runs unattended for long periods of time,
you may wish to restart the computer on a daily basis, to free up lost memory,
and improve performance.
This
program will reboot the computer at a time specified by the user. It does so in
unattended mode, ensuring that any requests for user intervention are ignored
where possible. This includes messages such as ‘Do you wish to save
changes?’ There is no provision for
saving settings, or restarting this application once the computer has rebooted.
This program does not provide any means of automatically logging in.
To
include a program for automatic start-up, it may be included in the start up
menu manually. Alternatively, an entry can be made in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run.
Information on accessing the registry can be read in chapter 4
Make sure to save all your program data before
running this program, as it will turn off your computer without warning
In order to reboot a computer you need to use a windows API
(application programming interface) function named ExitWindowsEx contained in user32.dll.
Functions in the Windows API have a calling convention, which can be determined
by reading up on the particular function. A good reference point for the
windows API in C# and VB.NET is a available at http://custom.programming-in.net
The technology behind this interoperability between the
Windows API and .NET is known as P/Invoke (platform invoke). This technology
allows you to declare Windows API functions in your code in almost the same way
as you would declare native .NET functions. Each Win32 function call is
declared with a static extern method. The DllImport attribute is then
applied to that method. Parameters of the DllImport attribute
indicate the specific DLL and DLL entry point that is called.
The significant parameters of the DllImport attribute are as
follows:
·
CallingConvention indicates
the method by which arguments are passed to the unmanaged implementation.
·
CharSet manages name mangling
and indicates how to marshal String arguments to the method.
·
EntryPoint indicates the name
or ordinal of the DLL entry point to be called. To discover entry points in
DLLs, a utility named dependency walker is indispensable ( http://www.dependencywalker.com/
).
·
ExactSpelling indicates
whether the name of the entry point in the unmanaged DLL should be modified to
correspond to the CharSet value, if not set
then a case-insensitive search is made for the entry point.
·
PreserveSig indicates whether
or not the name of the entry point in the unmanaged DLL should be modified to
correspond to the CharSet value specified in
the CharSet field.
·
SetLastError indicates the
caller may call the Win32 API GetLastError function to retrieve more detailed information for errors that may
have occurred during the call to the API.
The trickiest part of P/Invoke is determining how to map
types between the Win32 call and the static extern method that
you declare. When migrating C++ style API declarations to .NET, there are some
general rules for mapping types. When a Win32 method needs a handle or pointer
(int *),
you should use an IntPtr. For pointers to strings (char * or LPCTSTR),
you can simply use the .NET String type.
It is sufficient to simply call ExitWindowsEx on Windows 98
to reboot a computer. However from Windows NT upwards, you need to acquire
privileges to reboot a computer from code.
In this case we request a privilege named SeShutdownPrivilege from
the AdjustTokenPrivileges
API call. Unfortunately the privilege architecture of the Windows NT kernel is
beyond the scope of this book.
Start a new project in Visual Studio .NET. Add a label named
lblCurrentTime
to the form, along with a DateTimePicker of the same name. The latter control
should be set with format to time. A check box named chkReboot is required to enable
& disable automatic rebooting. Finally, add a timer named tmrReboot.
Ensure that the timer is set with enabled to true.
The timer will poll on a check that will compare the current
time with the time specified by the user. A check box is used to prevent the
computer from rebooting as soon as the program is started.
Page 2
Page 3
Page 4