爬取网页信息时,使用了C# + Selenium (WebDriver.dll) + chromedriver + Chrome
除了chromedriver控制台窗口(可以通过CDS.HideCommandPromptWindow = true隐藏),还有出现一个谷歌浏览器的Devtool调试工具的控制台窗口如下图:
尝试了很久没有能够通过添加启动参数的方式隐藏掉,于是尝试通过Windows窗口句柄的方式隐藏。 最终得到想要的隐藏效果。
基础知识:句柄分为:1.窗口句柄 和 2.线程句柄
本人通过System.Diagnostics.Process类只能找到线程句柄。 最初使用线程句柄作为参数,
使用 bool ShowWindowAsync(IntPtr hWnd, int nCmdShow); 隐藏窗口,
总是没有效果 ( 哭 /(ㄒoㄒ)/~~)
使用了public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);,才找到正确的窗口句柄。
如果有相同的类名lpClassName或者标题名lpWindowName,还需要通过窗口句柄找到进程PID,通过PID确定进程名称,从而正确筛选出想要隐藏的窗口。
Tips:public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName); 该方法可以找到具有相同类名lpClassName或者标题名lpWindowName的不同窗口的句柄。
使用 C#关键代码如下:
引用命名空间
using System;
using System.Runtime.InteropServices;
using System.Diagnostics;
using OpenQA.Selenium; //需要WebDriver.dll
using OpenQA.Selenium.Chrome; //需要WebDriver.dll
可能需要加个线程,来多次检测窗口是否创建 ,本人在Unity-MonoBehaviour -FixedUpdate()方法下使用,会多次使用
Process[] proc = Process.GetProcessesByName("conhost");
for (int i = 0; i < proc.Length; i++)
{
//startTime_Devtools时本人自己定义的变量
if (proc[i].StartTime.Ticks >= startTime_Devtools.Ticks)
{
curWindow = FindWindow("ConsoleWindowClass", null); //通过类名查找窗口句柄
int pidTemp = 0;
if (curWindow != IntPtr.Zero)
{
GetWindowThreadProcessId(curWindow, out pidTemp);
//获得窗口句柄的进程PID
Process processTemp = Process.GetProcessById(pidTemp);
if (processTemp.ProcessName == "MyChrome") //筛选是否为合适的窗口
{
ShowWindowAsync(curWindow, 0); //通过句柄隐藏窗口
}
}
}
}
///
/// Win32 API Imports
///
[DllImport("user32.dll")]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("User32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpClassName, string lpWindowName);
[DllImport("user32.dll")]
public static extern
bool ShowWindowAsync(IntPtr hWnd, int nCmdShow);
/// <summary>
/// 通过窗口句柄获取线程ID(TID)和进程ID(PID)
/// </summary>
/// <param name="hwnd">窗口句柄</param>
/// <param name="PID">返回进程ID</param>
/// <returns>返回线程ID</returns>
[DllImport("User32.dll", CharSet = CharSet.Auto)]
public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int PID); //获取线程ID
参考了网上很多的文章,最终实现了比较满意的效果。😀
版权归原作者 暗空凌 所有, 如有侵权,请联系我们删除。