Windows 7 WatiN LogonDialogHandler在Windows 7中无法正常工作
我最近更新了Windows7、VS2010和IE8。我们有一个自动化套件,使用WatiN对IE进行测试。这些测试需要使用登录对话框处理程序,以便将不同的AD用户登录到IE浏览器中 这在使用Windows XP和IE8时非常有效,但现在使用Windows 7导致Windows安全对话框不再被识别,对话框被忽略。这是用于启动浏览器的方法:Windows 7 WatiN LogonDialogHandler在Windows 7中无法正常工作,windows-7,watin,Windows 7,Watin,我最近更新了Windows7、VS2010和IE8。我们有一个自动化套件,使用WatiN对IE进行测试。这些测试需要使用登录对话框处理程序,以便将不同的AD用户登录到IE浏览器中 这在使用Windows XP和IE8时非常有效,但现在使用Windows 7导致Windows安全对话框不再被识别,对话框被忽略。这是用于启动浏览器的方法: public static Browser StartBrowser(string url, string username, string pa
public static Browser StartBrowser(string url, string username, string password)
{
Browser browser = new IE();
WatiN.Core.DialogHandlers.LogonDialogHandler ldh = new WatiN.Core.DialogHandlers.LogonDialogHandler(username, password);
browser.DialogWatcher.Add(ldh);
browser.GoTo(url);
return browser;
}
如果您有任何建议或帮助,我将不胜感激……因为没有人回答您的问题,我会的,但不幸的是没有现成的解决方案
目前我没有Windows 7可供尝试,但WatiN的
LogonDialogHandler
似乎与Windows 7不兼容,因此您必须编写自己的DialogHandler
。最简单的方法是从BaseDialogHandler
继承。您可以查看WatiN中现有对话框处理程序的源代码。我让自己变得非常简单,而不是通用的处理方式。在实现过程中非常有用。我们最终解决了这个问题,使用Windows Automation 3.0 API打开对话框并处理登录。具体做法如下:
public static Browser LoginToBrowser(string UserName, string Password, string URL)
{
AutomationElement element = StartApplication("IEXPLORE.EXE", URL);
Thread.Sleep(2000);
string t = element.Current.ClassName.ToString();
Condition conditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
Condition List_condition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem));
Condition Edit_condition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
Condition button_conditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
AutomationElementCollection c = element.FindAll(TreeScope.Children, conditions);
foreach (AutomationElement child in c)
{
if (child.Current.ClassName.ToString() == "#32770")
{
//find the list
AutomationElementCollection lists = child.FindAll(TreeScope.Children, List_condition);
// find the buttons
AutomationElementCollection buttons = child.FindAll(TreeScope.Children, button_conditions);
foreach (AutomationElement list in lists)
{
if (list.Current.ClassName.ToString() == "UserTile")
{
AutomationElementCollection edits = list.FindAll(TreeScope.Children, Edit_condition);
foreach (AutomationElement edit in edits)
{
if (edit.Current.Name.Contains("User name"))
{
edit.SetFocus();
//send the user name
}
if (edit.Current.Name.Contains("Password"))
{
edit.SetFocus();
//send the password
}
}
}
}
foreach (AutomationElement button in buttons)
{
if (button.Current.AutomationId == "SubmitButton")
{
//click the button
break;
}
}
}
}
return IE.AttachToIE(Find.By("hwnd", element.Current.NativeWindowHandle.ToString()), 30) ;
}
我们确实使用了一个名为UI Spy的工具来检查Windows UI。如果您在XP和Win7上运行它,您可以清楚地看到Windows安全对话框的结构在两个操作系统之间是如何变化的。如果您将运行watin的任何进程设置为在Windows 7中以管理员身份运行,则对话框处理程序工作正常 无论出于何种原因,Clint发布的代码都有注释,而不是输入用户名、密码和提交,并且引用了未定义的方法,但在其他方面是可以的。以下是一些已完成(和工作)的代码:
公共静态浏览器Win7Login(字符串用户名、字符串密码、字符串URL){
Process ieProcess=Process.Start(“iexplore.exe”,URL);
ieProcess.WaitForInputIdle();
《睡眠》(2000年);
AutomationElement ieWindow=AutomationElement.FromHandle(ieProcess.MainWindowHandle);
字符串t=ieWindow.Current.ClassName.ToString();
条件条件=新AND条件(新属性条件(AutomationElement.IsEnabledProperty,true),
新属性条件(AutomationElement.ControlTypeProperty、ControlType.Window);
条件列表_Condition=new和Condition(新属性条件(AutomationElement.IsEnabledProperty,true),
新属性条件(AutomationElement.ControlTypeProperty、ControlType.ListItem));
条件编辑_Condition=new and条件(新属性条件(AutomationElement.IsEnabledProperty,true),
新属性条件(AutomationElement.ControlTypeProperty、ControlType.Edit));
条件按钮\u条件=新建和条件(新属性条件(AutomationElement.IsEnabledProperty,true),
新属性条件(AutomationElement.ControlTypeProperty、ControlType.Button));
AutomationElementCollection c=ieWindow.FindAll(TreeScope.Children,conditions);
foreach(c中的AutomationElement子级){
if(child.Current.ClassName.ToString()==“#32770”){
//查找列表
AutomationElementCollection列表=child.FindAll(TreeScope.Children,列表条件);
//找到按钮
AutomationElementCollection按钮=child.FindAll(TreeScope.Children,按钮条件);
foreach(列表中的AutomationElement列表){
if(list.Current.ClassName.ToString()=“UserTile”){
AutomationElementCollection编辑=list.FindAll(TreeScope.Children,编辑条件);
foreach(编辑中的AutomationElement编辑){
if(edit.Current.Name.Contains(“用户名”)){
edit.SetFocus();
ValuePattern usernamePattern=edit.GetCurrentPattern(ValuePattern.Pattern)作为ValuePattern;
usernamePattern.SetValue(用户名);
}
if(edit.Current.Name.Contains(“密码”)){
edit.SetFocus();
ValuePattern passwordPattern=edit.GetCurrentPattern(ValuePattern.Pattern)作为ValuePattern;
passwordPattern.SetValue(密码);
}
}
}
}
foreach(按钮中的AutomationElement按钮){
如果(button.Current.AutomationId==“SubmitButton”){
InvokePattern submitPattern=button.GetCurrentPattern(InvokePattern.Pattern)作为InvokePattern;
submitPattern.Invoke();
打破
}
}
}
}
返回IE.AttachTo(Find.By(“hwnd”,ieWindow.Current.NativeWindowHandle.ToString()),30);
}
尼古拉斯·莱利·波斯特(Nicholas Riley post)很有魅力,但是包括使用System.Windows.Automation可能有点棘手。我原以为微软会把这个放进GAC,但他们没有,至少对我运行Windows7 professional来说是这样。我甚至从下载了自动化工具包
事实证明,在堆栈溢出上有一个主题显示w
public static Browser Win7Login(string username, string password, string URL) {
Process ieProcess = Process.Start("iexplore.exe", URL);
ieProcess.WaitForInputIdle();
Thread.Sleep(2000);
AutomationElement ieWindow = AutomationElement.FromHandle(ieProcess.MainWindowHandle);
string t = ieWindow.Current.ClassName.ToString();
Condition conditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
Condition List_condition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem));
Condition Edit_condition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
Condition button_conditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
AutomationElementCollection c = ieWindow.FindAll(TreeScope.Children, conditions);
foreach (AutomationElement child in c) {
if (child.Current.ClassName.ToString() == "#32770") {
// find the list
AutomationElementCollection lists = child.FindAll(TreeScope.Children, List_condition);
// find the buttons
AutomationElementCollection buttons = child.FindAll(TreeScope.Children, button_conditions);
foreach (AutomationElement list in lists) {
if (list.Current.ClassName.ToString() == "UserTile") {
AutomationElementCollection edits = list.FindAll(TreeScope.Children, Edit_condition);
foreach (AutomationElement edit in edits) {
if (edit.Current.Name.Contains("User name")) {
edit.SetFocus();
ValuePattern usernamePattern = edit.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
usernamePattern.SetValue(username);
}
if (edit.Current.Name.Contains("Password")) {
edit.SetFocus();
ValuePattern passwordPattern = edit.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
passwordPattern.SetValue(password);
}
}
}
}
foreach (AutomationElement button in buttons) {
if (button.Current.AutomationId == "SubmitButton") {
InvokePattern submitPattern = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
submitPattern.Invoke();
break;
}
}
}
}
return IE.AttachTo<IE>(Find.By("hwnd", ieWindow.Current.NativeWindowHandle.ToString()), 30);
}
public static Browser Win7Login(string username, string password, string url)
{
var ieProcess = Process.Start("iexplore.exe", url);
ieProcess.WaitForInputIdle();
Thread.Sleep(2000);
var ieWindow = AutomationElement.FromHandle(ieProcess.MainWindowHandle);
var conditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
var listCondition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem));
var editCondition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
var buttonConditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
var c = ieWindow.FindAll(TreeScope.Children, conditions);
foreach (AutomationElement child in c)
{
if (child.Current.ClassName == "#32770")
{
// find the list
var lists = child.FindAll(TreeScope.Children, listCondition);
// find the buttons
var buttons = child.FindAll(TreeScope.Children, buttonConditions);
var another = (from AutomationElement list in lists
where list.Current.ClassName == "UserTile"
where list.Current.Name == "Use another account"
select list).First();
another.SetFocus();
foreach (var edit in from AutomationElement list in lists
where list.Current.ClassName == "UserTile"
select list.FindAll(TreeScope.Children, editCondition)
into edits from AutomationElement edit in edits select edit)
{
if (edit.Current.Name.Contains("User name"))
{
edit.SetFocus();
var usernamePattern = edit.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
if (usernamePattern != null) usernamePattern.SetValue(username);
}
if (edit.Current.Name.Contains("Password"))
{
edit.SetFocus();
var passwordPattern = edit.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
if (passwordPattern != null) passwordPattern.SetValue(password);
}
}
foreach (var submitPattern in from AutomationElement button in buttons
where button.Current.AutomationId == "SubmitButton"
select button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern)
{
submitPattern.Invoke();
break;
}
}
}
return IE.AttachTo<IE>(Find.By("hwnd", ieWindow.Current.NativeWindowHandle.ToString()), 30);
}
public class Windows7LogonDialogHandler : BaseDialogHandler
{
private readonly string _username;
private readonly string _password;
AndCondition _conditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Window));
readonly AndCondition _listCondition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.ListItem));
readonly AndCondition _editCondition = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Edit));
readonly AndCondition _buttonConditions = new AndCondition(new PropertyCondition(AutomationElement.IsEnabledProperty, true),
new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button));
public Windows7LogonDialogHandler(string username, string password)
{
_username = username;
_password = password;
}
public override bool HandleDialog(Window window)
{
if(CanHandleDialog(window))
{
var win = AutomationElement.FromHandle(window.Hwnd);
var lists = win.FindAll(TreeScope.Children, _listCondition);
var buttons = win.FindAll(TreeScope.Children, _buttonConditions);
var another = (from AutomationElement list in lists
where list.Current.ClassName == "UserTile"
where list.Current.Name == "Use another account"
select list).First();
another.SetFocus();
foreach (var edit in from AutomationElement list in lists
where list.Current.ClassName == "UserTile"
select list.FindAll(TreeScope.Children, _editCondition)
into edits
from AutomationElement edit in edits
select edit)
{
if (edit.Current.Name.Contains("User name"))
{
edit.SetFocus();
var usernamePattern = edit.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
if (usernamePattern != null) usernamePattern.SetValue(_username);
}
if (edit.Current.Name.Contains("Password"))
{
edit.SetFocus();
var passwordPattern = edit.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
if (passwordPattern != null) passwordPattern.SetValue(_password);
}
}
foreach (var submitPattern in from AutomationElement button in buttons
where button.Current.AutomationId == "SubmitButton"
select button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern)
{
submitPattern.Invoke();
break;
}
return true;
}
return false;
}
public override bool CanHandleDialog(Window window)
{
return window.ClassName == "#32770";
}
}
using(var ie = new IE())
{
ie.DialogWatcher.Add(new Windows7LogonDialogHandler(@"domain\user", "password"));
ie.GoTo("http://mysecuredwebsite");
}