mturk 2004/12/22 02:18:48 Added: daemon/src/native/nt/procrun/apps/srvbatch MSG00001.bin srvbatch.c srvbatch.rc srvbatch.sln srvbatch.vcproj daemon/src/native/nt/procrun/apps/srvbatch/example example.c example.vcproj exservice.bat Log: Add new component to procrun. It behaves like standard unix rc.d conerting batch script to a service management script. It allows to run any program like service, but the focus is on running batch files as services. Revision Changes Path 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/MSG00001.bin <<Binary file>> 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.c Index: srvbatch.c =================================================================== /* Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <process.h> /* Custom return error values */ #define ERR_RET_USAGE 1 #define ERR_RET_VERSION 2 #define ERR_RET_INSTALL 3 #define ERR_RET_REMOVE 4 #define ERR_RET_PARAMS 5 #define ERR_RET_MODE 6 #define MSG_ERROR 0xC0000001L #define MSG_INFO 0x40000002L #define MAX_CMDLINE 8192 /* Extensions On, Old quote style */ static LPCSTR CMD_DEFAULT = "/E:ON /S /C \"SET SERVICE_PPID=%d && SET SERVICE_NAME=%s && CALL %s %s"; static LPCSTR REGSERVICE_ROOT = "SYSTEM\\CurrentControlSet\\Services\\"; static LPCSTR REGSERVICE_LOG = "SYSTEM\\CurrentControlSet\\Services\\EventLog\\Application\\"; static LPCSTR REGPARAMS = "\\Parameters"; static LPCSTR REGDESCRIPTION = "Description"; static LPCSTR REG_SERVFILE = "ServiceFile"; static LPCSTR REG_LOGFILE = "LogFile"; static LPCSTR REG_WPATH = "WorkingPath"; /* Main servic table entry * filled at run-time */ static SERVICE_TABLE_ENTRY _service_table[] = { {NULL, NULL}, {NULL, NULL} }; static SERVICE_STATUS _service_status; static SERVICE_STATUS_HANDLE _service_status_handle = NULL; static char _service_name[MAX_PATH + 1]; static char _service_disp[MAX_PATH + 1]; static char _service_desc[MAX_PATH * 2 + 1]; static char _working_path[MAX_PATH + 1]; static char _service_image[MAX_PATH + 1]; static char _service_bat[MAX_PATH + 1]; static char _cmd_exe[MAX_PATH + 1]; static BOOL _service_log = FALSE; enum _service_mode_e { mode_none, mode_install, mode_uninstall, mode_debug, mode_run }; static enum _service_mode_e _service_mode = mode_none; static BOOL IsWindowsNT() { BOOL rv = FALSE; OSVERSIONINFO osvi; ZeroMemory(&osvi, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); if (!GetVersionEx(&osvi)) return FALSE; switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT: rv = TRUE; break; default: rv = FALSE; break; } return rv; } static BOOL IsServiceRunning(LPCSTR szServiceName) { DWORD rc = 0; SC_HANDLE schService; SC_HANDLE schSCManager; SERVICE_STATUS schSStatus; schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT); if (!schSCManager) return FALSE; schService = OpenService(schSCManager, szServiceName, SERVICE_QUERY_STATUS); if (schService != NULL) { if (QueryServiceStatus(schService, &schSStatus)) rc = schSStatus.dwCurrentState; CloseServiceHandle(schService); CloseServiceHandle(schSCManager); return rc == SERVICE_RUNNING ? TRUE : FALSE; } CloseServiceHandle(schSCManager); return FALSE; } static void AddToMessageLog(BOOL isError, LPSTR szFormat, ...) { char szMsg [MAX_PATH]; LPSTR lpszStrings[2]; LPVOID lpMsgBuf = NULL; HANDLE hEventSource; DWORD dwErr = GetLastError(); WORD wErrType; DWORD dwErrId; WORD nStr; va_list args; if (!_service_log && !isError) { /* Nothing to log */ return; } va_start(args, szFormat); vsprintf(szMsg, szFormat, args); va_end(args); if (isError) { nStr = 2; wErrType = EVENTLOG_ERROR_TYPE; dwErrId = MSG_ERROR; FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, LANG_NEUTRAL), (LPSTR) &lpMsgBuf, 0, NULL); lpszStrings[0] = lpMsgBuf; lpszStrings[1] = szMsg; } else { wErrType = EVENTLOG_INFORMATION_TYPE; dwErrId = MSG_INFO; nStr = 1; lpszStrings[0] = szMsg; } /* Use event logging to log the error. */ hEventSource = RegisterEventSource(NULL, _service_name); if (hEventSource != NULL) { ReportEvent(hEventSource, // handle of event source wErrType, // event type 0, // event category dwErrId, // event ID NULL, // current user's SID nStr, // strings in lpszStrings 0, // no bytes of raw data lpszStrings, // array of error strings NULL); // no raw data DeregisterEventSource(hEventSource); } if (lpMsgBuf) LocalFree(lpMsgBuf); } static void ErrorUsage() { if (_service_mode == mode_run) return; fprintf(stderr, "srvbatch -- program for running batch files as services.\n\n"); fprintf(stderr, "Usage: srvbatch -i service service.bat\n"); fprintf(stderr, " -i[wdcl] service workingpath description comment\n" " service.bat\n"); fprintf(stderr, " -u service\n"); fprintf(stderr, " -t service\n"); fprintf(stderr, "Options:\n"); fprintf(stderr, " -d Service display name\n"); fprintf(stderr, " -c Service description\n"); fprintf(stderr, " -w Service working path\n"); fprintf(stderr, " -l Turn info logging On\n"); ExitProcess(ERR_RET_USAGE); } static void DumpParams() { if (_service_mode == mode_run) return; fprintf(stdout, "Name %s\n", _service_name); fprintf(stdout, "Display %s\n", _service_disp); fprintf(stdout, "Description %s\n", _service_desc); fprintf(stdout, "ImagePath %s\n", _service_image); fprintf(stdout, "Shell %s\n", _cmd_exe); fprintf(stdout, "WorkingPath %s\n", _working_path); fprintf(stdout, "Service Script %s\n", _service_bat); } static void BuildCommandLine(char *buf, const char *action) { ZeroMemory(buf, MAX_CMDLINE); lstrcpy(buf, _cmd_exe); lstrcat(buf, " "); buf += lstrlen(buf); sprintf(buf, CMD_DEFAULT, getpid(), _service_name, _service_bat, action); lstrcat(buf, "\""); fprintf(stdout, "Service Cmd %s\n", buf); } /* We could use the ChangeServiceConfig2 on WIN2K+ * For now use the registry. */ static BOOL SetServiceDescription(LPCSTR szServiceName, LPCSTR szDescription) { HKEY hKey; CHAR szName[MAX_PATH + 1]; DWORD rc; if (lstrlen(szServiceName) > MAX_PATH) return FALSE; lstrcpy(szName, REGSERVICE_ROOT); lstrcat(szName, szServiceName); rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szName, 0, KEY_WRITE, &hKey); if (rc != ERROR_SUCCESS) { return FALSE; } rc = RegSetValueEx(hKey, REGDESCRIPTION, 0, REG_SZ, (CONST BYTE *)szDescription, lstrlen(szDescription) + 1); CloseHandle(hKey); return rc == ERROR_SUCCESS; } /* We could use the ChangeServiceConfig2 on WIN2K+ * For now use the registry. */ static BOOL SetServiceEventLog(LPCSTR szServiceName) { HKEY hKey; CHAR szName[MAX_PATH + 1]; DWORD dwData; if (lstrlen(szServiceName) > MAX_PATH) return FALSE; lstrcpy(szName, REGSERVICE_LOG); lstrcat(szName, szServiceName); RegCreateKey(HKEY_LOCAL_MACHINE, szName, &hKey); if (!GetModuleFileName(NULL, szName, MAX_PATH)) { RegCloseKey(hKey); return FALSE; } RegSetValueEx(hKey, "EventMessageFile", 0, REG_SZ, (LPBYTE)szName, lstrlen(szName) + 1); dwData = EVENTLOG_ERROR_TYPE | EVENTLOG_WARNING_TYPE | EVENTLOG_INFORMATION_TYPE; RegSetValueEx(hKey, "TypesSupported", 0, REG_DWORD, (LPBYTE)&dwData, sizeof(DWORD)); RegFlushKey(hKey); RegCloseKey(hKey); return TRUE; } BOOL SetServiceParameters(LPCSTR szServiceName) { HKEY hKey; CHAR szName[MAX_PATH + 1]; DWORD rc; BOOL rv = TRUE; if (lstrlen(szServiceName) > MAX_PATH) return FALSE; lstrcpy(szName, REGSERVICE_ROOT); lstrcat(szName, szServiceName); lstrcat(szName, REGPARAMS); rc = RegCreateKeyEx(HKEY_LOCAL_MACHINE, szName, 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL); if (rc != ERROR_SUCCESS) { rv = FALSE; goto cleanup; } rc = RegSetValueEx(hKey, REG_SERVFILE, 0, REG_SZ, (CONST BYTE *)_service_bat, lstrlen(_service_bat) + 1); if (rc != ERROR_SUCCESS) { rv = FALSE; goto cleanup; } if (_service_log) { rc = RegSetValueEx(hKey, REG_LOGFILE, 0, REG_DWORD, (CONST BYTE *)&_service_log, sizeof(DWORD)); if (rc != ERROR_SUCCESS) { rv = FALSE; goto cleanup; } } if (lstrlen(_working_path)) { rc = RegSetValueEx(hKey, REG_WPATH, 0, REG_SZ, (CONST BYTE *)_working_path, lstrlen(_working_path) + 1); if (rc != ERROR_SUCCESS) { rv = FALSE; goto cleanup; } } cleanup: CloseHandle(hKey); return rv; } BOOL GetServiceParameters(LPCSTR szServiceName) { HKEY hKey; CHAR szName[MAX_PATH + 1]; DWORD rc; BOOL rv = TRUE; DWORD dwType; DWORD dwSize; if (lstrlen(szServiceName) > MAX_PATH) return FALSE; lstrcpy(szName, REGSERVICE_ROOT); lstrcat(szName, szServiceName); lstrcat(szName, REGPARAMS); rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey); if (rc != ERROR_SUCCESS) { return FALSE; } dwSize = MAX_PATH + 1; rc = RegQueryValueEx(hKey, REG_SERVFILE, NULL, &dwType, (LPBYTE)_service_bat, &dwSize); if (rc != ERROR_SUCCESS || dwType != REG_SZ) { rv = FALSE; goto cleanup; } dwSize = sizeof(DWORD); rc = RegQueryValueEx(hKey, REG_LOGFILE, NULL, &dwType, (LPBYTE)&_service_log, &dwSize); if (rc != ERROR_SUCCESS || dwType != REG_DWORD) { _service_log = FALSE; } dwSize = MAX_PATH + 1; rc = RegQueryValueEx(hKey, REG_WPATH, NULL, &dwType, (LPBYTE)_working_path, &dwSize); if (rc != ERROR_SUCCESS || dwType != REG_SZ) { _working_path[0] = '\0'; } if (GetSystemDirectory(szName, MAX_PATH + 1)) { lstrcat(szName, "\\cmd.exe"); if (strchr(_cmd_exe, ' ')) { _cmd_exe[0] = '"'; lstrcpy(&_cmd_exe[1], szName); lstrcat(_cmd_exe, "\""); } else lstrcpy(_cmd_exe, szName); } cleanup: CloseHandle(hKey); return rv; } BOOL InstallService(LPCSTR szServiceName) { char szImage[MAX_PATH + 1]; char szPath[MAX_PATH + 1]; char *p; BOOL rv = TRUE; SC_HANDLE hManager; SC_HANDLE hService; if (!(hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE))) { return FALSE; } p = &szImage[1]; if (!GetModuleFileName(NULL, p, MAX_PATH)) { rv = FALSE; goto cleanup; } lstrcpy(szPath, p); if ((p = strrchr(szPath, '\\'))) { *p = '\0'; } szImage[0] = '"'; lstrcat(szImage, "\" -r "); lstrcat(szImage, szServiceName); if (!_working_path[0]) lstrcpy(_working_path, szPath); hService = CreateService(hManager, // SCManager database _service_name, // name of service _service_disp, // name to display SERVICE_ALL_ACCESS, // access required SERVICE_WIN32_OWN_PROCESS, // service type SERVICE_AUTO_START, // start type SERVICE_ERROR_NORMAL, // error control type szImage, // service's binary NULL, // no load svc group NULL, // no tag identifier "Tcpip\0Afd\0", // dependencies NULL, // use SYSTEM account NULL); // no password if (!hService) { rv = FALSE; goto cleanup; } cleanup: if (hService) CloseServiceHandle(hService); CloseServiceHandle(hManager); return rv; } BOOL RemoveService(LPCSTR szServiceName) { BOOL rv = TRUE; SC_HANDLE hManager; SC_HANDLE hService; if (!(hManager = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT))) { return FALSE; } hService = OpenService(hManager, _service_name, DELETE); if (!hService) { rv = FALSE; goto cleanup; } rv = DeleteService(hService); cleanup: if (hService) CloseServiceHandle(hService); CloseServiceHandle(hManager); return rv; } /* Report the service status to the SCM */ BOOL ReportServiceStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint) { static DWORD dwCheckPoint = 1; BOOL fResult = TRUE; if (_service_mode == mode_run && _service_status_handle) { if (dwCurrentState == SERVICE_START_PENDING) _service_status.dwControlsAccepted = 0; else _service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP; _service_status.dwCurrentState = dwCurrentState; _service_status.dwWin32ExitCode = dwWin32ExitCode; _service_status.dwWaitHint = dwWaitHint; if ((dwCurrentState == SERVICE_RUNNING) || (dwCurrentState == SERVICE_STOPPED)) _service_status.dwCheckPoint = 0; else _service_status.dwCheckPoint = dwCheckPoint++; fResult = SetServiceStatus(_service_status_handle, &_service_status); if (!fResult) { /* TODO: Deal with error */ } } return fResult; } static BOOL RunChildProcess(LPCSTR szApplication, LPSTR szCmdLine, LPPROCESS_INFORMATION lpprInfo) { STARTUPINFO stInfo; BOOL bResult; ZeroMemory(&stInfo, sizeof(stInfo)); stInfo.cb = sizeof(stInfo); stInfo.dwFlags = STARTF_USESHOWWINDOW; stInfo.wShowWindow = SW_HIDE; bResult = CreateProcess(szApplication, szCmdLine, NULL, NULL, TRUE, CREATE_NEW_PROCESS_GROUP, NULL, _working_path, &stInfo, lpprInfo); return bResult; } /* Executed when the service receives stop event */ static DWORD ServiceStop() { DWORD rv; PROCESS_INFORMATION prInfo; char cmd[MAX_CMDLINE + 1]; if (!IsServiceRunning(_service_name)) { AddToMessageLog(FALSE, "Service %s is already stopped", _service_name); return 0; } BuildCommandLine(cmd, "stop"); AddToMessageLog(FALSE, "Stopping service %s", _service_name); if (RunChildProcess(_cmd_exe, cmd, &prInfo)) { ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); rv = WaitForSingleObject(prInfo.hProcess, INFINITE); AddToMessageLog(FALSE, "Stopped service %s", _service_name); CloseHandle(prInfo.hProcess); CloseHandle(prInfo.hThread); return 0; } else { AddToMessageLog(TRUE, "Stopping service %s", _service_name); return 1; } } /* Executed when the service receives restart event */ static DWORD ServiceRestart() { DWORD rv; PROCESS_INFORMATION prInfo; char cmd[MAX_CMDLINE + 1]; BuildCommandLine(cmd, "restart"); ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); if (RunChildProcess(_cmd_exe, cmd, &prInfo)) { ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0); rv = WaitForSingleObject(prInfo.hProcess, INFINITE); printf("Restart Wait %d %d\n", rv, WAIT_OBJECT_0); CloseHandle(prInfo.hProcess); CloseHandle(prInfo.hThread); rv = 0; } else { AddToMessageLog(TRUE, "Restarting service %s", _service_name); rv = 1; } ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0); return rv; } /* Service controll handler */ void WINAPI ServiceCtrlHandler(DWORD dwCtrlCode) { switch (dwCtrlCode) { case SERVICE_CONTROL_STOP: ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); /* Call the stop handler that will actualy stop the service */ ServiceStop(); return; case SERVICE_CONTROL_INTERROGATE: break; default: break; } ReportServiceStatus(_service_status.dwCurrentState, NO_ERROR, 0); } /* Console control handler * */ BOOL WINAPI ConsoleHandler(DWORD dwCtrlType) { switch (dwCtrlType) { case CTRL_BREAK_EVENT: if (_service_mode == mode_run) { ServiceStop(); return TRUE; } else return FALSE; case CTRL_C_EVENT: case CTRL_CLOSE_EVENT: case CTRL_SHUTDOWN_EVENT: ServiceStop(); return TRUE; break; } return FALSE; } /* Executed when the service receives start event */ static DWORD ServiceStart() { DWORD rv; PROCESS_INFORMATION prInfo; char cmd[MAX_CMDLINE + 1]; BuildCommandLine(cmd, "start"); DumpParams(); AddToMessageLog(FALSE, "Starting service %s", _service_name); if (RunChildProcess(_cmd_exe, cmd, &prInfo)) { AddToMessageLog(FALSE, "Started service %s", _service_name); ReportServiceStatus(SERVICE_RUNNING, NO_ERROR, 0); SetConsoleCtrlHandler((PHANDLER_ROUTINE)ConsoleHandler, TRUE); rv = WaitForSingleObject(prInfo.hProcess, INFINITE); AddToMessageLog(FALSE, "Finished service %s", _service_name); ReportServiceStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); ReportServiceStatus(SERVICE_STOPPED, NO_ERROR, 0); CloseHandle(prInfo.hProcess); CloseHandle(prInfo.hThread); return 0; } else { AddToMessageLog(TRUE, "Starting service %s", _service_name); return 1; } } /* Main service execution loop */ void WINAPI ServiceMain(DWORD argc, LPTSTR *argv) { DWORD rc; _service_status.dwServiceType = SERVICE_WIN32_OWN_PROCESS; _service_status.dwCurrentState = SERVICE_START_PENDING; _service_status.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE; _service_status.dwWin32ExitCode = 0; _service_status.dwCheckPoint = 0; _service_status.dwWaitHint = 0; _service_status.dwServiceSpecificExitCode = 0; if (_service_mode == mode_run) { /* Register Service Control handler */ _service_status_handle = RegisterServiceCtrlHandler(_service_name, ServiceCtrlHandler); if (!_service_status_handle) { AddToMessageLog(TRUE, "RegisterServiceCtrlHandler failed for %s", _service_name); goto cleanup; } } ReportServiceStatus(SERVICE_START_PENDING, NO_ERROR, 3000); if ((rc = ServiceStart()) == 0) { AddToMessageLog(FALSE, "Service %s Main finished", _service_name); } return; cleanup: /* Cleanup */ ReportServiceStatus(SERVICE_STOPPED, ERROR_SERVICE_SPECIFIC_ERROR, 0); return; } void __cdecl main(int argc, char **argv) { UINT rv = 0; char *arg; int i; int args_left = 1; int need_desc = 0; int need_disp = 0; int need_path = 0; if (argc < 3) { ErrorUsage(); } if (!IsWindowsNT()) { fprintf(stderr, "This program will run only on Windows NT or higher\n"); ExitProcess(ERR_RET_VERSION); } for (i = 1; i < argc; i++) { arg = argv[i]; if (*arg != '-') break; while (*++arg != '\0') { switch (*arg) { case 'i': _service_mode = mode_install; args_left++; break; case 'u': _service_mode = mode_uninstall; break; case 't': _service_mode = mode_debug; break; case 'r': _service_mode = mode_run; break; case 'd': need_disp = 1; args_left++; break; case 'c': need_desc = 1; args_left++; break; case 'w': need_path = 1; args_left++; break; case 'l': _service_log = TRUE; break; default: ErrorUsage(); break; } } } if ((argc - i) < args_left) ErrorUsage(); lstrcpy(_service_name, argv[i++]); if (need_path) lstrcpy(_working_path, argv[i++]); if (need_disp) lstrcpy(_service_disp, argv[i++]); if (need_desc) lstrcpy(_service_desc, argv[i++]); SetServiceEventLog(_service_name); if (_service_mode == mode_install) { lstrcpy(_service_bat, argv[i++]); if (!InstallService(_service_name)) { rv = ERR_RET_INSTALL; AddToMessageLog(TRUE, "Failed installing %s", _service_name); goto cleanup; } SetServiceParameters(_service_name); if (need_desc) SetServiceDescription(_service_name, _service_desc); AddToMessageLog(FALSE, "Installed %s", _service_name); } else if (_service_mode == mode_uninstall) { GetServiceParameters(_service_name); AddToMessageLog(FALSE, "Uninstalling %s", _service_name); ServiceStop(); if (!RemoveService(_service_name)) { AddToMessageLog(TRUE, "Failed removing %s", _service_name); rv = ERR_RET_REMOVE; } } else if (_service_mode == mode_run) { GetServiceParameters(_service_name); AddToMessageLog(FALSE, "Initialized %s", _service_name); _service_table[0].lpServiceName = _service_name; _service_table[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain; StartServiceCtrlDispatcher(_service_table); } else if (_service_mode == mode_debug) { GetServiceParameters(_service_name); AddToMessageLog(FALSE, "Debugging %s", _service_name); ServiceMain(argc, argv); } else { AddToMessageLog(TRUE, "Unknown service mode for %s", _service_name); rv = ERR_RET_MODE; } cleanup: AddToMessageLog(FALSE, "SrvBatch finished"); ExitProcess(rv); } 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.rc Index: srvbatch.rc =================================================================== /* Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <windows.h> #define PRODUCT_VER_STRING "1.0.0.0\0" #define PRODUCT_VER_NAME "ServBatch\0" IDI_MAINICON ICON "../../resources/procrunw.ico" LANGUAGE 0x9,0x1 1 11 MSG00001.bin 1 VERSIONINFO FILEVERSION 1,0,0,0 PRODUCTVERSION 1,0,0,0 FILEFLAGSMASK 0x3fL #if defined(_DEBUG) FILEFLAGS 0x03L #else FILEFLAGS 0x02L #endif FILEOS 0x40004L FILETYPE 0x1L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040904b0" BEGIN VALUE "Comments", "\0" VALUE "CompanyName", "Apache Software Foundation\0" VALUE "FileDescription", "Application for running batch files as services\0" VALUE "FileVersion", PRODUCT_VER_STRING VALUE "InternalName", PRODUCT_VER_NAME VALUE "LegalCopyright", "Copyright © 2000-2004 The Apache Software Foundation.\0" VALUE "OriginalFilename", "srvbatch.exe\0" VALUE "ProductVersion", PRODUCT_VER_STRING VALUE "ProductName", PRODUCT_VER_NAME END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x409, 1200 END END 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.sln Index: srvbatch.sln =================================================================== Microsoft Visual Studio Solution File, Format Version 8.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srvbatch", "srvbatch.vcproj", "{6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "example", "example\example.vcproj", "{1C38835C-714F-49F3-85FC-9E6372149DF3}" ProjectSection(ProjectDependencies) = postProject {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB} = {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB} EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Debug.ActiveCfg = Debug|Win32 {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Debug.Build.0 = Debug|Win32 {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Release.ActiveCfg = Release|Win32 {6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}.Release.Build.0 = Release|Win32 {1C38835C-714F-49F3-85FC-9E6372149DF3}.Debug.ActiveCfg = Debug|Win32 {1C38835C-714F-49F3-85FC-9E6372149DF3}.Debug.Build.0 = Debug|Win32 {1C38835C-714F-49F3-85FC-9E6372149DF3}.Release.ActiveCfg = Release|Win32 {1C38835C-714F-49F3-85FC-9E6372149DF3}.Release.Build.0 = Release|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/srvbatch.vcproj Index: srvbatch.vcproj =================================================================== <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" Version="7.10" Name="srvbatch" ProjectGUID="{6AD26261-F2A9-4E6A-9CE6-92B4F2AA37AB}" Keyword="Win32Proj"> <Platforms> <Platform Name="Win32"/> </Platforms> <Configurations> <Configuration Name="Debug|Win32" OutputDirectory="Debug" IntermediateDirectory="Debug" ConfigurationType="1" CharacterSet="2"> <Tool Name="VCCLCompilerTool" Optimization="0" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" OutputFile="$(OutDir)/srvbatch.exe" LinkIncremental="2" GenerateDebugInformation="TRUE" ProgramDatabaseFile="$(OutDir)/srvbatch.pdb" SubSystem="1" TargetMachine="1"/> <Tool Name="VCMIDLTool"/> <Tool Name="VCPostBuildEventTool"/> <Tool Name="VCPreBuildEventTool"/> <Tool Name="VCPreLinkEventTool"/> <Tool Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> <Tool Name="VCXMLDataGeneratorTool"/> <Tool Name="VCWebDeploymentTool"/> <Tool Name="VCManagedWrapperGeneratorTool"/> <Tool Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> <Configuration Name="Release|Win32" OutputDirectory="Release" IntermediateDirectory="Release" ConfigurationType="1" CharacterSet="2"> <Tool Name="VCCLCompilerTool" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="3"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" OutputFile="$(OutDir)/srvbatch.exe" LinkIncremental="1" GenerateDebugInformation="TRUE" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" TargetMachine="1"/> <Tool Name="VCMIDLTool"/> <Tool Name="VCPostBuildEventTool"/> <Tool Name="VCPreBuildEventTool"/> <Tool Name="VCPreLinkEventTool"/> <Tool Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> <Tool Name="VCXMLDataGeneratorTool"/> <Tool Name="VCWebDeploymentTool"/> <Tool Name="VCManagedWrapperGeneratorTool"/> <Tool Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> </Configurations> <References> </References> <Files> <Filter Name="Source Files" Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> <File RelativePath=".\srvbatch.c"> </File> </Filter> <Filter Name="Header Files" Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> </Filter> <Filter Name="Resource Files" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> <File RelativePath=".\srvbatch.rc"> </File> </Filter> </Files> <Globals> </Globals> </VisualStudioProject> 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/example/example.c Index: example.c =================================================================== /* Copyright 2000-2004 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include <windows.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <process.h> HANDLE hGlobalEvent; #define EVENT_NAME "ServBatchExampleEvent" int main(int argc, char **argv) { int mode = 0; int i; for (i = 0; i < argc; i++) fprintf(stdout, "Command line param [%d] = %s\n", i, argv[i]); if (argc > 1 && stricmp(argv[1], "stop") == 0) mode = 1; if (mode) { fprintf(stdout, "Stopping service\n"); hGlobalEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, EVENT_NAME); if (!hGlobalEvent) fprintf(stderr, "Unable to upen the Global Event\n"); else { fprintf(stdout, "Signaling service event\n"); SetEvent(hGlobalEvent); } } else { fprintf(stdout, "Starting service\n"); hGlobalEvent = CreateEvent(NULL, FALSE, FALSE, EVENT_NAME); WaitForSingleObject(hGlobalEvent, INFINITE); fprintf(stdout, "Event Signaled\n"); } fprintf(stdout, "Service mode %d finished\n", mode); return 0; } 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/example/example.vcproj Index: example.vcproj =================================================================== <?xml version="1.0" encoding="Windows-1252"?> <VisualStudioProject ProjectType="Visual C++" Version="7.10" Name="example" ProjectGUID="{1C38835C-714F-49F3-85FC-9E6372149DF3}" Keyword="Win32Proj"> <Platforms> <Platform Name="Win32"/> </Platforms> <Configurations> <Configuration Name="Debug|Win32" OutputDirectory="Debug" IntermediateDirectory="Debug" ConfigurationType="1" CharacterSet="2"> <Tool Name="VCCLCompilerTool" Optimization="0" PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE" MinimalRebuild="TRUE" BasicRuntimeChecks="3" RuntimeLibrary="1" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="4"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" OutputFile="example.exe" LinkIncremental="2" GenerateDebugInformation="TRUE" ProgramDatabaseFile="$(OutDir)/example.pdb" SubSystem="1" TargetMachine="1"/> <Tool Name="VCMIDLTool"/> <Tool Name="VCPostBuildEventTool"/> <Tool Name="VCPreBuildEventTool"/> <Tool Name="VCPreLinkEventTool"/> <Tool Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> <Tool Name="VCXMLDataGeneratorTool"/> <Tool Name="VCWebDeploymentTool"/> <Tool Name="VCManagedWrapperGeneratorTool"/> <Tool Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> <Configuration Name="Release|Win32" OutputDirectory="Release" IntermediateDirectory="Release" ConfigurationType="1" CharacterSet="2"> <Tool Name="VCCLCompilerTool" PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE" RuntimeLibrary="0" UsePrecompiledHeader="0" WarningLevel="3" Detect64BitPortabilityProblems="TRUE" DebugInformationFormat="3"/> <Tool Name="VCCustomBuildTool"/> <Tool Name="VCLinkerTool" OutputFile="$(OutDir)/example.exe" LinkIncremental="1" GenerateDebugInformation="TRUE" SubSystem="1" OptimizeReferences="2" EnableCOMDATFolding="2" TargetMachine="1"/> <Tool Name="VCMIDLTool"/> <Tool Name="VCPostBuildEventTool"/> <Tool Name="VCPreBuildEventTool"/> <Tool Name="VCPreLinkEventTool"/> <Tool Name="VCResourceCompilerTool"/> <Tool Name="VCWebServiceProxyGeneratorTool"/> <Tool Name="VCXMLDataGeneratorTool"/> <Tool Name="VCWebDeploymentTool"/> <Tool Name="VCManagedWrapperGeneratorTool"/> <Tool Name="VCAuxiliaryManagedWrapperGeneratorTool"/> </Configuration> </Configurations> <References> </References> <Files> <Filter Name="Source Files" Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx" UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"> <File RelativePath=".\example.c"> </File> </Filter> <Filter Name="Header Files" Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"> </Filter> <Filter Name="Resource Files" Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx" UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"> </Filter> </Files> <Globals> </Globals> </VisualStudioProject> 1.1 jakarta-commons/daemon/src/native/nt/procrun/apps/srvbatch/example/exservice.bat Index: exservice.bat =================================================================== @echo off REM Copyright 2000-2004 The Apache Software Foundation REM REM Licensed under the Apache License, Version 2.0 (the "License"); REM you may not use this file except in compliance with the License. REM You may obtain a copy of the License at REM REM http://www.apache.org/licenses/LICENSE-2.0 REM REM Unless required by applicable law or agreed to in writing, software REM distributed under the License is distributed on an "AS IS" BASIS, REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. REM See the License for the specific language governing permissions and REM limitations under the License. REM @if not "%ECHO%" == "" echo %ECHO% @if "%OS%" == "Windows_NT" setlocal set SERVICE_EXECUTABLE=example.exe REM Figure out the running mode @if "%1" == "install" goto cmdInstall @if "%1" == "uninstall" goto cmdUninstall @if "%1" == "start" goto cmdStart @if "%1" == "stop" goto cmdStop @if "%1" == "restart" goto cmdRestart echo Usage goto cmdEnd :cmdInstall ..\Debug\srvbatch.exe -iwdcl SrvbatchExample "%CD%" "Srvbatch Example Service" "This is an Example service" exservice.bat goto cmdEnd :cmdUninstall ..\Debug\srvbatch.exe -u SrvbatchExample goto cmdEnd :cmdStart %SERVICE_EXECUTABLE% start goto cmdEnd :cmdStop %SERVICE_EXECUTABLE% stop goto cmdEnd :cmdRestart %SERVICE_EXECUTABLE% stop %SERVICE_EXECUTABLE% start goto cmdEnd :cmdEnd --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]