我正在使用一套WatiN测试来驱动IE进行一些定期的健全性检查,以便监控网站。
当我以交互方式调用它时和/或当我将任务计划程序中的任务配置为“仅在用户登录时运行”时,套件工作正常。
但是,当我将其设置为“运行用户是否登录时”,并选中“以最高权限运行”选项(WatiN无法在Windows Server 2008和许多其他操作系统下令人满意地与浏览器通信没有管理员权限),WatiN无法令人满意地与它的iexplore.exe实例通信(它们开始,但我得到timeout exception as detailed in this post)。我已经为IE的管理和非管理上下文添加了我要访问可信站点的站点。无论有没有高程,我都尝试过,无论是否禁用ESC,并且有和没有关闭互联网区域的保护模式。由于我的非GUI测试很满意,我认为这是在非交互式计划任务的上下文中可能的交互类型的限制,即使“以最高权限运行”。
目前,我的临时解决方法是要求[TS]会话始终保持打开状态,准备好运行计划任务。
如果我坚持这一点,我至少会添加一个心跳通知,以允许某些事情监视该任务实际上正在运行[例如,如果有人记录会话或重新启动该框]。 / p>
然而,我正在寻找更永久的东西 - 能够在我的Windows Server 2008 [x64]框上定期调用我的WatiN测试[使用xunit-console.x86.exe v 1.5运行],就像任务计划程序,但具有适当的交互式会话。
如果可能的话,我不想使用psexec或remcom,并且无法看到创建Windows服务除了添加其他故障点之外还会做什么,但我有兴趣听到所有经过验证的解决方案
答案 0 :(得分:4)
我能够在"运行中使用预定任务运行Watin测试,无论用户是否登录"模式。 在我的情况下,当从没有登录用户运行的计划任务创建IE时,我跟踪问题,m_Proc.MainWindowHandle始终为0。 在Watin源代码中,这是在IE.cs中:CreateIEPartiallyInitializedInNewProcess函数
我的解决方法是手动枚举顶级窗口并找到一个带有className ==" IEFrame"的窗口。属于该进程,而不是使用Process.MainWindowHandle属性。
以下是代码段。所有的pinvoke我直接从Watin源复制。
public static class IEBrowserHelper
{
private static Process CreateIExploreInNewProcess()
{
var arguments = "about:blank";
arguments = "-noframemerging " + arguments;
var m_Proc = Process.Start("IExplore.exe", arguments);
if (m_Proc == null) throw new WatiN.Core.Exceptions.WatiNException("Could not start IExplore.exe process");
return m_Proc;
}
class IeWindowFinder
{
#region Interop
[DllImport("user32.dll", SetLastError = true)]
static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam);
[DllImport("user32.dll", SetLastError = true)]
public static extern bool EnumWindows(EnumWindowsProc lpEnumFunc, IntPtr lParam);
[DllImport("user32", EntryPoint = "GetClassNameA", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
internal static extern int GetClassName(IntPtr handleToWindow, StringBuilder className, int maxClassNameLength);
#endregion
readonly Process IeProcess;
IntPtr HWnd = IntPtr.Zero;
public IeWindowFinder(Process ieProcess)
{
this.IeProcess = ieProcess;
}
public IntPtr Find()
{
EnumWindows(FindIeWindowCallback, IntPtr.Zero);
return HWnd;
}
bool FindIeWindowCallback(IntPtr hWnd, IntPtr lParam)
{
uint processId;
GetWindowThreadProcessId(hWnd, out processId);
if (processId == IeProcess.Id)
{
int maxCapacity = 255;
var sbClassName = new StringBuilder(maxCapacity);
var lRes = GetClassName(hWnd, sbClassName, maxCapacity);
string className = lRes == 0 ? String.Empty : sbClassName.ToString();
if (className == "IEFrame")
{
this.HWnd = hWnd;
return false;
}
}
return true;
}
}
public static WatiN.Core.IE CreateIEBrowser()
{
Process ieProcess = CreateIExploreInNewProcess();
IeWindowFinder findWindow = new IeWindowFinder(ieProcess);
var action = new WatiN.Core.UtilityClasses.TryFuncUntilTimeOut(TimeSpan.FromSeconds(WatiN.Core.Settings.AttachToBrowserTimeOut))
{
SleepTime = TimeSpan.FromMilliseconds(500)
};
IntPtr hWnd = action.Try(() =>
{
return findWindow.Find();
});
ieProcess.Refresh();
return WatiN.Core.IE.AttachTo<WatiN.Core.IE>(
new WatiN.Core.Constraints.AttributeConstraint("hwnd", hWnd.ToString()), 5);
}
}
然后使用IEBrowserHelper.CreateIEBrowser()
而不是新的IE()答案 1 :(得分:0)
在命令提示符下,您可以安排如下的交互式任务:
C:\Users\someUser>schtasks /create /sc once /st 16:28 /tn someTask /tr cmd.exe
...其中sc是计划,st是开始时间,tn是您选择的任务名称(可以是任何内容),tr是您要运行的命令。显然,对于重复性任务,您可以将sc更改为每月,每周等。只需键入“schtasks / create /?”即可。了解更多信息。