3

Windows 7 で .NET Windows サービスを使用してメッセージ ボックスを表示する

ユーザーが Windows XP でアクセス カードをスキャンすると、確認メッセージ ボックスを表示するために使用される Windows サービスがありましたが、Windows 7 に移行すると、そのポップアップ機能が機能しなくなりました。この投稿で説明されているように、.NET Windows サービスを使用してメッセージ ボックスを表示する Windows 7では、指示に従いましたが、アプリケーションをコンソール アプリケーションとして実行すると機能しますが、Windows サービスとしてインストールすると機能しません。以下は私のコードです。また、result 変数は false を返し、err 変数は 5 を返しています。

class Class1
{
    public static IntPtr WTS_CURRENT_SERVER_HANDLE = IntPtr.Zero;
    public static int WTS_CURRENT_SESSION = -1;
    public void test()
    {
        bool result = false;
        string title = "Hello";
        int tlen = title.Length;
        string msg = "Terminal Service!";
        int mlen = msg.Length;
        int resp = 0;

        result = WTSSendMessage(WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, title, tlen, msg, mlen, 0, 0, out resp, true);
        int err = Marshal.GetLastWin32Error();
        System.Console.WriteLine("result:{0}, errorCode:{1}, response:{2}", result, err, resp);

    }

    [DllImport("wtsapi32.dll", SetLastError = true)]
    static extern bool WTSSendMessage(
        IntPtr hServer,
        [MarshalAs(UnmanagedType.I4)] int SessionId,
        String pTitle,
        [MarshalAs(UnmanagedType.U4)] int TitleLength,
        String pMessage,
        [MarshalAs(UnmanagedType.U4)] int MessageLength,
        [MarshalAs(UnmanagedType.U4)] int Style,
        [MarshalAs(UnmanagedType.U4)] int Timeout,
        [MarshalAs(UnmanagedType.U4)] out int pResponse,
        bool bWait);

    [DllImport("Kernel32.dll", SetLastError = true)]
    static extern int WTSGetActiveConsoleSessionID();

}
4

2 に答える 2

2

WTSGetActiveConsoleSessionId を宣言しましたが、それを呼び出したことはありません。この関数は、現在アクティブなセッション ID を返します。これは、WTSSendMessage に渡す必要があるセッション ID です。

現在のコードは、サービスのセッションであるセッション 0 でメッセージを表示しようとしています。意図したものではありません。

ただし、関数を呼び出す前に、その宣言を修正する必要があります。スペルが間違っています。これは WTSGetActiveConsoleSessionId という名前です。

文字列の長さのパラメーターは、ゼロ ターミネータを考慮する必要があると思います。渡す値に 1 を追加します。Unicode API に切り替えた場合、これらの値は文字ではなくバイト単位で測定されるため、これらの値に 2 を掛ける必要があります。

もう1点。API 呼び出しが失敗した場合にのみ、エラー コードを要求してください。したがって、コードでは、結果が false の場合にのみ Marshal.GetLastWin32Error を呼び出す必要があります。

于 2013-09-11T06:10:16.577 に答える
2

WTSSendMessage() への呼び出しは、「現在のセッションでメッセージ ボックスを表示する」ことを意味する WTS_CURRENT_SESSION を指定します。サービスとして実行すると、Windows 7 で分離されたセッション 0 になります。メッセージボックスがそこに表示されるのは絶対に嫌ですよね!

通常のユーザーのセッションに表示するには、ゼロ以外のセッション ID を指定する必要があります。詳細については、WTSSendMessage() のドキュメントを参照してください。

于 2013-09-11T05:38:21.360 に答える