Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.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 如果我没有';你没有窗户把手吗?_C_Winapi_Inter Process Communicat - Fatal编程技术网

C 如果我没有';你没有窗户把手吗?

C 如果我没有';你没有窗户把手吗?,c,winapi,inter-process-communicat,C,Winapi,Inter Process Communicat,我有两个程序,我需要一种方法,让其中一个能够以某种方式向另一个发送消息。我已经研究了Win32 API中的SendMessage函数,虽然只要有一个窗口句柄,它就可以正常工作,但我的程序需要能够在服务下注销时运行,这意味着它无法创建窗口句柄 是否有任何方法可以在不创建窗口句柄的情况下从另一个进程接收消息?我一直在寻找Win32是否有其他方式可以连接到消息传递中,这样我就不必依赖于窗口句柄,但必须有某种方式在进程之间进行基本级别的通信,不是吗 我曾考虑过使用管道来实现这一点,但遇到了巨大的权限问题

我有两个程序,我需要一种方法,让其中一个能够以某种方式向另一个发送消息。我已经研究了Win32 API中的SendMessage函数,虽然只要有一个窗口句柄,它就可以正常工作,但我的程序需要能够在服务下注销时运行,这意味着它无法创建窗口句柄

是否有任何方法可以在不创建窗口句柄的情况下从另一个进程接收消息?我一直在寻找Win32是否有其他方式可以连接到消息传递中,这样我就不必依赖于窗口句柄,但必须有某种方式在进程之间进行基本级别的通信,不是吗


我曾考虑过使用管道来实现这一点,但遇到了巨大的权限问题,除此之外,权限问题的级别远远高于我真正想要的级别。我所需要做的就是发送一个简单的自定义int消息,这样我的进程就知道该关机了。

如果它真的像向另一个程序发送关机信号一样简单,那么您就可以。两个进程都使用相同的名称创建事件。一个监视它,另一个可以发出信号。观看的人可以使用修改过的消息泵,而不是PeekMessage

这里存在轻微的拒绝服务风险,因为恶意进程可能创建同名事件并导致其他应用程序退出

如果您需要更复杂的通信,您将需要管道、邮件槽、共享内存、文件监视、注册表监视,或者使用另一个可同步的内核事件(互斥、信号量等)。

这很好:

// msg.c:

#include <windows.h>
#include <stdio.h>

int CALLBACK WinMain (_In_ HINSTANCE hInstance, _In_ HINSTANCE hPrevInstance, _In_ LPSTR lpCmdLine, _In_ int nCmdShow) {
    MSG msg;
    DWORD curThreadId;

    curThreadId = GetCurrentThreadId();

    // Send messages to self:
    PostThreadMessage(curThreadId, WM_USER, 1, 2);
    PostThreadMessage(curThreadId, WM_USER+1, 3, 4);
    PostThreadMessage(curThreadId, WM_USER+2, 5, 6);
    PostThreadMessage(curThreadId, WM_USER+3, 7, 8);
    PostThreadMessage(curThreadId, WM_QUIT, 9, 10);

    while (GetMessage(&msg, NULL, 0, 0)) {
        printf("message: %d; wParam: %d; lParam: %d\n", msg.message, msg.wParam, msg.lParam);
    }

    return (int) msg.wParam;
}

如果您的IPC不需要任何参数,您的服务可以实现其
处理程序/Ex()
查找的自定义控制代码,然后其他应用程序可以使用该代码将该控制代码发送到服务


但是,可以使用
ControlService(service\u CONTROL\u STOP)
以编程方式关闭服务。当服务的
处理程序/Ex()
收到
服务\u控制\u停止
请求时,该服务应该自动关闭。

我有发布愚蠢回复的危险,但是,您是否考虑过为IPC使用共享内存?似乎非常适合您的应用程序(请参阅)。邮件槽也可能是一个很好的选择()。希望这有帮助!如果你的应用程序中有什么让所有这些方法变得无关紧要的地方,请告诉我。在这一点上,我会选择@Ivan。这可能很简单,比如设置注册表值或文件中的值,然后让服务监视或轮询它。Naff,但是快速简单。一个命名的管道是最好的选择。我想你现在遇到了权限问题,这在任何其他机制下都不会变得更好。其他答案和评论解释了更好的方法,但要澄清的是,服务可以创建窗口,他们只是无法与桌面或任何其他会话进行交互。@HansPassant SendMessage在与pipe完全相同的情况下根本不会给我们任何权限问题,所以我知道有些方法没有那么多限制。我对管道导致这些问题的最好猜测是因为它们可以发送更复杂的消息消息泵?只需要一个三行线程-创建命名事件,使用WaitForSingleObject等待它,调用ExitProcess(0)。@Martin James:我认为关键是以有序的方式关闭进程,在这种情况下,您可能需要得到UI线程的通知。如果您只是想终止该进程,那么您也可以从另一个程序终止该进程。另外,这个问题暗示他/她通常会通过窗口消息来完成,所以我假设他的意图是在消息泵中接收通知。我误读了。我以为服务正在向交互进程发送信号。@MartinJames除了ExitProcess调用:)你基本上是对的。这一点是为了避免杀死进程,而是让它干净地退出。这可以很容易地用一个我可以从线程翻转的bool来完成,所以这个解决方案看起来非常有希望。这非常有效!非常感谢您为我指出这些函数!我所做的唯一不同是使用WaitForSingleObject,但那只是因为它更适合我所需要的。
> g++ -m64 -mwindows -c -o msg.o msg.c
> g++ -s -o msg.exe msg.o
> msg.exe
message: 1024; wParam: 1; lParam: 2
message: 1025; wParam: 3; lParam: 4
message: 1026; wParam: 5; lParam: 6
message: 1027; wParam: 7; lParam: 8

> echo %ERRORLEVEL%
9