Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在Windows服务中使用命名管道时出现的问题_C++_Windows_Winapi_Visual C++_Service - Fatal编程技术网

C++ 在Windows服务中使用命名管道时出现的问题

C++ 在Windows服务中使用命名管道时出现的问题,c++,windows,winapi,visual-c++,service,C++,Windows,Winapi,Visual C++,Service,我正在为Windows 10创建服务。我遵循了这个教程 但当我将代码添加到此示例中时,发生了一些事情,我无法从服务列表中停止服务。我只能通过任务管理器来阻止它。但如果我对代码进行注释,服务将正常停止 如蒙指教,我将不胜感激。代码如下所列 #include <Windows.h> #include <tchar.h> #include <string> #include <fstream> SERVICE_STATUS g_Servi

我正在为Windows 10创建服务。我遵循了这个教程

但当我将代码添加到此示例中时,发生了一些事情,我无法从服务列表中停止服务。我只能通过任务管理器来阻止它。但如果我对代码进行注释,服务将正常停止

如蒙指教,我将不胜感激。代码如下所列

#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,
        16 * 1024,
        0,
        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, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &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, TRUE, 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, 0, ServiceWorkerThread, NULL, 0, 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;
}
#包括
#包括
#包括
#包括
服务状态g服务状态={0};
服务状态句柄g状态句柄=NULL;
HANDLE g\u ServiceStopEvent=无效的\u句柄\u值;
std::wofstream输出(L“C:\\Users\\0x0\\source\\Service\\output.txt”);
VOID WINAPI ServiceMain(DWORD argc,LPTSTR*argv);
作废WINAPI服务CtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);
#定义服务名称(“测试服务”)
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
安全(a);
sa.nLength=sizeof(安全属性);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
auto dwFlags=文件\属性\正常;
STARTUPINFOW-si;
GetStartupInfoW&si;
处理信息;
零内存(&si,sizeof(si));
si.cb=sizeof(si);
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=SW_HIDE;
零内存(&pi,sizeof(pi));
HANDLE service\u pipe=CreateNamedPipe(文本(“\\\\.\\pipe\\ServicePipe”),
管道、通道、双工、,
管道|类型|字节|管道|读取模式|字节|管道|等待,
128,
16 * 1024,
16 * 1024,
0,
nullptr);
if(服务\u管道==无效的\u句柄\u值)
{
返回1;
}
TCHAR收件箱_缓冲区[1024];
德沃德读,写;
而(1)
{
if(WaitForSingleObject(g_ServiceStopEvent,0)!=WAIT_OBJECT_0)
{
//如果我对这个“If block”进行注释,服务将正确停止。但我在这部分代码中没有看到任何错误。
if(连接命名管道(服务管道,空PTR))
{
if(ReadFile(服务管道、收件箱缓冲区、1024*sizeof(TCHAR)、读取和空ptr))
{
std::wstring args=收件箱\缓冲区;
std::wstring command=L“\”C:\\Program Files(x86)\\Unility\\utility.exe\”“+args;
if(!CreateProcessW(NULL,(LPWSTR)command.c_str(),NULL,NULL,TRUE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{

输出脏的方式,但它正在工作。我创建了处理与管道相关的所有作业的函数。我在新线程中运行了此函数。当服务接收到停止信号时,我向管道发送停止消息,它停止循环

#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, 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,
        16 * 1024,
        0,
        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, inbox_buffer, 1024 * sizeof(TCHAR), &read, 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, (LPWSTR)command.c_str(), NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &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, L"executed", sizeof(L"executed"), &write, nullptr);
                } while (!success);
            }
            DisconnectNamedPipe(service_pipe);
            std::fill(inbox_buffer, inbox_buffer + 1024, '\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,
        0,
        nullptr,
        OPEN_EXISTING,
        0,
        nullptr);
    bool succeess = false;
    DWORD read;
    do
    {
        succeess = WriteFile(gsprint_pipe, L"stop_signal", sizeof(L"stop_signal"), &read, 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, 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)
    {
        //SetServiceStatus failed. You should log this!
    }

    g_ServiceStopEvent = CreateEvent(NULL, TRUE, 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)
        {
            //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, 0, ServiceWorkerThread, NULL, 0, NULL);

    WaitForSingleObject(hThread, 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, TCHAR *argv[])
{
    SERVICE_TABLE_ENTRY ServiceTable[] =
    {
        {(LPWSTR)"TestService", (LPSERVICE_MAIN_FUNCTION)ServiceMain},
        {NULL, NULL}
    };

    if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
    {
        return GetLastError();
    }

    return 0;
}
#包括
#包括
#包括
#包括
#包括
服务状态g服务状态={0};
服务状态句柄g状态句柄=NULL;
HANDLE g\u ServiceStopEvent=无效的\u句柄\u值;
VOID WINAPI ServiceMain(DWORD argc,LPTSTR*argv);
作废WINAPI服务CtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);
#定义服务名称(“测试服务”)
无效管道\服务器\函数(){
安全(a);
sa.nLength=sizeof(安全属性);
sa.lpSecurityDescriptor=NULL;
sa.bInheritHandle=TRUE;
auto dwFlags=文件\属性\正常;
STARTUPINFOW-si;
GetStartupInfoW&si;
处理信息;
零内存(&si,sizeof(si));
si.cb=sizeof(si);
si.dwFlags=STARTF_USESHOWWINDOW;
si.wShowWindow=SW_HIDE;
零内存(&pi,sizeof(pi));
HANDLE service\u pipe=CreateNamedPipe(文本(“\\\\.\\pipe\\ServicePipe”),
管道、通道、双工、,
管道|类型|字节|管道|读取模式|字节|管道|等待,
128,
16 * 1024,
16 * 1024,
0,
nullptr);
if(服务\u管道==无效的\u句柄\u值)
{
返回;
}
TCHAR收件箱_缓冲区[1024];
标准::填充(收件箱缓冲区,收件箱缓冲区+1024,“\0”);
德沃德读,写;
while(true)
{
if(连接命名管道(服务管道,空PTR))
{
if(ReadFile(服务管道、收件箱缓冲区、1024*sizeof(TCHAR)、读取和空ptr))
{
std::wstring args=收件箱\缓冲区;
if(args.find(“停止信号”)!=std::wstring::npos)
{
断开命名管道(服务管道);
打破
}
std::wstring command=L“\”C:\\Program Files(x86)\\Unility\\utility.exe\”“+args;
if(!CreateProcessW(NULL,(LPWSTR)command.c_str(),NULL,NULL,TRUE,CREATE_NO_WINDOW,NULL,NULL,&si,&pi))
{
//CreateProcessW失败。您应该记录此错误!
}
WaitForSingleObject(pi.hProcess,无限);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
布尔成功=假;
做
{
success=WriteFile(服务管道,L“已执行”,sizeof(L“已执行”),&write,nullptr);
}而(!成功);
}
断开命名管道(服务管道);
标准::填充(收件箱缓冲区,收件箱缓冲区+1024,“\0”);
}
}
闭合手柄(检修管);
}
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
if(WaitForSingleObject(g_ServiceStopEvent,0)!=WAIT_OBJECT_0){
睡眠(1000);
}
服务::handle gsprint\u pipe=CreateFile(文本(“\\\\.\\pipe\\ServicePipe”),
一般的读,一般的写,
0,
nullptr,
开放式,
0,
nullptr);
bool succeess=假;
德沃德·里德;
做
{
succeess=WriteFile(gsprint\u pipe,L“stop\u signal”,sizeof(L“stop\u signal”),&read,nullptr);
}而(!成功);
返回错误\成功;
}
无效WINAPI服务CtrlHandler(DWORD CtrlCode)
{
开关(CtrlCode)
{
案例服务控制站:
if(g_ServiceStatus.dwCurrentState!=服务正在运行)
打破
g_ServiceStatus.dwCont