C # зондировать и перехватывать Javascript Alert () и Confirm () - PullRequest
6 голосов
/ 16 декабря 2010

Так что я какое-то время проводил исследования и зашел в тупик.Я делаю некоторую автоматизацию IE.В C # /. NET, как я могу обнаружить и использовать предупреждение JavaScript () или подтвердить (), чтобы я мог делать такие вещи, как захватить его текст и нажимать кнопки OK \ Cancel?

Обновить :

Мне нужно повторить: мне нужно иметь возможность извлечь и проверить текст из оповещения () или подтвердить (), а также отправить его с помощью кнопки «ОК» или «Отмена».Примером такого теста может быть проверка того, что, когда я нажимаю на «Удалить», в методе verify () не указано «Вы уверены, что хотите поехать в Мексику?» или что-то ещекроме правильного сообщения.

На всякий случай, позвольте мне повторить: Для целей этого теста у меня есть ноль контроль над источником рассматриваемого сайта.

Наконец, я использую SHDocVw.InternetExplorer.

Ответы [ 3 ]

3 голосов
/ 20 декабря 2010

Я думаю, вам придется использовать FindWindow, SendMessage и т. Д. Вот как WatiN выполняет обработку диалогов.

2 голосов
/ 21 декабря 2010

Я думаю, что вы ищете, это IDocHostshowUI COM-интерфейс. Если я правильно прочитал документацию и мои предположения верны ShowMessage функция будет вызываться при вызове alert () или verify () в JavaScript.

Я сам этого не делал, поэтому я только догадываюсь. Вот некоторые примеры того, кто показывает пример использования этого интерфейса (и многих других) в C #. WebBrowserSample2 звучит как то, что вы ищете.

1 голос
/ 21 декабря 2010

FindWindow - приблизит вас;Вы действительно хотите ручку окна, но вы точно не будете знать, как ее найти.

Лучше было бы использовать EnumWindows. Вот пример подпрограммы, которую вы можете запускать каждую секунду или две, которая даст вам тонну информации о каждом отдельном окне в системе, а затем вы сможете проанализировать его.Вы можете проверить тип окна, текст в нем, получить кнопки и отправить сообщение о щелчке справа.Это позволит вам делать все, на что вы надеетесь.

Чтобы получить текст, вы отправляете wm_gettext, а для кнопки вы можете использовать wm_click.

Извините за C. Следующий лучший пример, который я смог найти, был в LISP.Потратьте время, чтобы прочитать код, вы увидите, в чем идея.Функции соответствия помогают определить, является ли текст правильным, не зная его точно.

Если вам удастся сделать это в c #, держу пари, вы получите намного более короткое решение.(вы можете использовать LINQ на выходе EnumWindows?; -)

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#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;
}
...