如何在隐藏模式下创建GUI进程?

时间:2017-10-09 18:27:11

标签: c winapi

我正在尝试以隐藏模式创建一个进程(Internet Explorer" iexplore.exe"准确无误),但没有成功。

我尝试过使用以下代码:

#include "stdafx.h"

BOOL WINAPI GetIePath(LPTSTR Buffer, DWORD Length)
{
    HKEY hKey;

    if(::RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\IEXPLORE.EXE"), 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS)
        return FALSE;

    if(::RegQueryValueEx(hKey, NULL, 0, NULL, (LPBYTE)Buffer, &Length) != ERROR_SUCCESS)
    {
        ::RegCloseKey(hKey);
        return FALSE;
    }

    ::RegCloseKey(hKey);
    return TRUE;
}

int _tmain(int argc, _TCHAR* argv[])
{
    //::ShellExecute(NULL, /*_T("open")*/ NULL, _T("iexplore.exe"), _T("https://www.google.com"), NULL, SW_FORCEMINIMIZE);

    PROCESS_INFORMATION PI = { 0 };
    STARTUPINFO SI = { 0 };
    SI.cb = sizeof(STARTUPINFO);
    SI.dwFlags = STARTF_USESHOWWINDOW;
    SI.wShowWindow = SW_FORCEMINIMIZE;

    TCHAR lpsziepath[MAX_PATH] = { 0 };

    if (!GetIePath(lpsziepath, MAX_PATH - 1))
        return 1;

    if(!::CreateProcess(lpsziepath, _T("iexplore.exe https://www.google.com") /*::GetCommandLine()*/, NULL, NULL, FALSE, /*CREATE_SUSPENDED*/ 0, NULL, NULL, &SI, &PI))
        return 1;

    //::ResumeThread(PI.hThread);

    //if ((hwnd = ::FindWindow(_T("IEFrame"), _T("https://www.google.com/ - Internet Explorer") /*NULL*/)) == NULL)
    //  return 1;

    //::ShowWindow(hwnd, SW_HIDE);

    return 0;
}

SW_HIDE 标志对我来说从未起作用,而 SW_FORCEMINIMIZE 有效,但它不稳定(不保证始终强制它处于隐藏状态,它有时会创建进程处于正常状态"显示")。

有更好的方法吗?

感谢您的理解。

修改 我发现只使用我的代码隐藏了第一个进程。如果我尝试使用launcher exe创建其他实例(代码exe),那么所有的IE实例都将以正常模式创建(如图所示)。

1 个答案:

答案 0 :(得分:0)

您可以尝试其他方法,而不是尝试在当前桌面中启动IE。 Start IE in a hidden/virtual desktop

查看CreateDesktopA/W,创建后,您可以使用SetThreadDesktop 1来设置对此桌面的所有进一步调用。

从这一点开始,您可以调用CreateProcessA/W在该桌面上创建一个IE窗口,并随意执行任何操作。然后,您可以再次调用SetThreadDesktop将流程执行设置回原始用户桌面。

要获取原始桌面,您可以在将当前线程上下文移动到新桌面之前将GetThreadDesktopGetCurrentThreadId一起使用。然后在完成后使用SetThreadDesktop将其恢复。

<强> CODE

INT WINAPI WinMain(HINSTANCE CurrBase, HINSTANCE PrevBase, LPSTR SomeArgs, INT ShowStatus) {
    PROCESS_INFORMATION PI = { 0 };
    STARTUPINFOW SI = { 0 };
    SI.cb = sizeof(STARTUPINFOW);
    SI.dwFlags = STARTF_USESHOWWINDOW;
    SI.wShowWindow = SW_FORCEMINIMIZE;

    WCHAR lpsziepath[MAX_PATH] = { 0 };

    if (!GetIePath(lpsziepath, MAX_PATH - 1))
        return 1;
    lpsziepath[lstrlenW(lpsziepath)/* (* sizeof(WCHAR)) */] = UNICODE_NULL;

    // create the hidden desktop
    HDESK hiddenDesktop = CreateDesktopA("MyHiddenIEDesktop", NULL, NULL, 0, GENERIC_ALL, NULL);
    if (hiddenDesktop) {
        // get the thread for the current desktop
        HDESK currDesktop = GetThreadDesktop(GetCurrentThreadId()); 
        // move to the hidden desktop
        if (SetThreadDesktop(hiddenDesktop)) { 
            // Before calling CreateProcessW you need to tell it which desktop to open the process in
            SI.lpDesktop = TEXT("MyHiddenIEDesktop"); 
            // here processes will with `SI` structure will be created in a hidden "window" / environment
            CreateProcessW(lpsziepath, TEXT("iexplore.exe https://www.google.com"), NULL, NULL, FALSE, 0, NULL, NULL, &SI, &PI);
            // Wait until CreateProcessW finishes execution, and then move on afterwards
            WaitForSingleObject(PI.hProcess, INFINITE);
            // move back to the original desktop after CreateProcessW is called
            SetThreadDesktop(currDesktop);
        }
    }
    return EXIT_SUCCESS;
}

注意

我刚刚从头顶编写了这段代码(因为我现在离桌面不远),但根据它的外观,它会对你有用!如果有的话,只需要玩弄它。