9

「WM_ENDSESSION」のような Windows メッセージを Windows サービスに送信 (模倣) するツールはありますか?

また

C#を使用してWindowsメッセージをプロセスに送信するにはどうすればよいですか?

(C#しか知らない)

編集: 目的: 基本的に、システムのシャットダウン時にのみ発生するバグを修正するために Windows サービスをデバッグする必要があります。

4

7 に答える 7

12

サービスはServiceController クラスを使用して制御する必要があります

Windows サービスを表し、実行中または停止中のサービスに接続したり、操作したり、情報を取得したりできます。

このクラスを使用してサービスを開始、停止、および通信するために使用できます。

于 2009-08-05T13:51:27.333 に答える
3

デバッグ中に Windows のシャットダウンをシミュレートする方法への回答を確認してください。

サービスには、サブスクライブできる OnShutdown という「イベント」があるため、そのコードに問題がある可能性があります。コードが .net の場合、コードをサブクラス化して、保護された OnShutdown メソッドを呼び出してデバッグできます。しかし、問題は、サービスがリソースが利用可能であることを期待しているが、リソースが既に閉じられているためではないことを他の人が示唆している可能性もあります。

また、サービスが .net 2.0 で記述されている場合、ワークステーションがシャットダウンされているときに Stop() コマンドがサービスで自動的に呼び出されないことに注意してください。これは非常に驚くべきことで、.net 3.5で修正されましたが、.net 2.0 を使用している場合は、OnShutdown() 内で Stop() を自分で呼び出す必要があります。

于 2010-10-24T16:29:25.273 に答える
2

ウィンドウの hwnd がある場合は、メッセージを送信できます。唯一の制限は、ウィンドウ テキストの設定などのポインターを含むメッセージを送信できないことです。hwnd の値と送信するメッセージを指定して
呼び出すだけです。 hwnd を見つけるには、spy++ を使用できます。PostMessage()

Windows サービスにはウィンドウがないため、これらすべてを Windows サービスに接続する方法がわかりません。

于 2009-08-05T13:25:39.723 に答える
1

以下をインポートして定義することをお勧めします。

[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;

次に、wParam メッセージとして true または false を表す 0x1 または 0x0 を介して送信します。

したがって、コードでは次を使用します。

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);

この質問には、どの詳細情報がありますか。

または多分

これが同様のハンドルであるかどうかはわかりませんが、疑いがありますが、誰かがそうであるかどうかを教えてくれますが、Process ハンドルを取得できます。つまり、Process.GetProcessesByName("MyAppName") を使用してプロセスを取得できます。 ;、しかし、あなたが求めているハンドルを取得するとは思わないので、これに依存しないでください。ただの提案です。

于 2009-08-05T13:42:58.610 に答える
0

各メッセージは任意の LPARAM および WPARAM 値を持つことができるため、任意のメッセージを送信するツールはないと思います。

しかし、Windows メッセージに関する最も便利なツールは spy++ です。Spy++ は Visual Studio に含まれており、送信されるメッセージ、ウィンドウ階層などを確認するのに役立ちます。

SendMessage Win32 APIを使用して、C# 経由でメッセージを送信できます。FindWindowFindWindowExなどの Win32 API を使用して、要求するウィンドウ ハンドルを取得できます。

編集(質問の編集に一致させるため):サービスは、シャットダウン時にウィンドウによって自動的に停止されます。したがって、バグを修正するには、サービス自体のコードを変更して適切にシャットダウンする必要があるようです。

Edit2: または、サービスを停止する場合は、Win32 API ControlServiceを使用してSERVICE_CONTROL_STOP 0x00000001.

于 2009-08-05T13:22:46.280 に答える
0

これが同様のハンドルであるかどうかはわかりませんが、疑いがありますが、誰かがそうであるかどうかを教えてくれますが、Process ハンドルを取得できます。つまり、Process.GetProcessesByName("MyAppName") を使用してプロセスを取得できます。 ;、しかし、あなたが求めているハンドルを取得するとは思わないので、これに依存しないでください。ただの提案です。

実際、このメソッドは機能します...プロセス オブジェクトの「MainWindowHandle」プロパティにアクセスするだけです。例えば...

Process myProcess;
Int handle;
myProcess = Process.GetProcessesByName("MyAppName");
handle = myProcess.MainWindowHandle;
于 2009-09-30T23:08:54.970 に答える