Question

VB6, Service - Best Practices

Asked by: CI3

I've got zero experience with creating windows services.  So not even sure the best way to approach this.  I basically started a simple VB6 project (one module, no forms) that checks to see if a process is running and writes the info to a database.  So essentially the meat of the code is the Sub Main():

Private Sub Main()
    'start polling
    Do Until EndNow = True
        CheckAndUpdateTheDB
        Sleep 10000
    Loop
    'do cleanup and end
    DoFinalTasks
    End
End Sub

My questions are:
1)  Is this a valid way for a service to run?  Just some looping code in a Sub Main()?
2)  How do I trap for when the service is started or ended?  Like currently EndNow never changes to True.  Id like to run some final code when the service is stopped.

Thanks

This Question has been solved and asker verified All Experts Exchange premium technology solutions are available to subscription members.

Subscribe now for full access to Experts Exchange and get

Instant Access to this Solution

  • Plus...
  • 30 Day FREE access, no risk, no obligation
  • Collaborate with the world's top tech experts
  • Unlimited access to our exclusive solution database
  • Never be left without tech help again

Subscribe Now

Asked On
2009-10-05 at 13:03:58ID24786829
Tags

VB6

,

Visual Basic 6

,

Service

Topic

Visual Basic Programming

Participating Experts
3
Points
500
Comments
19

Trusted by hundreds of thousands everyday for fast, accurate and reliable tech support.

  • "The time we save is the biggest benefit of Experts Exchange to Warner Bros. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange." Mike Kapnisakis, Warner Bros.
  • "Our team likes having a resource that is more secure than just using Google and most experts using this service really know their stuff. It's nice to look here first versus using Google." Dayna Sellner, Lockheed Martin
  • "Anytime that I've been stumped with a problem, 9 out of 10 times Experts Exchange has either the accepted solution or an open discussion of the potential solution to the problem." Kenny Red, eBay Inc.

See what Experts Exchange can do for you.

Got a question?

We've got the answer.

Experts Exchange has been collecting answers to technology questions since 1996…3 million and counting! If you have a question, chances are we already have your answer.

Screenshot of Experts Exchange Knowledgebase

Need individual assistance?

Our experts are ready to help.

If you can't find the exact answer you're looking for, ask our exclusive community of 50,000 experts. You’ll get a personalized answer from a trusted professional.

Screenshot of Experts Exchange Knowledgebase

Want to learn from the best?

Read articles from industry experts.

Thousands of free tech tips, tricks, how-to’s and tutorials are available in our peer reviewed articles section. See for yourself how smart our experts are, no login required.

Screenshot of an Article

Working on a long term project?

Store your work and research.

Save solutions to your questions, answers you’ve discovered through searching plus helpful articles in your personal knowledgebase for easy future access.

Screenshot of Experts Exchange Knowledgebase

Access the answers to your technology questions today.

Subscribe Now

30-day free trial. Register in 60 seconds.

What Makes Experts Exchange Unique?

Members of the expert community talk about why the experience at Experts Exchange is different than what you will find anywhere else.

Trusted by the world's most respected brands.

image of each brand's logo

Faithfully serving IT professionals since 1996.

Experts Exchange Logo

Try it out and discover for yourself.

Subscribe Now

30-day free trial. Register in 60 seconds.

Related Solutions

  1. CDONTS in VB6
    I have a quick question, I cannot find the object reference in VB6 for the CDONTS library. Can someone please direct me to this. I can only find CDO 1.2 library which is much different. Thanks. ch
  2. Using MAPI to poll an Exchange server in VB6
    Hi everyone. I'm creating a VB6 app to poll an Exchange2k server mailbox for incoming messages and read them into variables. I've looked around on the net for some source code to do this all I've found is VC++ code. Could someone help me out please? Cheers.
  3. VB6 Thread to Poll Hardware on Parallel Port
    VB6 on Win98 I have a VB6 program which calls a DLL written in ASM. This DLL communicates with some custom hardware on the parallel port. The front end of the program display information from this device. I need to create a background thread to poll the hardware and then ...
  4. Sleep
    Looking for a quick 'sleep' method for a splash screen
  5. VB6 error trapping
    I have to make sure that a set of textboxes on a VB6 form have either no value or a numeric value. I took a first cut at it, but it just doesn't work at all. I have a function called VerifyInput that returns a string telling how the attempt at verification turned out. The tex...

Free Tech Articles

  1. WARNING: 5 Reasons why you should NEVER fix a computer for free.
    It is in our nature to love the puzzle. We are obsessed. The lot of us. We love puzzles. We love the challenge. We thrive on finding the answer. We hate disarray. It bothers us deep in our soul. W...
  2. SCCM OSD Basic troubleshooting
    SCCM 2007 OSD is a fantastic way to deploy operating systems, however, like most things SCCM issues can sometimes be difficult to resolve due to the sheer volume of logs to sift through and the dispe...
  3. Migrate Small Business Server 2003 to Exchange 2010 and Windows 2008 R2
    This guide is intended to provide step by step instructions on how to migrate from Small Business Server 2003 to Windows 2008 R2 with Exchange 2010. For this migration to work you will need the fo...
  4. Create a Win7 Gadget
    This article shows you how to create a simple "Gadget" -- a sort of mini-application supported by Windows 7 and Vista. Gadgets can be dropped anywhere on the desktop to provide instant information, ...
  5. Outlook continually prompting for username and password
    There have been a lot of questions recently regarding Outlook prompting for a username and password whilst using Exchange 2007. There are a few reasons why this would happen and I will try to cover t...
  6. Backup Exchange 2010 Information Store using Windows Backup
    There seems to be quite a lot of confusion around the ability to backup Exchange 2010 using the built in Windows Backup feature. This stems from the omission of this feature prior to Exchange 2007 s...

Cloud Class Webinars

  1. Avoiding Bugs in Microsoft Access
    Alison Balter takes and in-depth look at avoiding bugs in Access. In this webinar you will learn about using the immediate window to debug your applications, invoking the debugger, using breakpoints to troubleshoot, stepping through code, setting the next statement to execute, ...
  2. Top 10 Best New Features in Visio 2010
    Scott Helmers gives live demonstrations of the top 10 new features in Visio 2010. This webinar will teach you how to create compelling diagrams by adding shapes to the page with a single click, linking the shapes in a diagram to data in Excel (or SQL Server, or SharePoint), ...
  3. IT Consultant Business Secrets Revealed
    Michael Munger, Experts Exchange tech pro and IT consultant, pulls back the curtain on his very successful businesses and answers question on every IT consultant and business owner should know about. He shares secrets on what he did to solve the 5 most common problems in IT, ...
  4. Disaster Recovery and Business Continuity
    Quest CTO, Mike Billon, gives an overview of the steps involved in building a dunamic disaster recovery plan. Through case studies and an examination of software/hardware tooles for monitoring and testing, you'll gain a better understandin of where you are, where you want ...
  5. Organize Your Visio Diagrams with Containers and Lists
    Scott Helmers uses cross functional flowcharts, wireframe diagrams, data graphic legends and seating charts to teach you: how to ustilize all three new structured diagram components in Visio 2010, the best practices for organizeing shapes in previous version of Visio, how to organize ...
  6. How to Us Objects, Properties, Events and Methods in Microsoft Access
    Alison Dalter gives an in-depbth look at objects, properties, events and methods in Microsoft Access. In this webinar you will learn about using the object browser, referring to objects, working with properties and methods, working with object variables, understanding the ...

Join the Community

Give a Little. Get a Lot.

Join the community of experts here and help other tech pros by answering question in your area of expertise. You can earn FREE access to all Experts Exchange's premium features and resources.

Join the Community

Answers

 

by: VBClassicGuyPosted on 2009-10-05 at 13:21:54ID: 25499282

For one thing, EndNow will never change to True because you have no statement to tell it to do so (unless CheckAndUpdateTheDB is a subroutine snd you do it there, AND EndNow is a Public variable.

Secondly, the Sleep function will tie up some processing time. I would use this instead:

  Timeout! = Timer + 10                                        'set timeout
  If Timeout! > 86399 Then                                       'if greater than 23:59:59
     Timeout! = 10                                             'set to tomorrow
  End If                                                         '(prevents infinite loop @ midnight)

...and...

  Do

     If Timer > Timeout! Then Exit Do

     DoEvents
  Loop

 

by: Brook1966Posted on 2009-10-05 at 13:34:37ID: 25499416

I would advise a couple of things for this...
1.  The methodology is not bad but put some allowances to stop the service normally..
    Allow the checkandUpdate function to look somewhere ( in your db, an .ini file, or even the registry ) for an off switch.  Some put timers in their code for stop and starting.
2.  Create either a text file for logging ( myapp.process.log ) or a table in your DB.  The text file is preferable in the event the db has stopped running.  Place start time, run time and stop time in the log so you can go back and check progression.
3.  Allow the logging to be turned on or off.
4. ERROR TRAP - and also write to a log file - preferably even a different file ( myapp.error.log ).

 

by: CI3Posted on 2009-10-06 at 14:01:08ID: 25509917

VBClassicGuy: Thanks, I did see other people talk about sleep not being that great.  But I'm not sure I understand your code though.  Well I mean I understand the code as its written but don't know how you mean to use it.  I'm assuming there is more to it that i'm not getting

Brook1966: Thanks, Good idea on the logging.

So I'm guess i'm still looking for how to tell when my applicaiton is ending.  So for example I guess I was picturing someone shutting down their machine and me having some sort of event to change my variable of EndNow to True so that it would fall threw the loop and do the final sub of 'DoFinalTasks' so that I can wite one last time to a database.  You know just like I could do in a forms Form_Unload() sub. (But again I don't have any forms all code is just in 1 modual)

Thanks!

 

by: Brook1966Posted on 2009-10-06 at 14:12:46ID: 25510015

you could put that code in the Form_Unload event

public sub Form_Unload()
  update database or write to log here

end sub

 

by: Brook1966Posted on 2009-10-06 at 14:13:24ID: 25510023

but  you are not using a form....

 

by: VBClassicGuyPosted on 2009-10-06 at 14:16:36ID: 25510057

My code snippet just "pauses" (or "sleeps", if you prefer) your program for the specified number of seconds. In the case of the example, 10 seconds. The advantage over the Sleep command is that it doesn't hog the CPU cycles. The DoEvents statement lets the PC perform other duties like updating the screen, responding to other program's needs, etc. In other words, it won't "freeze" your PC for 10 seconds like Sleep will.

By the way, if someone shuts down your PC, you will need an API call on a fast timer to detect the "kill application" message sent to your program, so you can do your EndNow thing. But shutdowns can still sneak by you if timed just right. And, if someone cuts off the power, unplugs the PC, or there is a power outage, you're SOL. And we haven't even talked about untrapped errors causing the program to terminate.

I have an "Event Log" in my programs that keeps track of everytime a user starts the program, and everytime they exit it. I don't even bother with trying to catch shutdowns, blackouts, and errors. I just know in the log that if I see to "IN"'s in a row without an "OUT" between them, the program terminated abnormally.

 

by: CI3Posted on 2009-10-06 at 14:47:56ID: 25510271

VBClassicGuy: got the timer thing finally, my problem was I didn't realize that "timer" was actually a built in function of VB6.  Wrote a small sub to pass number of seconds too pause for and the timer code you supplied works great!  Good info!

As for the part on knowing when the exe is ending... hmmm wonder if maybe I should just make this a standard exe with a hidden form and make it run on startup of the PC instead of making it a service.  My thought on making it a service was I didn't want our users to see it and be able to end task on it.

The point of my app is: we have some accounting software here they need to know who is actively connected to it because sometimes they need everyone out so they can do certain tasks in it which require every out except the person doing the task.  So usually they send out email after email telling everyone to get out but inevitably someone left it running while they stepped out.  So I wrote this small app to check if the accounting apps process is running on a machine and write back to a database the user name, ip, workstation name and if its running or not back to a database.  Then I have a simple web page management can look at to see who is running it.  Everything works fine in development Im at the point now of putting it on everyones machines and was trying to come up with the "best way" to implement it on users machines.  Just making it an exe that runs on startup with a hidden form seemed not stupid proof enough for some of our users since they can see it in the task manger and end task on.  :)

But maybe thats the best I can do?  Any suggestions now fully knowing the scenario? (I'll answer back tomorrow Im just heading out)  Thanks again.

 

by: VBClassicGuyPosted on 2009-10-06 at 15:18:21ID: 25510515

I have some programs that must stay running all the time, or data is lost. For these apps, I remove the "X" in the main form's upper right-hand corner, remove "Close" and "Maximize" from the system menu so they can only Minimize and Restore, and put in an "Easter egg" to get the Exit button to enable. Only high-level managers know of this "back door" and can exit the program. Most of my customers are too PC illiterate to know how to use Task Manager.

This back door is usually something like "hold down the Shift key and right-click on a certain control (maybe the PictureBox containing our logo), then enter the password". On a really secure program, this password changes daily (there is code in the program to generate the password-of-the-day, and managers are given an applet that generates this password).

I figure that's the best i can do. No program is 100% safe as long as a 16-year-old hacker/gamer is available LOL.

 

by: VBClassicGuyPosted on 2009-10-07 at 06:11:46ID: 25514906

Oh by the way, if your users can kill an app by using Task Manager, they can also stop the service from the Processes tab. Not much you can do if someone really, really wants to stop your program/service.

 

by: egl1044Posted on 2009-10-07 at 09:23:06ID: 25517128

<<< My thought on making it a service was I didn't want our users to see it and be able to end task on it. >>>

Add code to a form, Compile to exe run it and try terminate the process.

Let this be your warning :)

Option Explicit
 
Private Const SE_PRIVILEGE_ENABLED As Long = &H2&
Private Const TOKEN_ADJUST_PRIVILEGES As Long = &H20&
Private Const TOKEN_QUERY As Long = &H8&
 
Private Type LUID
LowPart As Long
HighPart As Long
End Type
 
Private Type TOKEN_PRIVILEGES
PrivilegeCount As Long
LuidUDT As LUID
Attributes As Long
End Type
 
Private Declare Function OpenProcessToken Lib "advapi32" (ByVal ProcessHandle As Long, ByVal DesiredAccess As Long, ByRef TokenHandle As Long) As Long
Private Declare Function LookupPrivilegeValueW Lib "advapi32" (ByVal lpSystemName As Long, ByVal lpName As Long, ByRef lpLuid As LUID) As Long
Private Declare Function AdjustTokenPrivileges Lib "advapi32" (ByVal TokenHandle As Long, ByVal DisableAllPrivileges As Long, ByRef NewState As TOKEN_PRIVILEGES, ByVal BufferLength As Long, ByRef PreviousState As Any, ByRef ReturnLength As Any) As Long
Private Declare Function GetCurrentProcess Lib "kernel32" () As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
 
Private Declare Function LoadLibraryA Lib "kernel32.dll" (ByVal lpLibFileName As String) As Long
Private Declare Function GetProcAddress Lib "kernel32.dll" (ByVal hModule As Long, ByVal lpProcName As String) As Long
Private Declare Function CallWindowProcA Lib "user32.dll" (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal uMsg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
Private Declare Function FreeLibrary Lib "kernel32.dll" (ByVal hLibModule As Long) As Long
 
Private Sub EnablePrivilege(ByVal szPrivilegeName As String)
 
    Dim hToken          As Long
    Dim TokenPriv       As TOKEN_PRIVILEGES
    
    ' Query the token
    Call OpenProcessToken(GetCurrentProcess, _
        TOKEN_ADJUST_PRIVILEGES Or _
        TOKEN_QUERY, hToken)
        
    Call LookupPrivilegeValueW(0, _
        StrPtr(szPrivilegeName), _
        TokenPriv.LuidUDT)
        
    ' Enable
    TokenPriv.PrivilegeCount = 1
    TokenPriv.Attributes = SE_PRIVILEGE_ENABLED
    
    ' Attempts to adjust the privilege.
    Call AdjustTokenPrivileges(hToken, 0, TokenPriv, 0, ByVal 0&, ByVal 0&)
 
    CloseHandle hToken
    
End Sub
 
Public Sub ProtectProcess()
    
    Dim hMod        As Long
    Dim Addr        As Long
    
    Call EnablePrivilege("SeDebugPrivilege")
    
    hMod = LoadLibraryA("ntdll.dll")
    
    If hMod <> 0 Then
       Addr = GetProcAddress(hMod, "RtlSetProcessIsCritical")
       Addr = CallWindowProcA(Addr, 1, 0, 0, 0)
    End If
 
End Sub
 
Private Sub Form_Load()
  Call ProtectProcess
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:

Select allOpen in new window

 

by: VBClassicGuyPosted on 2009-10-07 at 11:21:31ID: 25518291

Very impressive, egl1044. That's one of those pieces of code one wants to squirrel away in case you need it down the road. Good job!

 

by: egl1044Posted on 2009-10-07 at 11:50:55ID: 25518567

lol :)

 

by: CI3Posted on 2009-10-07 at 11:51:45ID: 25518579

Thanks egl1044.  I tried the code and got a Blue Screen of Death so a bit nervous about trying it again.  Basically I added a new modual, plopped in the code.  Ran the project.  Stopped the Project.  Compiled an EXE.  Ran the exe.  Didn't see it listed in processes.  Then since the form is hidden on it just for testing after 60 seconds i made it pop up a window and ask if i wated to exit.  I said yes and in code is just calls "unload me".  Thats then i got the BSoD.

BSoD message:
A process or thread crucial to system opration has unexpectedly exited or been terminated
...the usual other info...
STOP 0x0000000F4 (0x00000003, 0x89AOD670, 0x89AOD7E4, 0x805D297C)

Any ideas on why this might have happened?

 

by: egl1044Posted on 2009-10-07 at 12:01:17ID: 25518666

That is the intended behavior of the code. Because the process bit flag was changed to (critical) windows thinks it's a critical process that needs to be running for the operating system to work.
The code was just some geek humor to show that it's not a very good idea to stop a user from ending a process. :)

 

by: CI3Posted on 2009-10-07 at 12:49:31ID: 25519251

egl1044: I'll take that with a grain of salt since you gave me about what I asked for - although I really just wanted to hide the process from the task manager not BSoD a machine if the process was stopped.  But your warning of: "Let this be your warning :)" didn't make me think hey this will BSoD my computer losing any changes to any documents I had open.  Might be a tiny bit more specific next time for those of us who just code as part of their jobs and aren't code geeks.

VBClassicGuy: Thanks for all the help and suggestions!  I think I'll just go the easy route and make this a normal exe with a hidden form that starts on startup.  I'll let management worry about people not running the software after I'm done putting it on peoples machines.

 

by: CI3Posted on 2009-10-07 at 12:54:58ID: 31637405

End result wasn't what I had origianlly asked for but got some good info!

 

by: egl1044Posted on 2009-10-07 at 12:56:03ID: 25519329

<< hide the process from the task manager >>

Here is a small trick if your worried about task manager :)

The only way to actually prevent a process is what I showed, or hooking TerminateProcess.

Dim hFile As Long
 
Private Sub Command1_Click()
Close #hFile
End Sub
 
Private Sub Form_Load()
hFile = FreeFile
Open "c:\windows\system32\taskmgr.exe" For Binary Lock Read As #hFile
End Sub

                                              
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:

Select allOpen in new window

 

by: VBClassicGuyPosted on 2009-10-07 at 13:05:51ID: 25519430

Yeah, I run into similar situations with my customers. They want the program to do impossible (or VERY difficult) things to make up for their employee's "curiosity" or "playfulness". Some times I feel like telling them, "Look, at some point the user or management needs to take responsibility for their actions. Just add it to your rules...no guns at work, no drinking on the job or coming in intoxicated, no drugs, and YOU MUST RUN THIS PROGRAM to do your normal job functions. Period."

 

by: CI3Posted on 2009-10-07 at 13:17:32ID: 25519564

Exactly!  If I was a Dr. and someone came to me with a really weird thing like: "Hey Doc it hurts when i stick this paperclip in my ear"... I'd tell them: "then don't stick it in your ear!"  I certainly wouldn't fix the problem by surgically removing 6 inches of arm bone so they couln't reach their ears.

20120131-EE-VQP-002

3 Ways to Join

30-Day Free Trial

The Experts

98% positive feedback on 31,087 answers since March 2000. angeliii is a Microsoft Most Valuable Professional for his work with MS SQL Server & Develoment.

He has also proven his knowledge of Visual Basic Programming, PHP Scripting and Oracle Databases.

The Experts

97% positive feedback on 10,752 answers since July 2000. lrmoore has more than 18 years experience in the networking industry.

The six-time Mircosoft MVPs specialties include firewalls, virtual private networking, and network management.

Testimonials

"...and excellent source for support... Kind of like having your very own IT dept." Electriciansnet

Testimonials

"I was apprehensive at signing up at first. However... it has already made my life as an IT administrator much easier." JaCrews

Testimonials

"WOW! You guys have great, active, and knowledgeable people on here." moore50

Business Clients

Business Clients

In the Press

"If you’ve got a question... Experts Exchange can supply an answer.”

In the Press

"...an invaluable aid for both IT professionals and those who require tech support."

In the Press

"where IT professionals provide quick answers on just about any topic"

Business Account Plans

Loading Advertisement...