xxxxxxxxxx
#include <Windows.h>
SERVICE_STATUS g_ServiceStatus = {0};
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);
#define SERVICE_NAME _T("CalculatorService")
int _tmain(int argc, TCHAR *argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, _T("calc.exe"), NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
// No need to handle any control code in this example
}
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
// No worker thread in this example
return ERROR_SUCCESS;
}
xxxxxxxxxx
#include <Windows.h>
#include <tchar.h>
#include <iostream>
SERVICE_STATUS g_ServiceStatus = {0};
SERVICE_STATUS_HANDLE g_StatusHandle = NULL;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);
#define SERVICE_NAME _T("CalculatorService")
int _tmain(int argc, TCHAR *argv[])
{
if (argc < 2)
{
std::cerr << "Usage: " << argv[0] << " <calc_path>" << std::endl;
return 1;
}
// You can pass the path to calc.exe as a command-line argument
// e.g., CalculatorService.exe "C:\Program Files\calc.exe"
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
StartServiceCtrlDispatcher(ServiceTable);
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR *argv)
{
g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(g_StatusHandle, &g_ServiceStatus);
// Use the path provided as a command-line argument
TCHAR szPath[MAX_PATH];
_tcscpy_s(szPath, argv[1]); // Assuming the first argument is the path to calc.exe
// Start calc.exe
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess(NULL, szPath, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi);
WaitForSingleObject(pi.hProcess, INFINITE);
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
// No need to handle any control code in this example
}
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
// No worker thread in this example
return ERROR_SUCCESS;
}