WinBatch Tech Support Home

Database Search

If you can't find the information using the categories below, post a question over in our WinBatch Tech Support Forum.

TechHome

Run Winbatch as a Service

Can't find the information you are looking for here? Then leave a message over on our WinBatch Tech Support Forum.

A NT Service - More Info

Keywords:     NT service 95  wntSvcCreate error 531:  Invalid Parameter

Please see the followinging Windows System Journal Article 'Why Do Certain Win32 Technologies Misbehave in Windows NT Services?':

http://www.microsoft.com/msj/0398/service2.aspx

General Question using Winbatch as a Service:

I would like to know if anyone has tested running a Winbatch executable as a service under Windows NT Server 4.0. This can be facilitated by using SRVANY.EXE which is located on the NT Resource Kit or can be downloaded off of the Web. Please let me know if this is possible using this solution or another that you are aware of.

Answer:

WinBatch can run as a native mode service.

It is possible to create a compiled WinBatch program that will run as a native service under Windows NT or Windows 2000. To do this, compile the WinBatch script as usual using the 'Small EXE for Networked PC's' option in the WinBatch Compiler, but make sure to specify an output file with an extension of ".EXS" instead of ".EXE". Alternatively, you can simply rename an existing WinBatch program (version 2001 and higher) by changing its extension from ".EXE" to ".EXS".You can install a WinBatch service (or any service) using the wntSvcCreate function in the WIL Windows NT extender (see the Win32 Network Extender help file).

A WinBatch service can be configured in the Service Manager (in Control Panel) to run automatically on system startup, or manually on demand. In either case, when the WinBatch service starts up it processes the script just like a normal WinBatch program.

If you want the WinBatch service to wait for a particular time or event to occur, you can use any of the normal WIL methods (TimeDelay, TimeWait, WinWaitExist, etc.).

You can also use any of the following service functions: SvcSetAccept, SvcSetState, SvcWaitForCmd.

You can also use loops or branching (For, While, Goto, etc.) to cause the WinBatch service to continue running for an indefinite period of time. When processing reaches the end of the script (or a Return or Exit command, or a Cancel event), the WinBatch service will automatically stop. You can force a WinBatch service to stop prematurely by using the "Stop" function in the Service Manager (in Control Panel), or using another service control program (such as the wntSvcControl function in the WIL Windows NT extender). A WinBatch service will exit automatically on Windows shutdown.

It is unnecessary to use IntControl(1001) with a WinBatch service, but doing so will not hurt. WinBatch services do not exit when a user logs out.

If you are making a WinBatch service that will not be installed as an interactive service, you should use IntControl(38) at the beginning of the script to prevent WIL from displaying any unexpected error message boxes. If a non-interactive service attempts to interact with the desktop, it can cause the script to hang.

Notes:

  1. Make sure you specify a real account to give the script network access. The "LocalSystem" account is not allowed to access the network, thus a service that is running under the "LocalSystem" account cannot access network resources.

  2. To have a service access the desktop (i.e., Interact with the desktop with the 256 flag), that service must log on as the "LocalSystem" account, and be allowed to interact with the desktop.
Example:
AddExtender("WWWNT34i.DLL")
ServiceName="At Your Service"
DisplayName="AYS"
BinaryPathName="c:\temp\AtYourService.exs"
LoadOrderGroup=""
ServiceStartName="LocalSystem"  ;<==
Password=""
createstring=Strcat(ServiceName,"|",DisplayName,"|",BinaryPathName,"|",LoadOrderGroup,"|",ServiceStartName,"|",Password)
ServiceType=256|16
StartType=3
ErrorControl=0
createflags=strcat(ServiceType,"|",StartType,"|",ErrorControl)

wntSvcCreate("", createstring, createflags, "","")
Message("Done","Added a service to the service control manager database.")

See WinBatch Help, for details.


Shutting down Winbatch Service:

I have a NT service written with Winbatch (2001J). I would like to test during the execution if NT is in shutdown mode to stop properly my execution instead of receiving errors caused by the shutdown in process.

The errors received are not typical of the shutdown and may appear during the service life and must not stop the service.

Intcontrol (1005, 0, 0, 0, 0) never returns @true.

Answer:

Ummm. Are you using a new-style service or an old-style servcie, or an SRVRANY type service.

Starting in WinBatch 2001J (and updated in 2001K) you can write better services that can be notified of relevent system events. See Winbatch.hlp. Lots of new service documentation in that help file.

***You must use INSTSRV.EXE to install a service that runs SRVANY.EXE. You then go into the registry subkey used by that service and add some named registry values that tell that particular instance of SRVANY.EXE what particular non-service .EXE program should be run in the context of a service.***

Configuring winbatch to run as a service:

These notes describe installing a service which will run a winbatch script at service startup.

* Items you must have on hand before starting:

  1. A compiled and debugged winbatch script which can be run as a service. in this example, the script is: c:\temp\wbtsrv.exe

    Following these notes are two samples of wbt scripts which can be run under a service.

  2. One copy of any NT resource kit which contains the program 'srvany.exe'. the program srvany must be on the local machine - it cannot be installed from a networked drive.

* Instructions:

  1. Run instsrv to install the service, giving it a made-up name. in this case, the locally-picked name is winbsrv. from a dos or command line) enter this command:
    
         instsrv winbsrv  c:\temp\srvany.exe
    
    Should get msg: "the service was successfully added" note: to uninstall the service:
    instsrv winbsrv remove 

  2. Run regedt32 to edit the registry in order to specify which winbatch script you want run when 'winbsrv' starts'. from a dos prompt or command line:
    
         regedt32
    
    go to:
    
         HKLM\system\CCS\services\winbsrv
    
    • Select edit/add key and make the key name 'parameters'
    • Leave class blank
    • Select the 'parameters' key, and click on edit/add value,
    • For the 'value name', enter: application
    • For the 'data type', enter: REG_SZ (probably the default)
    • Click on ok, and the 'string editor' box will appear
    • For the 'string', enter: c:\temp\wbtsrv.exe

  3. Go to the services panel (in Windows 2000, it's in Control Panel under Administrative Tools/Services), and select winbatch and 'startup'. Make sure the 'allow to interact with desktop' attribute is set if anything in the script or called code requires it. Click on 'start', and the service should start up.

    Note: on the way to debugging this process several errors were encountered, and each one of them had entries describing the error and how to handle it in technet.

Here's a little background information on Windows services:

A service is something that runs whether a person is logged into the workstation or not. This is so that if a person logs out, the program continues to run. This has a variety of uses, such as to have a scheduling script that will run at preset times no matter whether a person is logged in or not, as long as the computer is running.

Another use is virus scanning software, which you don't want to not be running just because you don't have a person logged in.

Finally, you may want to have an admin service logging the users who log in or out of a multi-user machine, or may prefer to have some program running in the background continuously, and prefer to have it load once on a boot, rather than with each login.

If you have such a need, consider running as a service. With NT, you need to use a utility, because of the security on the NT. With Win95, since there is no security of that sort, you simply have to add an item to the registry to create a service once you tell your Winbatch to run as a service.

There is *a little bit* of built in support for running WinBatch as a service, via IntControl(1001 ....


        IntControl(1001,1,0,0,0) 
at the top of your script and don't trust any environment assumptions.

For NT, you need both the IntControl 1001 AND the SRVRANY.EXE utility from the NT resource kit. IntControl 1001 works alone for 95 but with NT needs the SvrAny.Exe utility.

The reason you need to use the external utility SVRANY in NT and not in 95 is because of the fact that you cannot boot NT without logging in as somebody. You need to be logged in to have any access rights at all. Therefore, by that logic, you cannot send keys to NT services, you cannot assume any specific access rights, etc.

The srvany utility with NT resourcekit allows you to run any application as a service. To use this, you have to install Srvany as a service (you can do this with another resource kit utility - srvinstw.exe). You then change the parameters registry setting for this service and add your application.

A better solution for all the above is to use the Rservice utility which allows you to install the service local or remotely (works very nice). This utility ships with SMS 1.2 SP 3 -(Rservice.exe is provided in the latest Systems Management Server 1.2 Service Pack). I have used the above method in a large scale environment and I am very impressed.

Basically the IntControl(1001,...) simply tells the script to ignore user shutdown messages. For example there is a USER_IS_LOGGING_OFF command that is sent to all applications, and they dutifully quit. This tells WinBatch to ignore such messages and continue to run.

The limitations we've found out so far with running Winbatch as a service this way are:

  1. Environment is toast. Cannot make many assumptions about PATH or any other environment variables.

  2. SendKeys do not work unless you allow the service to interact with the desktop of a logged on user. In other words, as long as the service is allowed to interact with the desktop and a user is logged in, you can send keystrokes. Not recommended.

  3. As it is not a real "user" making network connections can be problematic unless server is open to everybody.

  4. Do not use any function that puts up a message box.

  5. Error messages will be hidden, so debugging is tricky. If you allow it to interact with the desktop, then you may be able to debug it.

  6. Since you can't send keystrokes to a service, Winbatch *may* be able to push buttons on a dialog box via the Control Manager extender. But only on applications also lanuched by WinBatch running as a service. I don't think it can interact with the logged in desktop unless it was set up to do so.

Running WB Service with Admin Rights:

Has anyone ever written a WinBatch program that runs as a service, with admin rights, waiting for a task, job to process that is initiated by the current user logged on? What is the best way of managing the communications or interface between the two programs (with different sid's).

Answer:

I don't think anyone has done this.

I recommend disk files as the communications interface. The logged on user can make a file to do something. The service can:


while 1
  TimeDelay(5)
  if FileExist("flag.file")
    while FileSize("flag.file")==0
      TimeDelay(1)
    endwhile
    ;DO SOMETHING
  endif
endwhile

There is no way currently to run winbatch code with Admin rights from a normal users account. There are a couple of schemes where you can log the user off and auto-log in as admin to do the dirty work...but the security holes are atrocious.

1932 WinExec Undefined Error when Running Winbatch as a Service:

I'm getting the 1932: WinExec: Undefined Error, when running Winbatch as a service under NT.

I'm using SmartBatch32, an NT-based job scheduler, to launch a number of WinBatch jobs. I just hit my first snag.

This job attempts a DDE initiate to cc:Mail. If zero is returned, it attempts to start cc:Mail as follows:


Run(ccMailExe, ccMailLogin)
If I double-click on the WBT file to launch it, the job runs to completion. If SmartBatch launches it I get the 1932: WinExec: Undefined Error dialog box. I hope you might have some ideas because I've pretty much exhausted the SmartBatch people.

I've tried RunShell instead, but it didn't help. I note from the WIL manual that 32-bit WinBatch uses the CreateProcess API, but the message appears to come from WinExec? Also, and for what it's worth, SmartBatch is running as an NT Service.

Answer:

There are problems running Winbatch scripts from services. For one, no environment information is available.

You can try FileExist(ccmailexe) and see if the script can see it.

You might also try adding DirChange to the desired directory just before doing the RUN statement.

Question (continued):

Still working on this. I've given up on DDE and am now trying to use keystrokes. I'm using WinExist() to look for windows to display and go away, but WinBatch never sees the window even though it's there, albeit running under an NT service.

Answer:

  1. WinBatch running as a service CANNOT send keystrokes to anything.

  2. Programs running as a service must be interactive for a WinBatch script (not running as a service) to send keystrokes to.

WB as a Service and Intcontrol 66:

I have written a WinBatch routine that runs under Win95 as a service (via IntControl 1001). When I logout of the system by selecting Start-Shutdown-Close all programs, the WinBatch service continues running (as expected). If I use IntControl 66 to log off, the script is terminated (not expected). I tried setting IntControl(12,9,0,0,0), but to no avail.

I have a "daemon" script that runs on a remote-control host computer. The script's job is to make sure that the host logs off gracefully when someone disconnects. The script never terminates. It runs in the background and waits for a connection, then monitors the connection. When the user disconnects, the script cleans up and logs the user out (basically a "Close all programs and log on as a different user"). The script then waits for the next caller.

I have this jerry-rigged right now - when the caller disconnects, the script WinActivates Program manager and sends an Alt-F4, Alt-C, Alt-Y. All this does is activate the "Shut Down Windows" box and selects the "Close all programs..." button. This works as it should. I had expected IntControl 66 to behave identically, but it has the undesired side effect of terminating the script. BTW, I am not currently using the WinBatch "Shutdown Mode".

Answer:

What script is the IntControl(66 in ??? It sounds like you have the IntCotrol(66 in the same script that is running as a service.

If it is in the shutdown script...then that is expected behavior. But you are already in shutdown code so it should not be necessary.

Yes, that will terminate the script. I never did quite realize that before, but the original intent of the IntControl(66 was to shut down the computer...its been modifies since....

However I suggest a completely different method. I suggest letting the script shut down as it wished, and then when the "autologon" occurs, simple launch a new copy of the script by placing it in the RUN- line of win.ini or perhaps in the registry under the RUN key.

Question (continued):

I may have not fully understood your suggestion, but I don't think that it will accomplish what I need it to do. My script actually performs the autologin. Any Programs listed in the registry's "Run" key are executed *after* the user logs in. My script is run from the "RunServices" key, which executes its list when the computer starts up, while the "Network Logon" box is on the screen. Unfortunately, "RunServices" programs are not re-launched after a user logs out. I guess that the reasoning behind this is that if the program is running "as a service" it won't get terminated on logout and, therefore doesn't need to be restarted.

IntControl 66 doesn't seem to bother other "services" that I have running (e.g. McAfee Vshield, Eversys Monitor Agent, etc...). Any chance of an updated Intcontrol 66 (or a newer number if compatibility is an issue) that won't terminate the invoking script - provided that that script is running as a service (IntControl 1001)?

Answer:

I suggest launching a second script (or the same one with a special parameter if you are clever) to do the IntControl(66.

Don't really want to modify the IntControl 66 functionality as it is in widespread use.

So....being clever. Lets say your service is called MYSERVE.EXE and you launch it via the RunServices section of the registry. And now it comes time to log the user out via the IntControl 66.


-----snip-----
;Add this code to the TIPTOP of your script
if param0==1
   if param1=="LOGOFF"
      IntControl(66,0,0,0,0)
   endif
endif
; END OF TIPTOP SECTION

;much of the old script here.


;Here is where you do the IntControl66
;ASSUMING COMPILED EXE
MyExe=IntControl(1004,0,0,0,0)
Run(MyExe,"LOGOFF") ; Maybe RunWait ???
;and continue with your service code here.

Accessing a Directory without Permission by Running Winbatch as a Service:

There might just be one way. . .

If you cannot modify services (which is a shame), and you don't have an existing service you can post the command to (such as WinInstall, or your own winbatch service), then you can still do it as follows.

hmm.

Use winbatch COMPILER (don't recommend uncompiled version in this instance due to security considerations.)

This compiled program you email to use user, and ask them to run it. The program will:-

  1. Set autoadmin login up by editing the two keys in the registry, and putting in a hard coded admin password

  2. Setup runonce in the registry to run a batch file at startup.

  3. Close windows and login as different user (intcontrol)
This will log out the user, and automatically login the administrator, and run the batch file.

This batch file will contain a line running another winbatch script. which will add the icons, remove the autoadminlogin line, remove the runonce line, and then force a logout again.

While you're there, you'd do yourself a good favour to add an admin service on the machine.

Bit messy, but its the only way I can think of anyway.


How to Determine if User is Logged in:

I know there has got to be a way, but I can't figure it out and have a time deadline. How can a service running a WB app determine if there is a user logged in? The service must run as the operating system for some things it does, so I am limited there.

My goal is to perform certain tasks either in a forced mode or in an interactive mode. I just need to know which one to kick off.

Thanks in advance for your help!

Answer:

I had to do something similar this past summer, but needed to interact with a network share (actually, a Novell server). What I finally did was to have the background service launch a second service that was defined as a foreground service with desktop interaction activated. This allowed me to perform any network calls as well as post progress messages. Sort of weird, but it worked reliably.

I was able to start and stop the foreground service as needed. In your case, you could pass status information via registry changes within HKLM, which will be available to background and foreground users and services. In fact, I would just pop a couple extra value fields in those created by SRVANY (assuming that is what you used to define your WB app as a service) for your service and have the foreground task fill the fields as necessary.

Good luck.


User32.DLL Initialization Errors

Question:

I have been having a sporatic problem with compiled WinBatch executables failing with the message "Initialization of the dynamic link library C:\WINNT\System32\User32.dll failed. The process is terminating abnormally." The programs will run OK most of the time, but once the failures start, all subsequent WinBatch executables fail with the same message.

My environment is:

  1. WinBatch version 97D
  2. Windows NT Server 4.0
  3. WinBatch executables are being launched from a batch file which is, in turn, launched by the AutoSys scheduling application
  4. Connectivity with the server is via PCAnywhere
Any ideas regarding this would be appreciated

Answer:

There are two items on MS technet that might help. I've had some User32.dll problems with another application, which we have not solved yet.

You should be able to find them on support.microsoft.com under the following Q numbers.


Q142676: Overcoming User32.dll Initialization Failure Errors

The information in this article applies to: 
Microsoft Windows NT Workstation version 4.0 
Microsoft Windows NT Server version 4.0 

SYMPTOMS
When you try to start a service a pop-up dialog 
box appears with the following message: 

 - DLL initialization failure Initialization 
of the dynamic link library c:\windows\system32\user32.dll 
failed. The process is terminating abnormally.


CAUSE
The system has run out of memory to create a 
new desktop heap for the service being started. 

(see article for more details)


Q175875:  Dr. Watson Causing Fault in USER32

The information in this article applies to: 
Microsoft Windows NT Server version 4.0 

SYMPTOMS
When an application is running on a computer running 
Windows NT Server, it may at times raise an exception 
for any of a number of reasons. Ordinarily,an exception 
like this calls the Dr. Watson system utility which 
then captures the exception, writing out a log and a 
memory dump. Under some circumstances, Dr. Watson will 
fail to start and will cause an exception in User32.dll. 

CAUSE
This can occur if the application causing the exception 
is running as a service, but the service account does 
not have the right to log on locally. 

(see article for more details)

Windows Error 2186: The service is not responding to the control function.

Question:

I have created a simple executeable that I have turned into an NT service using srvany.exe. When I go into the Control Panel and start the service via the Service applet, I get the following error: Could not start the "My Service" on \\Computername Error 2186: The service is not responding to the control function.

Any help would be greatly appreciated.

Answer:

When you used the INSTSRV.EXE utility to create the service, did you install SRVANY.EXE as the program for the service or did you install your compiled script's .EXE file? You must install SRVANY.EXE as the service program and then create/edit some registry entries to tell SRVANY.EXE what other .EXE program it is supposed to run when the service control manage tells it to start up.

The error message you are seeing is a classic example of trying to start a .EXE as a service when the .EXE is not capable of detecting and responding to service control manager messages that are being sent to it.


Article ID:   W17209
File Created: 2007:07:03:14:28:48
Last Updated: 2007:07:03:14:28:48