2010-12-15 12 views
3

ターゲットは:.net winformに埋め込まれたWatin対応ブラウザテストです。WatiNと.net winforms WebBrowserコントロール - DialogWatcherは可能ですか?

現在、.net WebBrowserコントロールを使用して、ブラウザの動作をwinformに埋め込みます。私たちは、このようなコードをフォーム上のWebBroswerコントロール(感謝prostynick)にWatiNを取り付ける :

var thread = new Thread(() => 
{ 
    Settings.AutoStartDialogWatcher = false; 
    var ie = new IE(webBrowser1.ActiveXInstance); 
    ie.GoTo("http://www.google.com"); 
}); 
thread.SetApartmentState(ApartmentState.STA); 
thread.Start(); 

問題はこれです - 「Winフォームのブラウザは」テスト/自動化の際にポップアップを処理する必要があります。

質問:Watinがwinforms WebBrowserコントロール(WatiNで生成されたIEウィンドウを使用していない)に接続されていると、どのようにポップアップを処理できますか?
a)WatinのDialogWatcherは引き続き使用できますか?もしそうなら...どう?
b)そうでなければ、私たち自身のDialogWatcherを書くことができますが、追加するにはhWndまたはprocessIDが必要です。 Waitinが独自のウィンドウやプロセスを持たないこのシナリオでは、正しいhWndまたはprocessIdはどこから得られますか?

先入観ありがとうございました...同じターゲットに到達する別のアプローチは歓迎です!

答えて

3

男ああ、この質問は何度もアップしますし、私はいつものように何か書い:をしかし、ハッキングの少しであなたが(から:How to use watin with WebBrowser control?)オリジナルDialogWatcherクラスに基づいて独自に作成することができますので、私はに掘らそれを見つけるための私のソースコードと私はちょうど私がそれをやったかを示します。おそらく完璧ではないかもしれませんが、動作していて問題はありませんでした。

  1. 名前空間など、クラス名を変更し、元DialogWatcherをコピーしてFormDialogWatcherクラスを作成します。私は、元のクラスから次のフィールドやメソッドを削除しました。これはおそらく必要ではありませんが、おそらくWebBrowser controllのインスタンスを1つだけ使用することになりますので、このコードは実際には必要ではなく、変更を行っても削除しないと正しく動作するかどうかわかりません。削除するには:

    • private static IList<DialogWatcher> dialogWatchers
    • public static DialogWatcher GetDialogWatcher(IntPtr mainWindowHwnd)
    • public static DialogWatcher GetDialogWatcherFromCache(IntPtr mainWindowHwnd)
    • public static void CleanupDialogWatcherCache()
    • public void IncreaseReferenceCount()
    • public void DecreaseReferenceCount()
    • public int ReferenceCount { get; private set; }
    • private bool IsWindowOfIexploreProcess(Window window)
  2. Start()方法でこれを置き換えます。これで

    if (new Window(MainWindowHwnd).Exists()) 
    { 
        var winEnumerator = new WindowsEnumerator(); 
        var windows = winEnumerator.GetWindows(win => true); 
    

    を:

    var mainWindow = new Window(MainWindowHwnd); 
    if (mainWindow.Exists()) 
    { 
        var winEnumerator = new WindowsEnumerator(); 
        var windows = winEnumerator.GetWindows(window => window.ProcessID == mainWindow.ProcessID); 
    

  3. HandleWindow(Window window)でこれを削除する(唯一の本当の違いはGetWindowsコールの内部です)行:

    01すべてだ
    if (!IsWindowOfIexploreProcess(window)) return; 
    

!開始するには、それを作成してください:new FormDialogWatcher(Handle)HandleはちょうどFormのプロパティです。おそらく、あなたのサンプルコードにIEオブジェクトを作成した後に作成することができます(LOL、私はちょっと考えました。ニックネームが問題になります:)) - かそのようなものです。すぐに開始され(コンストラクターを参照)、ウィンドウが消滅した後でメインループが壊れます。

EDIT:全体の説明:あなたはダイアログを未処理の閉じるには、このクラス(またはWatiNの設定)を設定した場合は、その後もあなたのMessageBox.Showが閉鎖されること:)

EDIT 2(!重要)を注意してください上記は元のDialogWatcherクラスWatiN SVNトランクリビジョン1056から取得されたクラスに関連しています。このリビジョンとファイルへの直接リンク:http://watin.svn.sourceforge.net/viewvc/watin/trunk/src/Core/DialogHandlers/DialogWatcher.cs?revision=1056&content-type=text/plain&pathrev=1056

+0

プロスキンニック。細かい作業。 – user526186

4

私はWatiN(ヘッドリビジョン1166 - トランク:https://watin.svn.sourceforge.net/svnroot/watin/trunk/src/)の最新バージョンにアップグレードしました。元のDialogWatcherクラスに変更があったため、少ないコードで既存のDialogWatcherを使用できるようになりました。

var ie = new WebBrowserIE(webBrowser1); 
var thread = new Thread(() => 
{ 
    ie.GoTo("http://www.plus2net.com/javascript_tutorial/window-alert.php"); 
    ie.Button(Find.ByValue("Click here to display alert message")).Click(); 
}); 
thread.SetApartmentState(ApartmentState.STA); 
thread.Start(); 

警告:

public class WebBrowserIE : IE 
{ 
    private IntPtr hwnd; 

    public WebBrowserIE(WebBrowser webBrowserControl) 
     : base(webBrowserControl.ActiveXInstance, false) 
    { 
     hwnd = webBrowserControl.FindForm().Handle; 
     StartDialogWatcher(); 
    } 

    public override IntPtr hWnd 
    { 
     get 
     { 
      return hwnd; 
     } 
    } 

    protected override void Dispose(bool disposing) 
    { 
     hwnd = IntPtr.Zero; 
     base.Dispose(disposing); 
    } 
} 

ではなく、元のIEクラスでそれを使用して消えjavascriptの警告ダイアログを参照してください。

クラスを作成したスレッドの外WebBrowserIEインスタンスを作成します。それ以外の場合は、Handleプロパティの値をFormと読み取るときに、このクラスを変更してスレッド間の操作を回避する必要があります。

+0

優秀!上記のコードは、ファイルのアップロードを除いて成功しています。ファイルアップロードウィンドウは開きますが、このコードを使用するとファイル名を入力して閉じることはできません:ie.FileUpload(Find.ByName( "myInputTagName"))。Set( "c:\\ myUploadFileName.txt ")。何かご意見は? – user526186

+0

うーん...それは私のために働く。 Vista、IE8、SVNトランクのWatiN – prostynick

+0

メソッド内でローカル変数 'ie'を使用しているので、この変数をスレッドに渡しているので、スレッドが終了したときにGCが' ie'を処理するよう通知されます。それを強制的に処分することはできません – Odys

関連する問題