2

サイトを監視する目的で、IE を駆動する一連の WatiN テストを使用して定期的な健全性チェックを行っています。

スイートは、インタラクティブに呼び出すとき、および/またはタスク スケジューラでタスクを「ユーザーがログオンしているときのみ実行する」ように構成すると、正常に動作します。

ただし、「ユーザーがログオンしているかどうかに関係なく実行する」に設定し、「最高の特権で実行する」オプションをオンにすると (WatiN は、Windows Server 2008 やその他の多くの OS では、管理者権限がないとブラウザとうまく通信できません。特権)、WatiN は iexplore.exe インスタンスと十分に通信できません (それらは開始しますが、この投稿で詳しく説明されているようにタイムアウト例外が発生します))。IE の管理コンテキストと非管理コンテキストの両方について、ヒットしているサイトを信頼済みサイトに追加しました。昇格の有無、ESCの無効化の有無、インターネットゾーンの保護モードの有無を試しました。私の非 GUI テストは満足しているので、「最上位の権限で実行する」場合でも、非対話型のスケジュールされたタスクのコンテキストで可能な対話型の制限であると思います。

現時点での一時的な回避策は、[TS] セッションを常に開いたままにして、スケジュールされたタスクを実行できるようにすることです。

これに固執する場合は、少なくともハートビート通知を追加して、タスクが実際に実行されていることを監視できるようにします (たとえば、誰かがセッションをログオフしたり、ボックスを再起動した場合)。

ただし、より永続的なものを探しています-タスクスケジューラと同じように、Windows Server 2008 [x64]ボックスでWatiNテスト[xunit-console.x86.exe v 1.5を使用して実行]を定期的に呼び出すことができるものですが、適切なインタラクティブ セッションで。

可能であれば psexec や remcom を使用したくないので、Windows サービスを作成すると、別の障害点が追加される以外に何が起こるかわかりませんが、実証済みのすべてのソリューションについて知りたいです。

4

2 に答える 2

4

「ユーザーがログオンしているかどうかに関係なく実行」モードでスケジュールされたタスクを使用して、Watin テストを実行できました。私の場合、ログオンしているユーザーなしで実行されているスケジュールされたタスクからIEが作成された場合、m_Proc.MainWindowHandleが常に0になるまで問題を追跡しました。Watin ソースでは、これは IE.cs:CreateIEPartiallyInitializedInNewProcess 関数にあります。

私の回避策は、最上位のウィンドウを手動で列挙し、Process.MainWindowHandle プロパティを使用する代わりに、プロセスに属する className == "IEFrame" を持つウィンドウを見つけることです。

これがコードスニペットです。すべての 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);
        }
    }

次に、 new IE() の代わりに IEBrowserHelper.CreateIEBrowser() を使用します

于 2012-03-06T11:16:12.800 に答える
0

コマンド プロンプトから、次のような対話型タスクをスケジュールできます。

C:\Users\someUser>schtasks /create /sc once /st 16:28 /tn someTask /tr cmd.exe

... ここで、sc はスケジュール、st は開始時刻、tn は選択したタスク名 (何でもかまいません)、tr は実行するコマンドです。明らかに、定期的なタスクの場合は、sc を月単位、週単位などに変更します。「schtasks /create /?」と入力するだけです。詳細については。

于 2012-01-05T22:41:29.100 に答える