C\#웹 브 라 우 저의 동작 과 주의사항 소개

1.Winform 에서 WebBrowser 를 사용 하고 Form1.cs 에 추가 할 것 이 있 습 니 다.    1.1"Public partial class Form 1:Form"위 에 추가:

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
[System.Runtime.InteropServices.ComVisibleAttribute(true)]
   1.2 Form 1 의 Shown 이벤트 에 추가:

this.UI_webBrowser.ObjectForScripting = this;
2.웹 브 라 우 저 는 Winform 인터페이스 에 놓 여 있 기 때문에 인터페이스 스 레 드(메 인 스 레 드)에서 관리 하고 렌 더 링 을 실행 하 는 것 도 메 인 스 레 드 이기 때문에 업무 논 리 를 메 인 스 레 드 에 두 면 안 되 고 다른 스 레 드 를 열 어 업무 논 리 를 집행 해 야 합 니 다.웹 브 라 우 저 와 Invoke 를 통 해 대화 합 니 다.
  예:

private void Form1_Shown(object sender, EventArgs e)
 {
     this._thread_mainLogic = new Thread(this.ThreadFunction_MainLogic);
     this._thread_mainLogic.Start();
 }

 private void ThreadFunction_MainLogic()
 {
     Debugger.Log(0, "", "\r
\r
");
     this.Invoke( new Action( () => { this.webBrowser.Navigate("http://www.baidu.com");} ) );// Invoke webBrowser
     .....
 }
3.지정 한 URL 을 찾 습 니 다.이 방법 은 비동기 방법 이 므 로 수 동 동기 화가 필요 합 니 다.

//
 private AutoResetEvent _threadControlEvent_Tool_webBrowser_Navigate = null;

 private void Tool_webBrowser_Navigate(string arg_URL)
 {
     this._threadControlEvent_Tool_webBrowser_Navigate = new AutoResetEvent(false);
     this.Invoke(new Action(() =>
     {
         this.webBrowser.DocumentCompleted += webBrowser_DocumentCompleted_Tool_webBrowser_Navigate;
         this.webBrowser.Navigate(arg_URL);
     }));
     this._threadControlEvent_Tool_webBrowser_Navigate.WaitOne();
     this._threadControlEvent_Tool_webBrowser_Navigate.Close();
     this._threadControlEvent_Tool_webBrowser_Navigate.Dispose();
 }

 void webBrowser_DocumentCompleted_Tool_webBrowser_Navigate(object sender, WebBrowserDocumentCompletedEventArgs e)
 {
     this.webBrowser.DocumentCompleted -= webBrowser_DocumentCompleted_Tool_webBrowser_Navigate;
     this._threadControlEvent_Tool_webBrowser_Navigate.Set();
 }
4.ID 가 져 오기 버튼 에 따라 클릭 합 니 다.(웹 페이지 의 URL 링크 에 도 사용 가능)

// ,ID "btn"
HtmlElement element_btn = null;
this.Invoke(new Action(() => { element_btn = this.UI_webBrowser.Document.All["btn"]; }));//
element_btn.InvokeMember("Click");// , ,
5.ID 에 따라 입력 상 자 를 가 져 오고 내용 을 입력 합 니 다.

// ,ID "input"
HtmlElement input = null;
this.Invoke( new Action( () => { input = this.UI_webBrowser.Document.All["input"]; } ) );//
input.InnerText = "123";// "123"。 , Wait_SafeMode 。
Tool_Wait_SafeMode();//
6.ID 에 따라 form 을 가 져 와 제출(submit)

// form,ID "form2"
HtmlElement form2 = null;
this.Invoke( new Action( () => { form2 = this.UI_webBrowser.Document.Forms["form2"]; } ) );//
form_submit.InvokeMember("submit");// form2 。 , 。
7.ID 에 따라 CheckBox 를 가 져 오고 선 택 된 것 으로 설정(Checked)

// CheckBox,ID "checkbox5"
HtmlElement checkBox5 = null;
this.Invoke( new Action( () => { checkBox5 = this.UI_webBrowser.Document.All["checkbox5"]; } ) );//
checkBox5.SetAttribute("Checked", "true");// 。 , 。
8.원소 의 알려 진 속성 에 따라 이 원 소 를 찾 습 니 다

// , : "value" , "12345"
 bool isFind = false;
 HtmlElementCollection htmlElementCollection = null;
 this.Invoke( new Action( () => { htmlElementCollection = this.webBrowser.Document.All; } ) );//
 HtmlElement resultElement = null;

 foreach (HtmlElement currentElement in htmlElementCollection)//
 {
     if (currentElement.GetAttribute("value") == "12345")
     {
         isFind = true;
         resultElement = currentElement;
         break;
     }
 }

 if( ! isFind )
 {
     ;
 }
9.웹 페이지 의 ComboBox 를 설정 합 니 다.아래 코드 에 문제 가 있 으 니 사용 하지 마 십시오.SetAttribute 는 응답 이 없 는 API 이기 때문에 js 를 사용 하여 설정 하 는 것 을 권장 합 니 다.다음 글 에서 WebBrowser 에 js 코드 를 실행 시 키 면 리 셋 이 가능 합 니 다.

// ComboBox,ID "comboBox123", :
 // ID 1,value " "
 // ID 2,value " "
 HtmlElement element_comboBox = null;
 this.Invoke( new Action( () => { element_comboBox = this.webBrowser.Document.All["comboBox123"]; } ) );//
 Tool_Wait_SafeMode();
 this.Invoke( new Action( () => { element_comboBox.SetAttribute("value", "2"); } ) );// " ", value = 2
 Tool_Wait_SafeMode();
10.Tool_Wait_SafeMode

private void Tool_Wait_SafeMode()
 {
     bool isError = false;
     bool isBusy = false;
     do
     {
         this.Invoke(new Action(() =>
         {
             try
             {
                 isBusy = this.webBrowser.IsBusy;
             }
             catch (System.Exception ex)
             {
                 isError = true;
             }
         }));
         if (isError)
         {
             Thread.Sleep(errorWaitTime);// 2 。 , 。
         }
         else
         {
             if (isBusy)
             {
                 Thread.Sleep(arg_waitTime);// 0.1 。 , 。
             }
         }
     }
     while (isError | isBusy);
 }
11.웹 페이지 에서 js 코드 실행
    웹 브 라 우 저 에 js 를 실행 하 게 하 는 것 은 비동기 과정 이 고 리 셋 이 필요 하기 때문에 이 기능 은 복잡 합 니 다.이에 대해 패 키 징 을 진행 하여 동기 화 과정 으로 패키지 하여 사용 하기에 편리 합 니 다.

#region private void Tool_webBrowser_ExecUserJSScript(string arg_jsCodes)
         private AutoResetEvent _threadControlEvent_Tool_webBrowser_ExecUserJSScript_Init = null;
         private AutoResetEvent _threadControlEvent_Tool_webBrowser_ExecUserJSScript_Exec = null;
         private object _returnObj_Tool_webBrowser_ExecUserJSScript = null;

         /// <summary>
         /// WebBrowser JS 。
         /// 1: js , , html js 。 , window.external.NotifyCSharpComplete( msg ); js , CSharp。 arg_jsFunctionDefineCodes。
         /// 2: , arg_jsFunctionName。
         /// 3: , , arg_functionArgs。 , , null, new object[]{}。
         /// 4: js C# , , js window.external.NotifyCSharpComplete( null ); , window.external.NotifyCSharpComplete( );
         /// :js :function jsFunctionTest( arg1, arg2 ) { var arg3 = arg1 + arg2; window.external.NotifyCSharpComplete( " :" + arg3 ); }
         /// arg_jsFunctionDefineCodes = "function jsFunctionTest( arg1, arg2 ) { var arg3 = arg1 + arg2; window.external.NotifyCSharpComplete( \" :\" + arg3 ); }";
         ///    arg_jsFunctionName = jsFunctionTest
         ///    123、456, arg_functionArgs = new object[] { 123, 456 }
         /// , object 。 object , 。 :stirng result = (string)Tool_webBrowser_ExecUserJSScript(...);
         /// </summary>
         /// <param name="arg_jsFunctionDefineCodes">js , , 1991( 2048, 。)</param>
         /// <param name="arg_jsFunctionName">js </param>
         /// <param name="arg_functionArgs">js 。 , , null, new object[]{}</param>
         /// <returns> 。 , 。 , js , NotifyCSharpComplete( msg ) NotifyCSharpComplete( null )</returns>
         private object Tool_webBrowser_ExecUserJSScript(string arg_jsFunctionDefineCodes, string arg_jsFunctionName, object[] arg_functionArgs = null)
         {
             this._returnObj_Tool_webBrowser_ExecUserJSScript = null;
             if (arg_jsFunctionDefineCodes.Length > 1991)
             {
                 throw new Exception(" :js 1991。");
             }
             //1. js 。
             arg_jsFunctionDefineCodes = "javascript:" + arg_jsFunctionDefineCodes + ";window.external.NotifyCSharpCompleteInit();";
             if (arg_jsFunctionDefineCodes.Length >= 2048)
             {
                 throw new Exception(" :js 2048( + )。");
             }
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Init = new AutoResetEvent(false);
             this.Invoke(new Action(() =>
             {
                 this.webBrowser.Navigate(arg_jsFunctionDefineCodes);
             }));
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Init.WaitOne();
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Init.Close();
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Init.Dispose();
             //2. js
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Exec = new AutoResetEvent(false);
             this.Invoke(new Action(() =>
             {
                 this.webBrowser.Document.InvokeScript(arg_jsFunctionName, arg_functionArgs);
             }));
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Exec.WaitOne();
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Exec.Close();
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Exec.Dispose();
             //3.
             return this._returnObj_Tool_webBrowser_ExecUserJSScript;
         }

         public void NotifyCSharpCompleteInit()
         {
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Init.Set();
         }

         public void NotifyCSharpComplete(object arg_obj)
         {
             this._returnObj_Tool_webBrowser_ExecUserJSScript = arg_obj;
             this._threadControlEvent_Tool_webBrowser_ExecUserJSScript_Exec.Set();
         }
         #endregion
용법 예 1:

string jsCmdTest = "function testFunction( msg ) { setTimeout(\"window.external.NotifyCSharpComplete(\\\" \\\");\", 5000);};";
object returnObj = this.Tool_webBrowser_ExecUserJSScript(jsCmdTest, "testFunction", new object[] {" "});
string returnStr = returnObj as string;
용법 예 2:

string jsCmdTest = "function testFunction( ) { var a = 122; var b = 244; var c = a + b; window.external.NotifyCSharpComplete(c);};";
object returnObj = this.Tool_webBrowser_ExecUserJSScript(jsCmdTest, "testFunction", null);
int returnInt = (int)returnObj;
용법 예 3:

string jsCmdTest = "function testFunction( ) { window.external.NotifyCSharpComplete(null);};";
object returnObj = this.Tool_webBrowser_ExecUserJSScript(jsCmdTest, "testFunction", null);
string result = "js ";
요약:웹 브 라 우 저 를 사용 하 는 두 가지 큰 문제:
1.WebBrowser 는 기기 의 IE 를 호출 하기 때문에 버 전,렌 더 링 프로그램 도 IE 의 버 전과 렌 더 링 프로그램 에 달 려 있 습 니 다.
2.WebBrowser 의 실행 js 등 많은 작업 은 비동기 적 이 고 이벤트 응답 이 없 으 며 실행 시간 을 스스로 추산 하여 기다 릴 수 밖 에 없습니다.또한 대기 시간 은 js 의 실제 실행 시간 보다 커 야 합 니 다.그렇지 않 으 면 후속 코드 에 문제 가 생 길 수 있 습 니 다.
3.현재 js 를 실행 하 는 방식 은 브 라 우 저의 주소 표시 줄 을 통 해서 만 가능 합 니 다.주소 표시 줄 은 길이 제한 이 있 습 니 다.

좋은 웹페이지 즐겨찾기