c – 在Windows服务中使用命名管道时出现故障

c – 在Windows服务中使用命名管道时出现故障,第1张

概述我正在为 Windows 10创建服务.我已经按照本教程. https://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus 但是,当我将代码添加到此示例时,发生了一些事情,我无法停止服务列表中的服务.我只能从任务经理那里阻止它.但如果我评论我的代码,服务正常停止. 我会很感激任何建议.代码如下. #in 我正在为 Windows 10创建服务.我已经按照本教程. https://www.codeproject.com/Articles/499465/Simple-Windows-Service-in-Cplusplus

但是,当我将代码添加到此示例时,发生了一些事情,我无法停止服务列表中的服务.我只能从任务经理那里阻止它.但如果我评论我的代码,服务正常停止.

我会很感激任何建议.代码如下.

#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服务中使用命名管道时出现故障所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1229230.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存