`
yidongkaifa
  • 浏览: 4038555 次
文章分类
社区版块
存档分类
最新评论

WebBrowser弹出窗口之(三) – alert( ) / confirm( )

 
阅读更多

alert/confirm等javascript函数产生的对话框是标准的windows对话框,例如

image

通过HOOK对话框的初始化消息WM_INITDIALOG,检测其标题是否为“来自网页的消息”(英文系统需要匹配项文字符串)(因为钩子是针对主线程的,不会捕获到其它进程的消息,如IE的),然后找到“确定”按钮,通过发送按钮的命令消息来模拟点击“确定”按钮,来实现自动关闭。其中,对话框中显示的消息也在一个window中,可以通过字符串匹配来找到,安装HOOK函数的方法与showModalDialog相同,只是处理的消息不同

private static Int32 WH_CALLWNDPROCRET_PROC(Int32 iCode, IntPtr pWParam, IntPtr pLParam)
{
if (iCode return CallNextHookEx(_pWH_CALLWNDPROCRET, iCode, pWParam, pLParam);

CWPRETSTRUCT cwp = (CWPRETSTRUCT)
Marshal.PtrToStructure(pLParam, typeof(CWPRETSTRUCT));
Win32Message msg = Win32Message.WM_NULL;
try {
msg = (Win32Message)cwp.message;
} catch {
return CallNextHookEx(_pWH_CALLWNDPROCRET, iCode, pWParam, pLParam); ;
}

if (msg == Win32Message.WM_INITDIALOG) { //
// A dialog was initialized, find out what sort it was via it's Caption text
string caption = GetWindowText(cwp.hwnd);

// 此处从配置文件中读取需要自动关闭的窗口,配置文件中一行为一项格式为
// titile | message | button
// 先匹配title再匹配message,匹配上后查找button,然后发送消息点击按钮


const string AUTO_CLOSE_CONFIG_FILE = "autoclose.config";
FileInfo fi = new FileInfo(AUTO_CLOSE_CONFIG_FILE);
if (_autoCloseList == null && fi.Exists) {
try {
noock.log.DefaultLogger.Logger.Info("[Auto-closing]Loading config: {0} ...", AUTO_CLOSE_CONFIG_FILE);
_autoCloseList = new List<alertwindowinfo>(); <br> using (FileStream fs = new FileStream(fi.ToString(), FileMode.Open)) { <br> using (StreamReader sr = new StreamReader(fs)) { <br> string line = null; <br> while ((line = sr.ReadLine()) != null) { <br> if (line.Length == 0 || line[0] == '#') // comments <br> continue; <br> string[] fields = line.Split('|'); <br> if (fields.Length != 3) { <br> noock.log.DefaultLogger.Logger.Warning("Invalid config in file: " + fi.ToString()); <br> continue; <br> } <br> _autoCloseList.Add(new AlertWindowInfo(fields[2].Trim(), fields[0].Trim(), fields[1].Trim())); <br> } <br> } <br> } <br> noock.log.DefaultLogger.Logger.Info("[Auto-closing] Loaded {0} items", _autoCloseList.Count); <br> } catch (Exception ex) { <br> noock.log.DefaultLogger.Logger.Exception("[AutoClose]: Failed to load auto-close list: " + fi.FullName, ex); <br> } <br> } <br>// Call the next hook in the chain <br>return CallNextHookEx(_pWH_CALLWNDPROCRET, iCode, pWParam, pLParam); <br>}</alertwindowinfo>

窗口匹配的函数

private static bool MatchWindowAndClickButton(IntPtr hwnd, string caption, string expectedCaption, string message, string button)
{
if (-1 == caption.IndexOf(expectedCaption))
return false;
bool contentMatched = false;
IntPtr pButton = IntPtr.Zero;

// Check out further properties of the dialog
foreach (IntPtr pChildOfDialog in listChildWindows(hwnd)) {
// Go through all of the child controls on the dialog and see what they reveal via their text
int iLength = GetWindowTextLength(pChildOfDialog);
if (iLength continue;

StringBuilder sbProbe = new StringBuilder(iLength + 1);
GetWindowText(pChildOfDialog, sbProbe, sbProbe.Capacity);
string msg = sbProbe.ToString();
noock.log.DefaultLogger.Logger.Info("Child window:[{0}]", msg);
if (msg.IndexOf(message) != -1) {
contentMatched = true;
noock.log.DefaultLogger.Logger.Debug("Matched window message: [{0}]", msg);
continue;
}
if (msg.IndexOf(button) != -1) {
pButton = pChildOfDialog;
noock.log.DefaultLogger.Logger.Debug("Matched button: [{0}]", msg);
}
}

if (pButton != IntPtr.Zero && contentMatched) {
noock.log.DefaultLogger.Logger.Info("Found a window , try to close: [{0}]:{1}:{2}",caption, message,button);
Int32 ctrlId = GetDlgCtrlID(pButton);
//PostMessage(hwnd, WM_COMMAND, ctrlId, (int)pButton);
//SendMessage(pButton, WM_COMMAND, ctrlId, (int)pButton);
SendMessage(hwnd, WM_COMMAND, ctrlId, (int)pButton);
return true;
}
return false;
}

获取窗体文本的函数

public static string GetWindowText(IntPtr hwnd)
{
Int32 iLength = GetWindowTextLength(hwnd);
StringBuilder sb = new StringBuilder(iLength + 1);

GetWindowText(hwnd, sb, sb.Capacity);
return sb.ToString();
}

需要注意配置文件内容要用UTF-8格式,因为C#默认是UTF-8,否则里面出现中文的时候可能出现乱码,导致窗口匹配的时候匹配不上。
实际上这里用到的全是windows的API,与C#本身关系并不大,通过C++、C都可以实现。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics