Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ SwitchDesktop会暂时工作,但过一会儿会切换回来_C++_Windows_Winapi - Fatal编程技术网

C++ SwitchDesktop会暂时工作,但过一会儿会切换回来

C++ SwitchDesktop会暂时工作,但过一会儿会切换回来,c++,windows,winapi,C++,Windows,Winapi,我有一些代码来创建一个新的桌面,并在桌面上启动一个进程 在一些选择Windows XP的机器上,当代码运行时,我可以看到它切换到新的桌面并启动进程,但几乎立即,桌面切换回正常的桌面 这段代码在大约98%的机器上运行良好,我似乎无法找出这段代码不能在其他机器上运行的任何原因 SwitchDesktop应该可靠吗?我可以钩住可能从另一个应用程序调用的SwitchDesktop调用吗 我的代码: int DLL_EXP_IMP WINAPI Process_Desktop(char *szDeskto

我有一些代码来创建一个新的桌面,并在桌面上启动一个进程

在一些选择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;
    }
}

我猜SetThreadDesktop失败了

从MSDN: 如果调用线程在其当前桌面上有任何窗口或挂钩,则SetThreadDesktop函数将失败,除非hDesktop参数是当前桌面的句柄

您提到StartProcess会一直阻塞,直到进程终止。 因此,没有人引用新的桌面,因此桌面将消失

你可能想在C++中考虑包装错误系统调用 -在它们失败时抛出异常。 当然,这两个CealTeaTeal/CutoTeCH属于C++资源包装器。


这是2013年

要么SwitchDesktop在大多数情况下失败,要么是访问被拒绝,要么是由于另一个桌面中存在句柄而出现错误170,要么是有另一个程序切换回默认桌面

我知道一个事实,雅虎工具栏做了5-6-7版本,也许他们现在修复了;KABE4.exe我不知道这是什么,Acronis程序备份调度程序,AFAIK,等等。所有这些都是在没有任何用户干预的情况下将SwitchDesktop称为一个大禁忌

我为雅虎工具栏证明了这一点;通过将另一个dll注入IE加载的yt.dll并从挂接调用返回FALSE来挂接SwitchDesktop解决了我的问题


大约2年前发送给雅虎的概念证明至今仍未得到答复。

在您发布的代码中,有以下部分:

// 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的两次调用之间。 此代码中没有停止暂停或延迟正在运行的代码、线程或进程的函数,因此当您切换到hNewDesktop时,您会立即切换回HORIGINALIPUT。在调用StartProcess之后,在第二次调用SwitchDesktop之前,应该添加一个带有结束条件的while循环。我不知道while循环的结束条件是什么,但是你知道,你会选择,毕竟这是你的程序


例如,您可以使用GetKeyState或GetAsyncKeyState函数检查键盘上按下的键,并将其作为while循环的结束条件,因此当您按下该键时,您将立即返回到原始桌面

很好的代码,我想我会尝试一下。您是否检查了机器上正在运行的进程以查看是否存在任何差异?可能会有一个切换回初始桌面。事实上,我是这样做的,但问题是没有一个好方法来真正检测哪个进程负责切换。我曾轶闻地读到一些消息传递客户端会这样做。最终,我采用了另一种解决方案。产生的过程可能会崩溃。