C#探测并捕获Javascript Alert()和Confirm()

所以我已经做了一段时间的研究而且我已经走到了尽头。 我正在做一些IE自动化。 在C#/ .NET中,如何探测和使用javascript alert()或confirm()以便我可以执行诸如获取文本并单击OK \ Cancel按钮之类的操作?

更新

我需要重申一下:我需要能够从alert()或confirm()中提取并validation文本,并向其发送OK或Cancel click。 这种测试的一个例子是确保当我点击删除时,confirm()没有说“你确定你想去墨西哥吗?” 或除了正确信息之外的任何其他内容

为了以防万一,请允许我重申:出于本次测试的目的,我无法控制相关网站的来源。

最后,我正在使用SHDocVw.InternetExplorer

FindWindow – 会让你亲近; 你确实想要一个窗口句柄,但你肯定不知道如何找到它。

更好的方法是使用EnumWindows.Here是一个例程,您可以每隔一两步运行一次,它将为您提供有关系统上每个窗口的大量信息,然后您可以对其进行分析。 您可以检查窗口类型,其中的文本,获取按钮,并向右侧发送单击消息。 它会让你做你希望能做的一切。

要获取文本,您发送一个wm_gettext,对于按钮,您可以使用wm_click。

抱歉C.我能找到的下一个最佳例子是LISP。 花点时间阅读代码,你会看到这个想法是什么。 匹配function有助于确定文本是否正确而不完全了解它。

如果你能在c#中设法做到这一点我打赌你会得到更短的解决方案。 (你可以在EnumWindows的输出上使用LINQ吗?;-)

 #include  #include  #include  #include  #include "resource.h" #define ET_STARTUP 1 #define ET_WINDOWOPEN 2 #define ET_RUNEND 3 #define ET_USEREVENT 4 #define M_STAR 1 #define M_QUESTION 2 typedef struct WindowList_s { int iScriptLine; HWND hwnd; char *stName; char *stTitle; char *stClassName; char *stParentName; struct WindowList_s *wlParentPtr; char *stChildName; struct WindowList_s *wlChildPtr; int bWarned; struct WindowList_s *next; } WindowList_t; //////////////// extern long g_runids[]; extern WindowList_t *g_windowlist; extern EventList_t *g_eventlist; char stWTx[2000]; char stWCl[200]; char stPTx[2500]; char stPCl[200]; int bEventEntry=0; // means we're inside of processing an event. HWND LogWinParent; void FixIt(char *buf,unsigned int siz) { int i,j,bump; int ir; char cr; char hex[10]; // keep special characters from screwing up script by // replacing w/ single-character wildcard for (i=0;buf[i];i++) { cr='\0'; ir=0; bump=1; switch(buf[i]) { case '\0':cr='0';break; case '\\':cr='\\';break; case '\n':cr='n';break; case '\t':cr='t';break; case '\a':cr='a';break; case '\b':cr='b';break; case '\f':cr='f';break; case '\r':cr='r';break; case M_STAR:cr='*';break; case M_QUESTION:cr='*';break; case '"':cr='"';break; default: if (buf[i]<32 || buf[i]>=127) { bump=2; ir=buf[i]; } else bump=0; } if (bump) { for (j=strlen(buf)+bump+1>=siz-1?siz-1:strlen(buf)+1; j>i;j--) buf[j+bump]=buf[j]; buf[siz-1]='\0'; if (cr) { buf[i++]='\\'; buf[i]=cr; } if (ir) { sprintf(hex,"\\x%00H",ir); memcpy(buf+i,hex,4); i+=4; } } } } void LogWin(HWND hw) { static long ParentNum=0,ChildNum=0; GetWindowText(hw,stWTx,sizeof(stWTx)-1); GetClassName(hw,stWCl,sizeof(stWCl)-1); FixIt(stWTx,sizeof(stWTx)); FixIt(stWCl,sizeof(stWCl)); if (GetParent(hw)==LogWinParent) { ChildNum++; sprintf(stPTx," WindowObject %ld.%ld \"%s\" \"%s\" " "Parent %ld",ParentNum,ChildNum,stWTx,stWCl,ParentNum); } else if (hw==LogWinParent) { ChildNum=0; ParentNum++; sprintf(stPTx," WindowObject %ld \"%s\" \"%s\"", ParentNum,stWTx,stWCl); } else { ChildNum++; sprintf(stPTx," WindowObject %ld.%ld \"%s\" \"%s\" GRANDCHILD", ParentNum,ChildNum,stWTx,stWCl); } log_it(stPTx); } BOOL CALLBACK EnumChildProc4Logging( HWND hwnd,LPARAM lParam ) { LogWin(hwnd); return 1; } void LogCurrentWindows(void) { static int bEntry=0; static HWND hwCurrentFocus = 0; if (bEntry) return; bEntry=1; LogWinParent=GetForegroundWindow(); if (LogWinParent!=hwCurrentFocus) { hwCurrentFocus=LogWinParent; LogWin(LogWinParent); EnumChildWindows(LogWinParent,EnumChildProc4Logging,0); } bEntry=0; } /******************************************************************/ /* match() - parse wildcard strings . */ /******************************************************************/ int match(char *pattern,char *str) { int patt,st; patt=0; st=0; while(pattern[patt] || str[st]) /* go until both at '\0' */ { if ((!pattern[patt] || !str[st]) && pattern[patt]!=M_STAR) return 0; /* fail if one at '\0' */ if (pattern[patt]==M_STAR) { patt++; while (str[st] && !match(pattern+patt,str+st)) st++; } else if (pattern[patt]!=M_QUESTION && pattern[patt]!=str[st]) return 0; /* Oh, No!! no match. */ else { patt++; st++; } } return 1; /* successful match */ } void CheckWindowList(HWND hwnd) { WindowList_t *wl; HWND hwndParent,hwndTarget; static char buf[600]; // Get the window's class and text GetWindowText(hwnd,stWTx,sizeof(stWTx)-1); GetClassName(hwnd,stWCl,sizeof(stWCl)-1); // Get the Parent Window's class and text hwndParent=GetParent(hwnd); GetWindowText(hwndParent,stPTx,sizeof(stPTx)-1); GetClassName(hwndParent,stPCl,sizeof(stPCl)-1); // search thru window objects, fill in // matching hwnds as appropriate for (wl=g_windowlist;wl;wl=wl->next) { hwndTarget=NULL; // separate variable enables // warning on duplicate matches if (wl->wlChildPtr==NULL && wl->wlParentPtr==NULL) { // no parent/child requirements if (match(wl->stClassName,stWCl) && match(wl->stTitle,stWTx) ) hwndTarget=hwnd; } else if (wl->wlParentPtr) { // parent requirement - if I (hwnd) match the // wl's class/title and the parent (hwndParent) // matches the wl's parentptr's class/title then // set 'me' as the window that matches and has // the proper parent requirement. if (match(wl->stClassName,stWCl) && match(wl->stTitle,stWTx) && match(wl->wlParentPtr->stClassName,stPCl) && match(wl->wlParentPtr->stTitle,stPTx) ) hwndTarget=hwnd; } else { // child requirement - if I (hwnd) match the child // requirement's stuff and the parent(hwndParent) // matches the wl's stuff then set the parent // as that wl's hwnd. if (match(wl->stClassName,stPCl) && match(wl->stTitle,stPTx) && match(wl->wlChildPtr->stClassName,stWCl) && match(wl->wlChildPtr->stTitle,stWTx) ) hwndTarget=hwndParent; } if (hwndTarget) { if (wl->hwnd && !wl->bWarned ) // log a warning on dup windows { sprintf(buf,"267.EnumChildProc4Search.10 " "Warning: more than one match for " "windowobject %s exists",wl->stName); log_it(buf); wl->bWarned =1; } else wl->hwnd=hwndTarget; } } } BOOL CALLBACK EnumChildProc4Search( HWND hwnd,LPARAM lParam ) { CheckWindowList(hwnd); // return value of 1 means continue with rest of enumeration. return 1; } // to enumerate all... enumchild w/ NULL hwnd don't work???! BOOL CALLBACK EnumWindowProc4Search( HWND hwnd,LPARAM lParam ) { CheckWindowList(hwnd); EnumChildWindows(hwnd,EnumChildProc4Search,0); return 1; } // Check thru all windows and runIDs to see if a run is done // or a window has opened. First emumerate the windows and running // programs and then see which events should be run. // this function must not run if blocked, 'once' countdown // has run out, or stopscript=1, or entry = 1 void RunEvents(void) { // Please keep in mind this program's error philosphoy when // extending it, namely, catch all possible script errors // when loading script, but do not display messageboxes for // even the most serious errors when doing events, because // the idea is to catch errors during development and avoid // errors at run time or in production!! static bEventEntry=0; WindowList_t *wl; EventList_t *el; ParmList_t *pl; char *st; int i; long lExitCode; // exit this routine if we shouldn't be here if (g_iStopScript || bEventEntry) return; bEventEntry=1; // clear all of the window handles in windowobject list for (wl=g_windowlist;wl;wl=wl->next) { wl->hwnd=NULL; wl->bWarned = 0; } // enumerate all windows in the system; repopulate all of // the window handles in the windowobject list EnumWindows(EnumWindowProc4Search,0); // go thru event list, calling any events that must // be called; windows handles for any subsequent actions // will have been set by above code. Check for runs ending // to process runend events and search the windowobject list // to process windowopen events. for (el=g_eventlist;g_eventlist && el;el=el->next) { pl=MakeParms(el->stEventTypeSourceLine); st=ParmValue(pl,2); // event name // check for windowopen events if (el->iEventType==ET_WINDOWOPEN) { // search for their open windows!! for (wl=g_windowlist;wl;wl=wl->next) { if (0==_stricmp(wl->stName,st) && wl->hwnd) RunActions(el); if (g_iStopScript) return; // quit doing actions/events ASAP. } } } if (el->iEventType==ET_RUNEND) { sscanf(st,"%ld",&i); if (g_runids[i]!=-1 && g_runids[i]!=0) { GetExitCodeProcess((HANDLE)g_runids[i],&lExitCode); if (lExitCode != STILL_ACTIVE) { RunActions(el); g_runids[i]=0; } } } KillParms(pl); } bEventEntry=0; } void RunStartup(void) { EventList_t *el; if (bEventEntry) return; bEventEntry=1; // check stopscript in case of endscript in startup event! for (el=g_eventlist;g_eventlist && el && !g_iStopScript;el=el->next) { if (el->iEventType==ET_STARTUP) RunActions(el); } bEventEntry=0; } 

我认为你将不得不使用FindWindow,SendMessage等。这就是WatiN如何处理对话框。

我认为您正在寻找的是IDocHostshowUI COM接口。 如果我正确阅读文档并且我的假设是正确的,则在JavaScript中调用alert()或confirm()时将调用ShowMessage函数。

我自己没有这样做,所以我只是在猜测。 以下是某些人在C#中显示使用该界面(以及许多其他界面)的示例。 WebBrowserSample2听起来像你在寻找。