或者
如何使用C#向进程发送Windows消息?
(我只知道C#)
编辑:目的:基本上,我必须调试Windows服务以修复仅在系统关闭时出现的错误。
查看如何在调试时模拟Windows关机的答案。
服务可以订阅名为OnShutdown的“事件”,因此问题可能出现在该代码中。如果代码是.net的,您可以对其进行子类化,以便调用受保护的OnShutdown方法进行调试。但问题也可能是其他人建议的那样,即服务期望可用的资源已被关闭。
此外,如果该服务是在.net 2.0中编写的,请注意在工作站关闭时不会自动调用Stop()命令!这非常令人惊讶,并且已经在.net 3.5中修复,但如果您使用的是.net 2.0,则需要在OnShutdown()内自己调用Stop()。
PostMessage()
即可。[System.Runtime.InteropServices.DllImportAttribute("user32.dll")]
public static extern bool PostMessage(IntPtr handleWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
const int WM_ENDSESSION = 0x0016,
WM_TRUE = 0x1,
WM_FALSE = 0x0;
然后通过0x1或0x0发送wParam消息,分别表示真或假。
因此,在您的代码中,您将使用:
PostMessage(HandleToSendTo, WM_ENDSESSION, WM_TRUE, 0);
HandleToSendTo是您想要发送消息的窗口的窗口句柄。
编辑
如果您不知道窗口句柄,但知道其标题或名称,则可以使用以下方法获取:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern int FindWindowEx(int hwndParent, int hwndEnfant, int lpClasse, string lpTitre);
更多信息可以在这个问题中找到。
或者
我不知道这是否是一个类似的句柄,我怀疑它不是,但如果是的话,有人可以告诉我,但你可以获得一个进程句柄,这意味着你可以使用Process.GetProcessesByName("MyAppName");来获取进程,尽管不要依赖这一点,因为我认为它不会得到你想要的句柄。只是一个建议。
Process myProcess;
Int handle;
myProcess = Process.GetProcessesByName("MyAppName");
handle = myProcess.MainWindowHandle;
我认为没有工具可以发送任意消息,因为每个消息都可以有任意的LPARAM和WPARAM值。
但是,围绕Windows消息最有用的工具是Spy++。Spy++随Visual Studio一起提供,它可以帮助您查看发送的消息、窗口层次结构等等。
您可以使用SendMessage Win32 API通过C#发送消息。您可以使用类似FindWindow或FindWindowEx的Win32 API获取它所需的窗口句柄。
编辑(以匹配问题的编辑):服务会在关闭时自动停止。因此,要修复您的错误,听起来您需要修改服务本身的代码以正确关闭。
编辑2:或者如果您想停止服务,您应该使用Win32 API ControlService,传递SERVICE_CONTROL_STOP
0x00000001
。