Skip to content

Commit 72adb79

Browse files
committed
Add support for Chrome 138
1 parent ad2bb0f commit 72adb79

File tree

1 file changed

+57
-23
lines changed

1 file changed

+57
-23
lines changed

ProxyDialogAutoFiller/ProxyDialogAutoFiller.cs

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ This Source Code Form is subject to the terms of the Mozilla Public
77
*/
88
using System;
99
using System.Diagnostics;
10+
using System.Diagnostics.Contracts;
1011
using System.Linq;
1112
using System.Threading.Tasks;
1213
using 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);
@@ -57,6 +58,7 @@ internal static void PrintControlIdentifiers(RuntimeContext context, AutomationE
5758
{
5859
var ind = new string(' ', indent * 2);
5960
Console.WriteLine($"{ind}- {element.Current.ControlType.ProgrammaticName} : {element.Current.Name}");
61+
context.Logger.Log($"{ind}- {element.Current.ControlType.ProgrammaticName} : {element.Current.Name}");
6062
var children = element.FindAll(TreeScope.Children, Condition.TrueCondition);
6163
foreach (AutomationElement child in children)
6264
{
@@ -75,41 +77,51 @@ private static void SendValue(AutomationElement element, string value)
7577
object valuePatternObj;
7678
if (element.TryGetCurrentPattern(ValuePattern.Pattern, out valuePatternObj))
7779
{
78-
element.SetFocus();
7980
(valuePatternObj as ValuePattern).SetValue(value);
8081
}
8182
else
8283
{
8384
// フォーカス後にSendKeys(WinFormsやWPF参照)などで文字列を入力
84-
element.SetFocus();
85+
try
86+
{
87+
element.SetFocus();
88+
}
89+
catch
90+
{
91+
// ignore set focus error
92+
}
8593
System.Windows.Forms.SendKeys.SendWait(value);
8694
}
8795
}
8896

8997
internal static void LoginToProxy(RuntimeContext context, AutomationElement targetRootElement, TargetDefinition dialogDefinition)
9098
{
91-
if(context.Config.SectionList == null || context.Config.SectionList.Count == 0)
99+
if (context.Config.SectionList == null || context.Config.SectionList.Count == 0)
92100
{
101+
context.Logger.Log($"Empty config.");
93102
return;
94103
}
95104
try
96105
{
97106
var proxyDialogNameCondition = new PropertyCondition(AutomationElement.NameProperty, dialogDefinition.DialogTitleName);
107+
var targetControlTypeCondition = new OrCondition(
108+
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window),
109+
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Pane));
98110
var proxyDialogCondition = new AndCondition(
99111
proxyDialogNameCondition,
100-
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
101-
var proxyDialogElement = targetRootElement.FindFirst(TreeScope.Descendants, proxyDialogCondition);
112+
targetControlTypeCondition);
113+
var proxyDialogElement = targetRootElement.FindFirst(TreeScope.Subtree, proxyDialogCondition);
102114
if (proxyDialogElement == null)
103115
{
104116
return;
105117
}
106118
context.Logger.Log($"Found proxy dialog.");
107-
var textTypeDescendants = proxyDialogElement.FindAll(TreeScope.Descendants, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text));
119+
var textTypeDescendants = proxyDialogElement.FindAll(TreeScope.Subtree, new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Text));
108120

109121
bool isTargetProxy = false;
110122
string userName = "";
111123
string password = "";
112-
foreach(AutomationElement textTypeDescendant in textTypeDescendants)
124+
foreach (AutomationElement textTypeDescendant in textTypeDescendants)
113125
{
114126
string name = textTypeDescendant.Current.Name;
115127
if (!string.IsNullOrEmpty(name) && name.Contains("プロキシ"))
@@ -139,54 +151,70 @@ internal static void LoginToProxy(RuntimeContext context, AutomationElement targ
139151
{
140152
return;
141153
}
142-
154+
context.Logger.Log($"Found proxy dialog matching to config.");
143155
var userNameEditCondition = new AndCondition(
144156
new PropertyCondition(AutomationElement.NameProperty, dialogDefinition.UserNameInputName),
145157
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
146-
var userNameEditElement = proxyDialogElement.FindFirst(TreeScope.Descendants, userNameEditCondition);
158+
var userNameEditElement = proxyDialogElement.FindFirst(TreeScope.Subtree, userNameEditCondition);
147159
if (userNameEditElement == null)
148160
{
161+
context.Logger.Log($"User name edit not found.");
149162
return;
150163
}
151164
SendValue(userNameEditElement, userName);
152165

166+
context.Logger.Log($"Set username.");
153167
var passwordEditCondition = new AndCondition(
154168
new PropertyCondition(AutomationElement.NameProperty, dialogDefinition.PasswordInputName),
155169
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
156-
var passwordEditElement = proxyDialogElement.FindFirst(TreeScope.Descendants, passwordEditCondition);
170+
var passwordEditElement = proxyDialogElement.FindFirst(TreeScope.Subtree, passwordEditCondition);
157171
if (passwordEditElement == null)
158172
{
173+
context.Logger.Log($"Password edit not found.");
159174
return;
160175
}
161176
SendValue(passwordEditElement, password);
162-
177+
context.Logger.Log($"Set password.");
163178
var loginButtonNameCondition = new PropertyCondition(AutomationElement.NameProperty, dialogDefinition.LoginButtonName);
164179
var loginButtonCondition = new AndCondition(
165180
loginButtonNameCondition,
166181
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
167-
var loginButtonElement = proxyDialogElement.FindFirst(TreeScope.Descendants, loginButtonCondition);
182+
var loginButtonElement = proxyDialogElement.FindFirst(TreeScope.Subtree, loginButtonCondition);
168183
if (loginButtonElement == null)
169184
{
185+
context.Logger.Log($"Login button not found.");
170186
return;
171187
}
172188
InvokePattern loginButton = loginButtonElement.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
173189
if (loginButton == null)
174190
{
175191
return;
176192
}
193+
177194
Task.Delay(50).Wait();
178195
loginButton.Invoke();
179196
context.Logger.Log($"Click login button.");
197+
180198
// プロキシーダイアログが消えていることを確認する。
181199
// ユーザー名、パスワードに誤りがあった場合などに、短時間で連続してダイアログの表示とOKが繰り返され、ユーザーが対処できなくなる可能性がある。
182200
// そのため、ダイアログが表示されている場合、ここで15秒間待機し、ダイアログが閉じられなかった場合にユーザーがキャンセルや正しいユーザー名
183201
// パスワードが入力できるようにする。
202+
bool isProxyDialogClosed = false;
184203
for (int i = 0; i < 30; i++)
185204
{
186205
Task.Delay(500).Wait();
187-
proxyDialogElement = targetRootElement.FindFirst(TreeScope.Descendants, proxyDialogCondition);
188-
if (proxyDialogElement == null)
206+
// ログインボタンが消えていたらダイアログも消えていると判断する。
207+
// このあとログインボタンを押すことから、ログインボタンを再利用している。
208+
try
189209
{
210+
_ = loginButtonElement.Current.ItemType;
211+
_ = loginButtonElement.Current.Name;
212+
_ = loginButtonElement.Current.IsOffscreen;
213+
}
214+
catch
215+
{
216+
context.Logger.Log($"login button closed.");
217+
isProxyDialogClosed = true;
190218
break;
191219
}
192220
// ChromeでloginButton.Invoke()の実行までが早すぎて応答しないことがあるので
@@ -198,17 +226,23 @@ internal static void LoginToProxy(RuntimeContext context, AutomationElement targ
198226
loginButton.Invoke();
199227
context.Logger.Log($"Retry to click login button.");
200228
}
201-
catch { }
229+
catch
230+
{
231+
// ログインボタンのInvokeに失敗した場合、ログインボタンが消えていると判断してループを抜ける。
232+
context.Logger.Log($"Failed to invoke button");
233+
isProxyDialogClosed = true;
234+
break;
235+
}
202236
}
203237
}
204238

205-
if (proxyDialogElement != null)
239+
if (isProxyDialogClosed)
206240
{
207-
context.Logger.Log($"Dialog not closed. Maybe failed to login to the proxy.");
241+
context.Logger.Log($"Success to login to the proxy.");
208242
}
209243
else
210244
{
211-
context.Logger.Log($"Success to login to the proxy.");
245+
context.Logger.Log($"Dialog not closed. Maybe failed to login to the proxy.");
212246
}
213247
}
214248
catch (Exception ex)

0 commit comments

Comments
 (0)