this page is best viewed with any browser™.

How To Write an NT Service in VB5

Polkatulk is

Please read my new page about the NT Service Custom Control. It enables you to build true NT services in NT (with built-in installation + uninstallation)

Please note: this is a fairly technical article, i am not going to hold anyone's hand. If, however, you are a techie or hacker and you don't understand something, you should probably mail me, otherwise do some reading and come back later. Also if you don't understand the point of this article please don't read it. (I especially hate advice like , 'Why don't you write in C++ or assembler?')

a little clarification

First off, let me say that it is not entirely truthful to say what i will show you how to write is an nt service (this is essentially impossible because you can't create true dlls in vb and a service has to export certain entry points to be run by service control manager). What we are writing is a program that gets executed by a program called srvany (written by microsoft), which is a service. we use another program from ms called instsrv to install srvany as a service ie

instsrv MyService c:\winnt40\system32\srvany.exe

and then you edit the registry to create the necessary entries:

REGEDIT4

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyService]
"Type"=dword:00000110
"Start"=dword:00000002
"ErrorControl"=dword:00000001
ImagePath="c:\\winnt40\\system32\\srvany.exe"
"DisplayName"="Test"
"ObjectName"="LocalSystem"

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\MyService\Parameters]
"Application"="C:\\WINNT40\\system32\\ntsvc.exe"

a few problems, and why vb5

of course, if you've tried writing services in vb you'd probably noticed the 500-pound gorilla sitting in the corner. The way the SRVANY documentation puts it is this:

For WIN32 graphical applications: when the currently logged-in user is logging-off, all WIN32 top-level windows receive WM_QUERYENDSESSION and WM_ENDSESSION messages. Some WIN32 applications choose to terminate upon receipt of such messages. In order for your WIN32 application to survive logoff, it must not do that: instead, your windows procedure should call the default windows procedure on these messages.}

which means, as soon as you logoff and logon your machine the program is gone, defeating the whole point of services. This is why the heading of this page says VB5. now subclassing of windows is built into vb you can write code like this:

Module1.BAS:

Public Sub Hook(lwnd As Long)
WndProc = SetWindowLong(lwnd, GWL_WNDPROC, AddressOf WindowProc)
End Sub


Function WindowProc(ByVal hw As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long

If uMsg = WM_QUERYENDSESSION Then
WindowProc = True
Exit Function
ElseIf uMsg = WM_ENDSESSION Then
WindowProc = True
Exit Function
End If

WindowProc = CallWindowProc(WndProc, hw, uMsg, wParam, lParam)


End Function

Form1.FRM:

Private Sub Form_Load()

Hook (Me.hwnd)

End Sub

i'm working on a solution for programs without forms (OLE servers, very important).

now you cut and paste the code into your program and compile it. you start your service and logoff and on. voila, it's still running (you set it to interact with the desktop, just for testing). then you notice something strange.

something i never expected

you click on the close button, doesn't work, you click on alt-space,close, you try the default close method of your program, all fail. weird. for some reason only microsoft knows your vb program has become immune to closing (or worse you could get a strange message about floating point exceptions!!?)

but when you choose service control manager to close your service it obediently closes. what the..? referring again to the srvany docs:

WARNING:
When the service is stopped, it terminates the application via the WIN32 TerminateProcess() API:

Since you can get your apps current process, you can do that yourself! i created a sub called, strangely enough, EndApp like this:

Public Sub EndApp()

Dim uProcess As Long
uProcess = GetCurrentProcess
Debug.Print TerminateProcess(uProcess, 0)



End Sub

You then put a call to EndApp in place of any End statement and in all the necessary Form_Unload events (ie ones that would normally end your app).

And now you have a functioning nifty service you can show off to your friends (especially those who 'know' it can't be done).

Download stuff:

Download srvany.zip (contains srvany.exe, srvany.wri, instsrv.exe) 23kb

Download a funky demo: ntsvc.zip (the src and a ~sample~ .reg file and the .exe) 5kb

people have been enlightened since 30/12/97.

BackUpHome

polkatulk@geocities.com This page hosted by GeoCities Get your own Free Home Page

1