是否有任何工具發送(模仿)Windows消息如'WM_ENDSESSION'到Windows服務?發送Windows消息到Windows服務
OR
我怎麼能發送窗口消息,使用C#的過程?
(我只知道C#)
編輯:目的:基本上我有調試Windows服務用於固定僅發生在關閉系統的錯誤。
是否有任何工具發送(模仿)Windows消息如'WM_ENDSESSION'到Windows服務?發送Windows消息到Windows服務
OR
我怎麼能發送窗口消息,使用C#的過程?
(我只知道C#)
編輯:目的:基本上我有調試Windows服務用於固定僅發生在關閉系統的錯誤。
通常,服務沒有窗口(更不用說消息泵)來接收Windows消息。
如果錯誤確實只發生在關機(而不是僅僅停止服務)上,可能會出現這樣的情況:某些東西依賴於正在消失的資源,而這些資源沒有得到正常處理(在這種情況下,錯誤修復程序可能是正確設置服務依賴關係)。您是否嘗試過使用遠程調試工具在關機之前附加到進程?
這是值得研究,如果你能得到要發生的問題,而無需關閉,也許當剛剛與服務控制管理器停止服務(無需編程方式做到這一點,因爲這是一個調試的情況),在這種情況下,你可以在你的服務中斷點OnStop()(我假設C#)並觀察發生了什麼。
我有一種感覺,依賴關係不能幫助關閉......但我不確定這一點。 – Rory 2010-10-24 16:42:01
我不認爲有一種工具可以發送任意消息,因爲每條消息都可以具有任意的LPARAM和WPARAM值。
但圍繞windows消息的最有用的工具是spy ++。 Spy ++包含在Visual Studio中,可幫助您查看發送的消息,窗口層次結構等。
您可以使用SendMessage Win32 API通過C#發送消息。您可以通過使用Win32 API(如FindWindow或FindWindowEx)來獲得它要求的窗口句柄。
編輯(以匹配問題的編輯):服務在關機時自動停止。所以要修復你的bug,聽起來你需要修改服務本身的代碼來正確關閉。
Edit2:或者,如果你想停止服務,你應該使用Win32 API ControlService傳入SERVICE_CONTROL_STOP
0x00000001
。
但我必須將消息發送到作爲Windows服務運行的進程? FindWindow在這種情況下如何工作? – devnull 2009-08-05 13:24:54
該服務必須首先有一個窗口或消息隊列才能發送消息。根據Vista設置,您可能無法將消息發送到在不同會話中運行的服務。如果你有服務的控制權,更好的選擇是管道。 – 2009-08-05 13:26:59
如果你有一個窗口的hwnd,你可以發送消息。唯一的限制是您無法發送包含設置窗口文本等指針的消息。
只需撥打PostMessage()
,使用hwnd的值和您要發送的消息。
要找到hwnd,你可以使用spy ++。
我不知道你怎麼樣,因爲Windows服務連接這一切的Windows服務沒有窗戶。
我會建議導入和定義如下:
[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是你想將消息發送到窗口的窗口句柄。
編輯
獲得Windows處理,如果你不知道吧,我假設你會知道它的名稱或者姓名。如果是這樣你可以使用這個:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern int FindWindowEx(int hwndParent, int hwndEnfant, int lpClasse, string lpTitre);
哪個更多有關可在this question.
或許
發現我不知道這是一個類似手柄,我懷疑它,但有人可以讓我知道如果它是,但你可以得到一個進程句柄,這意味着你可以使用Process.GetProcessesByName(「MyAppName」)得到進程,儘管不要依賴這個,因爲我沒有認爲它會得到你以後的處理。只是一個建議。
我不知道這是一個類似手柄,我對此表示懷疑,但有人可以讓我知道,如果它是,但你可以得到一個進程句柄,這意味着你可以使用進程中取得的過程。 GetProcessesByName(「MyAppName」),儘管不要依賴這個,因爲我不認爲它會得到你以後的句柄。只是一個建議。
實際上這種方法將工作......您只需訪問過程對象的'MainWindowHandle'屬性。對於實例...
Process myProcess;
Int handle;
myProcess = Process.GetProcessesByName("MyAppName");
handle = myProcess.MainWindowHandle;
退房的答案How to simulate windows shutdown while debugging?
服務有一個「事件」稱爲OnShutdown他們可以訂閱,因此它可能是問題出在該代碼。如果代碼是.net,你可以繼承它,所以你可以調用受保護的OnShutdown方法來調試。但問題也可能如其他人所建議的那樣,服務期望資源可用,這不是因爲它們已經關閉。
此外,如果該服務是以.net 2.0編寫的,請注意,Stop()命令在工作站關閉時不會自動調用服務!這非常令人驚訝,並且是fixed in .net 3.5,但是如果您使用.net 2.0,則需要在OnShutdown()中自己調用Stop()。
爲什麼這不投票更多 – Malachi 2013-10-10 22:01:39
我認爲它是屬於stackoverflow.com – 2009-08-05 13:29:30
任何運氣呢? – ThePower 2009-08-06 11:59:19