但是,当我将代码添加到此示例时,发生了一些事情,我无法停止服务列表中的服务.我只能从任务经理那里阻止它.但如果我评论我的代码,服务正常停止.
我会很感激任何建议.代码如下.
#include <windows.h>#include <tchar.h>#include <string>#include <fstream>SERVICE_STATUS g_ServiceStatus = { 0 };SERVICE_STATUS_HANDLE g_StatusHandle = NulL;HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE;std::wofstream output(L"C:\\Users\\0x0\\source\\Service\\output.txt");VOID WINAPI ServiceMain(DWORD argc,LPTSTR *argv);VOID WINAPI ServiceCtrlHandler(DWORD);DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);#define SERVICE_name _T("TestService")DWORD WINAPI ServiceWorkerThread(LPVOID lpParam){ Security_ATTRIBUTES sa; sa.nLength = sizeof(Security_ATTRIBUTES); sa.lpSecurityDescriptor = NulL; sa.binheritHandle = TRUE; auto DWFlags = file_ATTRIBUTE_norMAL; STARTUPINFOW si; GetStartupInfoW(&si); PROCESS_informatION pi; ZeroMemory(&si,sizeof(si)); si.cb = sizeof(si); si.DWFlags = STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; ZeroMemory(&pi,sizeof(pi)); HANDLE service_pipe = CreatenamedPipe(TEXT("\\\\.\\pipe\\ServicePipe"),PIPE_ACCESS_DUPLEX,PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,128,16 * 1024,nullptr); if (service_pipe == INVALID_HANDLE_VALUE) { return 1; } TCHAR inBox_buffer[1024]; DWORD read,write; while (1) { if (WaitForSingleObject(g_ServiceStopEvent,0) != WAIT_OBJECT_0) { //If I comment this 'if block',service stopPing properly. But I don't see any errors in this part of code. if (ConnectnamedPipe(service_pipe,nullptr)) { if (Readfile(service_pipe,inBox_buffer,1024 * sizeof(TCHAR),&read,nullptr)) { std::wstring args = inBox_buffer; std::wstring command = L"\"C:\\Program files (x86)\\Unility\\utility.exe\" " + args; if (!CreateProcessW(NulL,(LPWSTR)command.c_str(),NulL,TRUE,CREATE_NO_WINDOW,&si,&pi)) { output << "CreateProcessW Error = " << GetLastError() << std::endl; } WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); bool success = false; do { success = Writefile(service_pipe,L"executed",sizeof(L"executed"),&write,nullptr); } while (!success); } disconnectnamedPipe(service_pipe); } } else { output << "WaitForSingleObject(g_ServiceStopEvent,0)" << std::endl; break; } } output << "CloseHandle(service_pipe)_1" << std::endl; CloseHandle(service_pipe); output << "CloseHandle(service_pipe)_2" << std::endl; return ERROR_SUCCESS;}VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode){ switch (CtrlCode) { case SERVICE_CONTRol_Stop: if (g_ServiceStatus.DWCurrentState != SERVICE_RUNNING) break; g_ServiceStatus.DWControlsAccepted = 0; g_ServiceStatus.DWCurrentState = SERVICE_Stop_PENDING; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWCheckPoint = 4; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { output << "TestService: ServiceCtrlHandler: SetServiceStatus returned error" << std::endl; } SetEvent(g_ServiceStopEvent); output << "SetEvent(g_ServiceStopEvent)_1" << std::endl; break; default: break; } output << "SetEvent(g_ServiceStopEvent)_2" << std::endl;}VOID WINAPI ServiceMain(DWORD argc,LPTSTR *argv){ DWORD Status = E_FAIL; g_StatusHandle = RegisterServiceCtrlHandler(SERVICE_name,ServiceCtrlHandler); if (g_StatusHandle == NulL) { return; } ZeroMemory(&g_ServiceStatus,sizeof(g_ServiceStatus)); g_ServiceStatus.DWServiceType = SERVICE_WIN32_OWN_PROCESS; g_ServiceStatus.DWControlsAccepted = 0; g_ServiceStatus.DWCurrentState = SERVICE_START_PENDING; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWServiceSpecificExitCode = 0; g_ServiceStatus.DWCheckPoint = 0; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { output << "TestService: ServiceMain: SetServiceStatus returned error" << std::endl; } g_ServiceStopEvent = CreateEvent(NulL,FALSE,NulL); if (g_ServiceStopEvent == NulL) { g_ServiceStatus.DWControlsAccepted = 0; g_ServiceStatus.DWCurrentState = SERVICE_StopPED; g_ServiceStatus.DWWin32ExitCode = GetLastError(); g_ServiceStatus.DWCheckPoint = 1; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { output << "TestService: ServiceMain: SetServiceStatus returned error" << std::endl; } return; } g_ServiceStatus.DWControlsAccepted = SERVICE_ACCEPT_Stop; g_ServiceStatus.DWCurrentState = SERVICE_RUNNING; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWCheckPoint = 0; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { output << "TestService: ServiceMain: SetServiceStatus returned error" << std::endl; } HANDLE hThread = CreateThread(NulL,ServiceWorkerThread,NulL); WaitForSingleObject(hThread,INFINITE); output << "CloseHandle(g_ServiceStopEvent)_1" << std::endl; CloseHandle(g_ServiceStopEvent); output << "CloseHandle(g_ServiceStopEvent)_2" << std::endl; g_ServiceStatus.DWControlsAccepted = 0; g_ServiceStatus.DWCurrentState = SERVICE_StopPED; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWCheckPoint = 3; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { output << "TestService: ServiceMain: SetServiceStatus returned error" << std::endl; } return;}int _tmain(int argc,TCHAR *argv[]){ SERVICE_table_ENTRY Servicetable[] = { {(LPWSTR)"TestService",(LPSERVICE_MAIN_FUNCTION)ServiceMain},{NulL,NulL} }; if (StartServiceCtrldispatcher(Servicetable) == FALSE) { return GetLastError(); } return 0;}@H_502_16@解决方法 肮脏的方式,但它的工作.我创建了一个处理与管道相关的所有工作的函数.我在新线程中运行了这个函数.当服务收到停止信号时,我向管道发送停止消息并停止循环.#include <windows.h>#include <tchar.h>#include <string>#include <thread>#include <fstream>SERVICE_STATUS g_ServiceStatus = { 0 };SERVICE_STATUS_HANDLE g_StatusHandle = NulL;HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE;VOID WINAPI ServiceMain(DWORD argc,LPTSTR *argv);VOID WINAPI ServiceCtrlHandler(DWORD);DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);#define SERVICE_name _T("TestService")voID pipe_server_function() { Security_ATTRIBUTES sa; sa.nLength = sizeof(Security_ATTRIBUTES); sa.lpSecurityDescriptor = NulL; sa.binheritHandle = TRUE; auto DWFlags = file_ATTRIBUTE_norMAL; STARTUPINFOW si; GetStartupInfoW(&si); PROCESS_informatION pi; ZeroMemory(&si,nullptr); if (service_pipe == INVALID_HANDLE_VALUE) { return; } TCHAR inBox_buffer[1024]; std::fill(inBox_buffer,inBox_buffer + 1024,'\0'); DWORD read,write; while (true) { if (ConnectnamedPipe(service_pipe,nullptr)) { if (Readfile(service_pipe,nullptr)) { std::wstring args = inBox_buffer; if (args.find("stop_signal") != std::wstring::npos) { disconnectnamedPipe(service_pipe); break; } std::wstring command = L"\"C:\\Program files (x86)\\Unility\\utility.exe\" " + args; if (!CreateProcessW(NulL,&pi)) { //CreateProcessW Failed. You should log this! } WaitForSingleObject(pi.hProcess,INFINITE); CloseHandle(pi.hProcess); CloseHandle(pi.hThread); bool success = false; do { success = Writefile(service_pipe,nullptr); } while (!success); } disconnectnamedPipe(service_pipe); std::fill(inBox_buffer,'\0'); } } CloseHandle(service_pipe);}DWORD WINAPI ServiceWorkerThread(LPVOID lpParam){ if (WaitForSingleObject(g_ServiceStopEvent,0) != WAIT_OBJECT_0) { Sleep(1000); } service::handle gsprint_pipe = Createfile(TEXT("\\\\.\\pipe\\ServicePipe"),GENERIC_READ | GENERIC_WRITE,nullptr,OPEN_EXISTING,nullptr); bool succeess = false; DWORD read; do { succeess = Writefile(gsprint_pipe,L"stop_signal",sizeof(L"stop_signal"),nullptr); } while (!succeess); return ERROR_SUCCESS;}VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode){ switch (CtrlCode) { case SERVICE_CONTRol_Stop: if (g_ServiceStatus.DWCurrentState != SERVICE_RUNNING) break; g_ServiceStatus.DWControlsAccepted = 0; g_ServiceStatus.DWCurrentState = SERVICE_Stop_PENDING; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWCheckPoint = 4; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { //SetServiceStatus Failed. You should log this! } SetEvent(g_ServiceStopEvent); break; default: break; }}VOID WINAPI ServiceMain(DWORD argc,&g_ServiceStatus) == FALSE) { //SetServiceStatus Failed. You should log this! } g_ServiceStopEvent = CreateEvent(NulL,&g_ServiceStatus) == FALSE) { //SetServiceStatus Failed. You should log this! } return; } g_ServiceStatus.DWControlsAccepted = SERVICE_ACCEPT_Stop; g_ServiceStatus.DWCurrentState = SERVICE_RUNNING; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWCheckPoint = 0; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { //SetServiceStatus Failed. You should log this! } std::thread pipe_server(pipe_server_function); HANDLE hThread = CreateThread(NulL,INFINITE); pipe_server.join(); CloseHandle(g_ServiceStopEvent); g_ServiceStatus.DWControlsAccepted = 0; g_ServiceStatus.DWCurrentState = SERVICE_StopPED; g_ServiceStatus.DWWin32ExitCode = 0; g_ServiceStatus.DWCheckPoint = 3; if (SetServiceStatus(g_StatusHandle,&g_ServiceStatus) == FALSE) { //SetServiceStatus Failed. You should log this! } return;}int _tmain(int argc,NulL} }; if (StartServiceCtrldispatcher(Servicetable) == FALSE) { return GetLastError(); } return 0;}@H_502_16@ 总结以上是内存溢出为你收集整理的c – 在Windows服务中使用命名管道时出现故障全部内容,希望文章能够帮你解决c – 在Windows服务中使用命名管道时出现故障所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)