VC++ 创建一个服务程序。

玉生香 2018-12-31 11:33:02
功能描述:
1.一个主线程,三个工作线程。
主线程负责管理(三个工作线程),
2.我对程序实现了 program.exe stop|start|reload 操作

但每次运行都会弹出黑色的框框,容易被×掉而终止程序。这样太危险。

我想把它做程序一个windows程序,能否做,如何实现。请大神给一段实现代码! windows编程不在行
...全文
382 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
玉生香 2019-01-09
  • 打赏
  • 举报
回复
引用 3 楼 wuxia2118 的回复:
用Win32API做,也可以用MFC做,对Windows编程没经验最好从Win32 API的对话框程序学起。


明白这个道理。是直接项目使用。
wuxia2118 2019-01-03
  • 打赏
  • 举报
回复
用Win32API做,也可以用MFC做,对Windows编程没经验最好从Win32 API的对话框程序学起。
Eleven 2019-01-01
  • 打赏
  • 举报
回复

void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv);
DWORD WINAPI ServiceCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext); // Service Control
BOOL Create(LPCTSTR lpszCmdLine); // Create Service
BOOL Delete(void); // Delete Service
void Dispatch(void); // Dispatch Service
void Run(LPCTSTR lpszExecute, LPCTSTR lpszCmdLine);

// Global Variables
SERVICE_STATUS_HANDLE ServiceStatusHandle = NULL;
SERVICE_STATUS ServiceStatus = { 0 };
HANDLE StopEventHandle = NULL;
// The one and only application object

CWinApp theApp;

using namespace std;

int _tmain(int argc, TCHAR* argv[])
{
do
{
if (!AfxWinInit(GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
break;
}

if (2 == argc)
{
LPCTSTR lpszCmdLine = NULL;
if (NULL != (lpszCmdLine = _tcsstr(argv[1], DEFAULT_BATTERYMONITORSERVICES_COMMANDLINE_CREATE))) { Create(lpszCmdLine + _tcslen(DEFAULT_BATTERYMONITORSERVICES_COMMANDLINE_CREATE)); }
else if (NULL != (lpszCmdLine = _tcsstr(argv[1], DEFAULT_BATTERYMONITORSERVICES_COMMANDLINE_DELETE))) { Delete(); }
else { Usage(); }

break;
}

CCommon::INITIALIZE(); // Initialize

// Dispatch Service
Dispatch();

CCommon::PRINT(CCommon::INF, TEXT("-------------------------------------------------------------"));
CCommon::UNINITIALIZE(); // Uninitialize

// Completed
} while (FALSE);
return 0;
}


BOOL Create(LPCTSTR lpszCmdLine)
{
BOOL bRet = FALSE;

SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
do
{
// Open Service Control Manager
if (NULL == (hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) { break; }

// Get Service Execute Path
TCHAR szPath[MAX_PATH] = { 0 };
TCHAR szExecute[MAX_PATH] = { 0 };
GetModuleFileName(NULL, szPath, _countof(szPath));
StringCchPrintf(szExecute, _countof(szExecute), TEXT("\"%s\""), szPath);

_ASSERT(NULL != hSCManager);
// Create Service
hService = CreateService(hSCManager,
DEFAULT_BATTERYMONITORSERVICES_SERVICENAME,
DEFAULT_BATTERYMONITORSERVICES_DISPLAYNAME,
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_IGNORE,
szExecute,
TEXT("ShellSvcGroup"),
NULL,
NULL,
NULL,
NULL);
if (NULL == hService)
{
DWORD dwError = GetLastError();
if (ERROR_SERVICE_EXISTS != dwError) { break; }
else { if (NULL == (hService = OpenService(hSCManager, DEFAULT_BATTERYMONITORSERVICES_SERVICENAME, SERVICE_START))) { break; } }
}
else
{
// Set Service Description
SERVICE_DESCRIPTION sd;
sd.lpDescription = DEFAULT_BATTERYMONITORSERVICES_DESCRIPTION;

if (!ChangeServiceConfig2(hService, SERVICE_CONFIG_DESCRIPTION, &sd)) { _tprintf(TEXT("Change service configuration failed!\r\n")); }
}

_ASSERT(NULL != hService);
// Start Service
LPCTSTR lpszArgv[] = { DEFAULT_BATTERYMONITORSERVICE_COMMANDLINE_AUTORUN, lpszCmdLine };
if (!StartService(hService, _countof(lpszArgv), lpszArgv))
{
if (ERROR_SERVICE_ALREADY_RUNNING != GetLastError()) { _tprintf(TEXT("Start service failed!\r\n")); }
else { _tprintf(TEXT("Service is already running!\r\n")); bRet = TRUE; break; }
}

// Completed
bRet = TRUE;
} while (FALSE);
if (!bRet) { _tprintf(TEXT("Create service failed!\r\n")); }
else { _tprintf(TEXT("Create service scuccessful.\r\n")); }

if (NULL != hService) { CloseServiceHandle(hService); hService = NULL; }
if (NULL != hSCManager) { CloseServiceHandle(hSCManager); hSCManager = NULL; }
return bRet;
}


BOOL Delete(void)
{
BOOL bRet = FALSE;

SC_HANDLE hSCManager = NULL;
SC_HANDLE hService = NULL;
do
{
// Notify Battery Monitor Application Exit
HANDLE hEvent = CreateEvent(NULL, TRUE, FALSE, DEFAULT_BATTERYMONITORSERVICES_QUIT_APPLICATION);
if (NULL != hEvent) { SetEvent(hEvent); CloseHandle(hEvent); hEvent = NULL; }

// Open Service Control Manager
if (NULL == (hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS))) { break; }

_ASSERT(NULL != hSCManager);
// Open Service
if (NULL == (hService = OpenService(hSCManager, DEFAULT_BATTERYMONITORSERVICES_SERVICENAME, SERVICE_ALL_ACCESS)))
{
_tprintf(TEXT("Service does not exist or has been removed!\r\n"));
break;
}

SERVICE_STATUS status = { 0 };
if (QueryServiceStatus(hService, &status))
{
if (SERVICE_STOPPED != status.dwCurrentState)
{
if (ControlService(hService, SERVICE_CONTROL_STOP, &status))
{
while (QueryServiceStatus(hService, &status) && (SERVICE_STOP_PENDING == status.dwCurrentState)) { Sleep(200); }
}
}
}

// Delete Service
if (!DeleteService(hService)) { break; }

// Completed
bRet = TRUE;
} while (FALSE);
if (!bRet) { _tprintf(TEXT("Delete services failed!\r\n")); }
else { _tprintf(TEXT("Delete services Scuccessful.\r\n")); }

if (NULL != hService) { CloseServiceHandle(hService); hService = NULL; }
if (NULL != hSCManager) { CloseServiceHandle(hSCManager); hSCManager = NULL; }
return bRet;
}


void Dispatch(void)
{
// Dispatch Service
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ DEFAULT_BATTERYMONITORSERVICES_SERVICENAME, ServiceMain },
{ NULL, NULL }
};
if (!StartServiceCtrlDispatcher(DispatchTable))
{
_tprintf(TEXT("Start service control dispatcher failed!\r\n"));
}
}


void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
CCommon::PRINT(CCommon::INF, TEXT("ServiceMain(+)."));
do
{
// Parse Command Line
BOOL bAutoRun = FALSE;
for (DWORD i = 0; i != dwArgc; ++i)
{
CCommon::PRINT(CCommon::INF, TEXT("ServiceMain() Argv[%u] = %s."), i, lpszArgv[i]);
LPCTSTR lpszTask = NULL;
if (0 == _tcsicmp(DEFAULT_BATTERYMONITORSERVICE_COMMANDLINE_AUTORUN, lpszArgv[i])) { bAutoRun = TRUE; }
else if(NULL != (lpszTask = _tcsstr(lpszArgv[i], DEFAULT_BATTERYMONITORSERVICE_COMMANDLINE_TOKEN)))
{
CCommon::PRINT(CCommon::INF, TEXT("ServiceMain() Parse Task Parameters."));
// Parse Task Parameters
TASK task = (TASK)_tcstoul(lpszTask + _tcslen(DEFAULT_BATTERYMONITORSERVICE_COMMANDLINE_TOKEN), NULL, 16);
CCommon::UpdateXML(DEFAULT_BATTERYMONITOR_CONFIG_SCHEDULE, (TASK_SCHEDULE & task) ? 1 : 0);
CCommon::UpdateXML(DEFAULT_BATTERYMONITOR_CONFIG_INTERVAL, (TASK_INTERVAL & task) ? 1 : 0);
CCommon::UpdateXML(DEFAULT_BATTERYMONITOR_CONFIG_POLLING, (TASK_POLLING & task) ? 1 : 0);
}
}

// Initialize SERIVCE_STATUS
ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS | SERVICE_INTERACTIVE_PROCESS;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SESSIONCHANGE;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwServiceSpecificExitCode = 0;

// Register the handler function for the service
CCommon::PRINT(CCommon::INF, TEXT("Registry Service Control Handler..."));
ServiceStatusHandle = RegisterServiceCtrlHandlerEx(DEFAULT_BATTERYMONITORSERVICES_SERVICENAME, ServiceCtrlHandler, NULL);
_ASSERT(NULL != ServiceStatusHandle);
if (NULL == ServiceStatusHandle) { CCommon::PRINT(CCommon::ERR, GetLastError(), TEXT("RegisterServiceCtrlHandler")); break; }

// Report service status to the SCM
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 3000;
if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)) { CCommon::PRINT(CCommon::ERR, GetLastError(), TEXT("SetServiceStatus")); break; }

CCommon::PRINT(CCommon::INF, TEXT("Initialize and Create Stop Event."));
// Report initial status to the SCM
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)) { CCommon::PRINT(CCommon::ERR, GetLastError(), TEXT("SetServiceStatus")); break; }

// Create Event
_ASSERT(NULL == StopEventHandle);
StopEventHandle = CreateEvent(NULL, TRUE, FALSE, NULL);
_ASSERT(NULL != StopEventHandle);
if (NULL == StopEventHandle) { CCommon::PRINT(CCommon::ERR, GetLastError(), TEXT("CreateEvent")); break; }


// Run Application
if (bAutoRun) { Run(DEFAULT_BATTERYMONITORSERVICES_APPLICATION, NULL); }

// If Run completed and notify event to close
CCommon::PRINT(CCommon::INF, TEXT("Wait Stop Event Signal and Stop Service..."));
WaitForSingleObject(StopEventHandle, INFINITE);
if (NULL != StopEventHandle) { CloseHandle(StopEventHandle); StopEventHandle = NULL; }

// Report service status to the SCM
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
if (!SetServiceStatus(ServiceStatusHandle, &ServiceStatus)) { CCommon::PRINT(CCommon::ERR, GetLastError(), TEXT("SetServiceStatus")); }

CCommon::PRINT(CCommon::INF, TEXT("Service Stop Completed."));

// Completed
} while (FALSE);

CCommon::PRINT(CCommon::INF, TEXT("ServiceMain(-)."));
}


DWORD WINAPI ServiceCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEventData, LPVOID lpContext)
{
UNREFERENCED_PARAMETER(lpEventData);
UNREFERENCED_PARAMETER(lpContext);

CCommon::PRINT(CCommon::INF, TEXT("ServiceCtrlHandler(+)."));

// Handle the requested control code.
switch (dwControl)
{
case SERVICE_CONTROL_SESSIONCHANGE:
{
switch (dwEventType)
{
case WTS_CONSOLE_CONNECT:
CCommon::PRINT(CCommon::INF, TEXT("Session Notify : WTS_CONSOLE_CONNECT."));
break;

case WTS_CONSOLE_DISCONNECT:
CCommon::PRINT(CCommon::INF, TEXT("Session Notify : WTS_CONSOLE_DISCONNECT."));
break;

case WTS_REMOTE_CONNECT:
CCommon::PRINT(CCommon::INF, TEXT("Session Notify : WTS_REMOTE_CONNECT."));
break;

case WTS_REMOTE_DISCONNECT:
CCommon::PRINT(CCommon::INF, TEXT("Session Notify : WTS_REMOTE_DISCONNECT."));
break;

case WTS_SESSION_LOGON:
CCommon::PRINT(CCommon::INF, TEXT("Session Notify : WTS_SESSION_LOGON."));
Run(DEFAULT_BATTERYMONITORSERVICES_APPLICATION, NULL); /
zgl7903 2019-01-01
  • 打赏
  • 举报
回复

16,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧