我正在为 Windows 编写一个 Web 测试框架,它使用多个浏览器来测试 Web 应用程序。
我想启动隐藏的浏览器,但它不起作用。
我正在使用 CreateProcess 来启动带有 SW_HIDE 标志的浏览器,
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
CreateProcess(NULL, const_cast<char*> (cmd.c_str()) , NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
它对于 Internet Explorer 和其他应用程序运行良好,但对于 Firefox 和其他浏览器则失败。
我知道进程可以选择是否遵循传递的标志。有什么办法可以强制它开始隐藏吗?
我可能可以等到窗口显示,然后通过获取打开的窗口的句柄来隐藏它。但我正在寻找更清洁的解决方案。
I'm writing a web testing framework for windows that uses multiple browsers to test web apps.
I want to launch the browsers hidden but it's not working.
I'm using CreateProcess to start the browsers with the SW_HIDE flag
STARTUPINFO si;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
si.dwFlags = STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
PROCESS_INFORMATION pi;
ZeroMemory(&pi, sizeof(pi));
CreateProcess(NULL, const_cast<char*> (cmd.c_str()) , NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi);
It works fine for internet explorer and other apps, but fails with firefox and other browsers.
I'm aware that a process is able to choose whether or not to follow the passed flags. Is there any way i can force it to start hidden?
I can probably wait until the window shows up and then hide it by getting a handle to the open window. But I'm looking for cleaner solution.
发布评论
评论(5)
尝试 si.wShowWindow = 0;
有趣的是,这对我有用,但对 SW_HIDE 不起作用,它应该具有相同的值。
try si.wShowWindow = 0;
funny this worked for me, not SW_HIDE which should carry the same value though.
您可以启动应用程序,然后向其主窗口发送 WM_SIZE 消息。
http://msdn.microsoft.com/en-我们/library/ms632646(v=vs.85).aspx
You can launch the application and then send a WM_SIZE message to its main window.
http://msdn.microsoft.com/en-us/library/ms632646(v=vs.85).aspx
根据MSDN,看起来像你需要在 dwFlags 中传递此标志。
According to MSDN, looks like you need to pass this flag in dwFlags.
问题在于,仅当使用命令
SW_SHOWDEFAULT
调用函数ShowWindow
时,才使用wShowWindow
的值,另外,正如 FastAl 所说,浏览器创建一些额外的过程来完成额外的任务。根据您的想法和 FastAl 的答案,您可以这样做来隐藏您创建的进程创建的窗口:
1.- 使用以下命令创建进程列表:
CreateToolhelp32Snapshot
、Process32First
、Process32Next
和CloseHandle
;仅采用您创建的进程所创建的进程。 此处演示了如何使用此功能,它适用于除 Windows NT 之外的任何 Windows 版本。2.- 使用
EnumWindows
枚举屏幕上的窗口,并使用GetWindowThreadProcessId
检查窗口是否是由上一步中恢复的任何进程创建的。3.- 如果窗口是由步骤 1 中定义的进程之一创建的;使用 ShowWindow 函数隐藏窗口。
您可以监视您创建的进程并检查是否创建了新进程/窗口。
The problem is that the value of
wShowWindow
is used only when the functionShowWindow
is called with the commandSW_SHOWDEFAULT
, additionally as FastAl said the browser create some additional process to do additional tasks.Based on you idea and the answer of FastAl, you can do this to hide the windows created by the process that you created:
1.- Create a List of Process with:
CreateToolhelp32Snapshot
,Process32First
,Process32Next
andCloseHandle
; taking only the process that has been created by the process that you created. Here is a demostration of how to use this functions, it works with any windows version except Windows NT.2.- Use
EnumWindows
to Enumerate the windows on the screen and withGetWindowThreadProcessId
check if the windows was created by any of the process recovered in the previous step.3.- If the windows was created by one of the process defined in the step 1; hide the windows using the ShowWindow function.
You can monitor the process created by you and check if new process/windows are created.
您可以从服务启动进程(例如以 NETWORK SERVICE 用户身份运行)。这将阻止他们显示任何 UI。然而,它会阻止您完全查看用户界面,即使您稍后想查看。
另一种选择是使用 Window Stations 和 Desktops 执行某些操作,请查看 MSDN 上有关 Window Station 和桌面的部分。一个想法是使用 CreateDesktop然后将此桌面指定为 CreateProcess 的 STARTUPINFO 结构中的 lpDesktop 参数。如果您稍后想要显示 UI,请使用 切换桌面。
You could launch the processes from a service (running as the NETWORK SERVICE user for instance). This will prevent them from showing any UI. It will however prevent you from being able to look at the ui at all, even if you want to at a later time.
Another option would be to do something with Window Stations and Desktops, take a look at the section about Window Stations and Desktops on MSDN. An idea would be to use CreateDesktop and then specifying this desktop as the lpDesktop parameter in the STARTUPINFO structure given to CreateProcess. If you at a later time want to display the UI, use SwitchDesktop.