@@ -7,6 +7,7 @@ This Source Code Form is subject to the terms of the Mozilla Public
77*/
88using System ;
99using System . Diagnostics ;
10+ using System . Diagnostics . Contracts ;
1011using System . Linq ;
1112using System . Threading . Tasks ;
1213using System . Windows . Automation ;
@@ -30,16 +31,16 @@ internal static void WatchDialog(RuntimeContext context)
3031 {
3132 foreach ( var targetDefinition in targetDefinitions )
3233 {
33- var filteredElements = Process . GetProcessesByName ( targetDefinition . ProcessName ) ;
34+ //ブラウザのプロセスのうち、メインウィンドウがあるものに絞り込み
35+ var filteredElements = Process . GetProcessesByName ( targetDefinition . ProcessName ) . Where ( _ => _ . MainWindowHandle != IntPtr . Zero ) ;
36+
3437 foreach ( var filteredElement in filteredElements )
3538 {
3639 var targetPid = filteredElement . Id ;
37- var windowCondition = new AndCondition (
38- new PropertyCondition ( AutomationElement . ProcessIdProperty , targetPid ) ,
39- new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Window ) ) ;
40- var targetElement = desktop . FindFirst ( TreeScope . Children , windowCondition ) ;
40+ var targetElement = desktop . FindFirst ( TreeScope . Children , new PropertyCondition ( AutomationElement . ProcessIdProperty , targetPid ) ) ;
4141 if ( targetElement == null )
4242 {
43+ context . Logger . Log ( $ "Empty element.") ;
4344 continue ;
4445 }
4546 PrintControlIdentifiers ( context , targetElement , 0 ) ;
@@ -75,30 +76,40 @@ private static void SendValue(AutomationElement element, string value)
7576 object valuePatternObj ;
7677 if ( element . TryGetCurrentPattern ( ValuePattern . Pattern , out valuePatternObj ) )
7778 {
78- element . SetFocus ( ) ;
7979 ( valuePatternObj as ValuePattern ) . SetValue ( value ) ;
8080 }
8181 else
8282 {
8383 // フォーカス後にSendKeys(WinFormsやWPF参照)などで文字列を入力
84- element . SetFocus ( ) ;
84+ try
85+ {
86+ element . SetFocus ( ) ;
87+ }
88+ catch
89+ {
90+ // ignore set focus error
91+ }
8592 System . Windows . Forms . SendKeys . SendWait ( value ) ;
8693 }
8794 }
8895
8996 internal static void LoginToProxy ( RuntimeContext context , AutomationElement targetRootElement , TargetDefinition dialogDefinition )
9097 {
91- if ( context . Config . SectionList == null || context . Config . SectionList . Count == 0 )
98+ if ( context . Config . SectionList == null || context . Config . SectionList . Count == 0 )
9299 {
100+ context . Logger . Log ( $ "Empty config.") ;
93101 return ;
94102 }
95103 try
96104 {
97105 var proxyDialogNameCondition = new PropertyCondition ( AutomationElement . NameProperty , dialogDefinition . DialogTitleName ) ;
106+ var targetControlTypeCondition = new OrCondition (
107+ new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Window ) ,
108+ new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Custom ) ) ;
98109 var proxyDialogCondition = new AndCondition (
99- proxyDialogNameCondition ,
100- new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Window ) ) ;
101- var proxyDialogElement = targetRootElement . FindFirst ( TreeScope . Descendants , proxyDialogCondition ) ;
110+ targetControlTypeCondition ,
111+ proxyDialogNameCondition ) ;
112+ var proxyDialogElement = targetRootElement . FindFirst ( TreeScope . Subtree , proxyDialogCondition ) ;
102113 if ( proxyDialogElement == null )
103114 {
104115 return ;
@@ -109,7 +120,7 @@ internal static void LoginToProxy(RuntimeContext context, AutomationElement targ
109120 bool isTargetProxy = false ;
110121 string userName = "" ;
111122 string password = "" ;
112- foreach ( AutomationElement textTypeDescendant in textTypeDescendants )
123+ foreach ( AutomationElement textTypeDescendant in textTypeDescendants )
113124 {
114125 string name = textTypeDescendant . Current . Name ;
115126 if ( ! string . IsNullOrEmpty ( name ) && name . Contains ( "プロキシ" ) )
@@ -139,56 +150,81 @@ internal static void LoginToProxy(RuntimeContext context, AutomationElement targ
139150 {
140151 return ;
141152 }
142-
153+ context . Logger . Log ( $ "Found proxy dialog matching to config." ) ;
143154 var userNameEditCondition = new AndCondition (
144155 new PropertyCondition ( AutomationElement . NameProperty , dialogDefinition . UserNameInputName ) ,
145156 new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Edit ) ) ;
146157 var userNameEditElement = proxyDialogElement . FindFirst ( TreeScope . Descendants , userNameEditCondition ) ;
147158 if ( userNameEditElement == null )
148159 {
160+ context . Logger . Log ( $ "User name edit not found.") ;
149161 return ;
150162 }
151163 SendValue ( userNameEditElement , userName ) ;
152164
165+ context . Logger . Log ( $ "Set username.") ;
153166 var passwordEditCondition = new AndCondition (
154167 new PropertyCondition ( AutomationElement . NameProperty , dialogDefinition . PasswordInputName ) ,
155168 new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Edit ) ) ;
156169 var passwordEditElement = proxyDialogElement . FindFirst ( TreeScope . Descendants , passwordEditCondition ) ;
157170 if ( passwordEditElement == null )
158171 {
172+ context . Logger . Log ( $ "Password edit not found.") ;
159173 return ;
160174 }
161175 SendValue ( passwordEditElement , password ) ;
162-
176+ context . Logger . Log ( $ "Set password." ) ;
163177 var loginButtonNameCondition = new PropertyCondition ( AutomationElement . NameProperty , dialogDefinition . LoginButtonName ) ;
164178 var loginButtonCondition = new AndCondition (
165179 loginButtonNameCondition ,
166180 new PropertyCondition ( AutomationElement . ControlTypeProperty , ControlType . Button ) ) ;
167181 var loginButtonElement = proxyDialogElement . FindFirst ( TreeScope . Descendants , loginButtonCondition ) ;
168182 if ( loginButtonElement == null )
169183 {
184+ context . Logger . Log ( $ "Login button not found.") ;
170185 return ;
171186 }
172187 InvokePattern loginButton = loginButtonElement . GetCurrentPattern ( InvokePattern . Pattern ) as InvokePattern ;
173188 if ( loginButton == null )
174189 {
175190 return ;
176191 }
192+
177193 Task . Delay ( 50 ) . Wait ( ) ;
178194 loginButton . Invoke ( ) ;
179195 context . Logger . Log ( $ "Click login button.") ;
196+
180197 // プロキシーダイアログが消えていることを確認する。
181198 // ユーザー名、パスワードに誤りがあった場合などに、短時間で連続してダイアログの表示とOKが繰り返され、ユーザーが対処できなくなる可能性がある。
182199 // そのため、ダイアログが表示されている場合、ここで15秒間待機し、ダイアログが閉じられなかった場合にユーザーがキャンセルや正しいユーザー名
183200 // パスワードが入力できるようにする。
201+ bool isProxyDialogClosed = false ;
184202 for ( int i = 0 ; i < 30 ; i ++ )
185203 {
186204 Task . Delay ( 500 ) . Wait ( ) ;
205+ // ログインボタンが消えていたらダイアログも消えていると判断する。
187206 proxyDialogElement = targetRootElement . FindFirst ( TreeScope . Descendants , proxyDialogCondition ) ;
188207 if ( proxyDialogElement == null )
189208 {
209+ context . Logger . Log ( $ "Proxy dialog not found.") ;
210+ isProxyDialogClosed = true ;
211+ break ;
212+ }
213+ loginButtonElement = proxyDialogElement . FindFirst ( TreeScope . Descendants , loginButtonCondition ) ;
214+ if ( loginButtonElement == null )
215+ {
216+ context . Logger . Log ( $ "Login button not found.") ;
217+ isProxyDialogClosed = true ;
218+ break ;
219+ }
220+ loginButton = loginButtonElement . GetCurrentPattern ( InvokePattern . Pattern ) as InvokePattern ;
221+ if ( loginButton == null )
222+ {
223+ context . Logger . Log ( $ "Cannot cast to InvokePattern.") ;
224+ isProxyDialogClosed = true ;
190225 break ;
191226 }
227+
192228 // ChromeでloginButton.Invoke()の実行までが早すぎて応答しないことがあるので
193229 // ここで二回までリトライする。
194230 if ( i < 2 )
@@ -198,17 +234,23 @@ internal static void LoginToProxy(RuntimeContext context, AutomationElement targ
198234 loginButton . Invoke ( ) ;
199235 context . Logger . Log ( $ "Retry to click login button.") ;
200236 }
201- catch { }
237+ catch
238+ {
239+ // ログインボタンのInvokeに失敗した場合、ログインボタンが消えていると判断してループを抜ける。
240+ context . Logger . Log ( $ "Failed to invoke button") ;
241+ isProxyDialogClosed = true ;
242+ break ;
243+ }
202244 }
203245 }
204246
205- if ( proxyDialogElement != null )
247+ if ( isProxyDialogClosed )
206248 {
207- context . Logger . Log ( $ "Dialog not closed. Maybe failed to login to the proxy.") ;
249+ context . Logger . Log ( $ "Success to login to the proxy.") ;
208250 }
209251 else
210252 {
211- context . Logger . Log ( $ "Success to login to the proxy.") ;
253+ context . Logger . Log ( $ "Dialog not closed. Maybe failed to login to the proxy.") ;
212254 }
213255 }
214256 catch ( Exception ex )
0 commit comments