5

新しいデスクトップを作成し、そのデスクトップにプロセスを起動するためのコードがいくつかあります。

いくつかの選択された Windows XP マシンで、このコードを実行すると、新しいデスクトップに切り替わり、プロセスが開始されますが、ほとんどすぐにデスクトップが通常のデスクトップに戻ります。

このコードは約 98% のマシンで問題なく動作しますが、これが他のマシンで動作しない理由を突き止めることはできません。

SwitchDesktop信頼できるはずですか?SwitchDesktop別のアプリケーションから呼び出される可能性のある呼び出しをフックできますか?

私のコード:

int DLL_EXP_IMP WINAPI Process_Desktop(char *szDesktopName, char *szPath)
{
    HDESK   hOriginalThread;
    HDESK   hOriginalInput;
    HDESK   hNewDesktop;
    int procSuccess;
    // Save original ...
    hOriginalThread = GetThreadDesktop(GetCurrentThreadId());
    hOriginalInput = OpenInputDesktop(0, FALSE, DESKTOP_SWITCHDESKTOP);

    // Create a new Desktop and switch to it
    hNewDesktop = CreateDesktop(szDesktopName, NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
    SetThreadDesktop(hNewDesktop);
    SwitchDesktop(hNewDesktop);

    // This call blocks until the process exits, and is confirmed to work on the affected machines
    procSuccess = StartProcess(szDesktopName, szPath);

    // Restore original ...
    SwitchDesktop(hOriginalInput);
    SetThreadDesktop(hOriginalThread);

    // Close the Desktop
    CloseDesktop(hNewDesktop);

    if (procSuccess != 0)
    {
        return procSuccess;
    }
    else
    {
        return 0;
    }
}
4

3 に答える 3

1

SwitchDesktop が失敗している (ほとんどの場合、アクセスが拒否されるか、別のデスクトップにハンドルが存在するためにエラー 170 が発生する) か、デフォルトのデスクトップに戻る別のプログラムが存在します。

Yahooツールバーがこれを行ったという事実を私は知っています(バージョン5-6-7、おそらく現在修正されています)。KABE4.exe (これが何かはわかりません)、Acronis プログラム (バックアップ スケジューラ、AFAIK) などです。これらはすべて、ユーザーの介入なしに SwitchDesktop を呼び出しています (大したことではありません)。

これを Yahoo ツールバーで証明しました。別のdllをyt.dll(IEによってロードされた)に挿入してSwitchDesktopをフックし、フックされた呼び出しからFALSEを返すことで問題が解決しました

ほぼ 2 年前に Yahoo に送信された概念実証は、今日に至るまで未回答のままです。

于 2013-10-25T16:45:09.973 に答える
1

私の推測では、 SetThreadDesktop() は失敗します。

MSDN から: 「呼び出し元のスレッドが現在のデスクトップにウィンドウまたはフックを持っている場合、SetThreadDesktop 関数は失敗します (hDesktop パラメーターが現在のデスクトップへのハンドルでない限り)。」

StartProcess() は、プロセスが終了するまでブロックすると述べました。そのため、新しいデスクトップを参照する人は誰もいないため、デスクトップはなくなります。

失敗しやすいシステム コールを C++ でラップすることを検討することをお勧めします。失敗した場合は例外をスローします。確かに、CreateDesktop/CloseDesktop のペアは C++ リソース ラッパーに属しています。これは2013年です!

于 2013-06-21T16:11:19.793 に答える
0

投稿されたコードには、次の部分があります。

// Create a new Desktop and switch to it
    hNewDesktop = CreateDesktop(szDesktopName, NULL, NULL, DF_ALLOWOTHERACCOUNTHOOK, GENERIC_ALL, NULL);
    SetThreadDesktop(hNewDesktop);
    SwitchDesktop(hNewDesktop);

    // This call blocks until the process exits, and is confirmed to work on the affected machines
    procSuccess = StartProcess(szDesktopName, szPath);

    // Restore original ...
    SwitchDesktop(hOriginalInput);
    SetThreadDesktop(hOriginalThread);

StartProcess 関数への呼び出しは、SwitchDesktop への 2 つの呼び出しの間にあります。このコードには、実行中のコード、スレッド、またはプロセスを停止 (一時停止) したり遅延させたりする機能はないため、hNewDesktop に切り替えると、すぐに hOriginalInput に戻ります。StartProcess の呼び出しの後、SwitchDesktop の 2 番目の呼び出しの前に、終了条件付きの while ループを追加する必要があります。while ループの終了条件がどうなるかはわかりませんが、選択するのはあなたのプログラムです。

たとえば、GetKeyState 関数または GetAsyncKeyState 関数を使用してキーボードのどのキーが押されたかを確認し、それを while ループの終了条件にすることで、そのキーを押すとすぐに元のデスクトップに戻ることができます。

于 2014-08-09T19:25:57.453 に答える