UIA问题(非常奇怪)

灯塔麦克

新成员
已加入
2020年7月20日
留言内容
2
编程经验
5-10
嘿,

我一直在从事一个自动化"Save As"对话框作为自动下载过程的一部分,我认为最好使用UIA(又称UIA)。"Microsoft UI自动化",而不是模拟AutoHotKey样式的击键。我以前曾经这样做过(在C / Win32中),并且可以工作,但是我认为UIA可能更可靠。同时,需求发生了变化,因此我现在使用C#(大声笑)。无论如何,我一直在与一个没有逻辑解释的怪异错误作斗争(基于我的小小的大脑对.NET内部工作原理的有限理解,哈哈)。从Visual Studio(VS 2017,在Windows 10上)运行时,我的程序运行完美,而从PowerShell / CMD运行时,部分运行良好。但是,当不使用VS时,程序将崩溃且没有堆栈跟踪。调试与发布模式似乎无关紧要,但是它只能在Visual Studio中使用(在两种模式下都可以)。当它崩溃时(在任何一种模式下),都没有"该程序已停止工作",不会在stdout或stderr上打印任何文本,并且绝对没有任何指示导致问题的原因。 try / catch块不能捕获它,将输​​出管道传输到文件不会显示任何新信息,并且我也无法在interwebz上挖掘任何可用信息。

But the random doesn't stop there. When I run it from PowerShell, then bring up the 另存为 dialog in Notepad, it not only crashes my program, but also PowerShell and Notepad! Returning to Visual Studio, if I try to re-compile my code, I get an error:

严重性:错误
说明:无法复制文件"obj \ Debug \ download.exe" to "bin \ Debug \ download.exe". Access to the path 'bin \ Debug \ download.exe' is denied.
项目:下载
所有其他字段为空白/空。

这是代码,我在经历了这场噩梦之后尝试了不同的方式时发表了所有评论:
让我更喜欢Linux了:
/// <summary>
    /// Automates the "Save As" dialog
    /// </summary>
    /// <param name="path">The path</param>
    /// <param name="file">The file name</param>
    static void AutomateSaveAsDialog(string path, string file)
    {
        // Wait for the "Save As" dialog to appear
        AutomationElement start;
        while (true)
        {
            start = AutomationElement.FocusedElement;
            if (start.Current.Name.Equals("File name:")) break;
            Thread.Sleep(100);
        }

        // Set the file name
        ValuePattern textBox = start.GetCurrentPattern(ValuePattern.Pattern) as ValuePattern;
        if (textBox == null)
        {
            Console.WriteLine("Error: Can't set the name");
            return;
        }
        textBox.SetValue(path + "\\" + file);
        
        // Get a reference to the dialog.
        // "Luke TreeWalker" lol
        TreeWalker luke = TreeWalker.ControlViewWalker;
        AutomationElement dialog = luke.GetParent(luke.GetParent(luke.GetParent(start)));
        
        // Use that to find the "Save" button
        Condition[] conditions = {
            new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Button),
            new PropertyCondition(AutomationElement.NameProperty, "Save")
        };

        // Using this "cave man debugging" (as one Stack Overflow post cleverly put it)
        // I found that the cause of the crashing is something somewhere after this line:
        Console.WriteLine("Conditions set");

        AutomationElement button = dialog.FindFirst(TreeScope.Descendants, new AndCondition(conditions));

        // And this line doesn't run, so I think it IS line 123... but why?
        Console.WriteLine("It's not line 123");
        
        /*
        // Gonna try commenting out this block - maybe something in here causes it??????
        if (button == null)
        {
            Console.WriteLine("Error: couldn't find the save button");
            return;
        }
        */

        Console.WriteLine("button is not null");
        
        // Push the button
        InvokePattern save = button.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
        Console.WriteLine("It's not line 138");

        /*
        // We know it won't be null, so Lord willing we can comment this out safely.
        if (save == null)
        {
            Console.WriteLine("Error: Can't set the name");
            Console.ReadKey();
            return;
        }
        */
        save.Invoke();
        Console.WriteLine("It's not line 151");
        
        // Check to make sure it worked
        Thread.Sleep(1000);  // just to play it safe
        if (!FileExistsAnyExtension(path, file))
            Console.WriteLine("Error: File not saved");
    }

任何有关该主题的信息,想法,问题,建议或其他想法将不胜感激。现在,我可以回到模拟击键并完成该项目的过程。但是UIA是我可能需要再次使用的东西,因此,如果这是一个非常常见的重复出现的问题,或者我最终需要了解它。我最好的猜测是Visual Studio会跳过一些未知的部分,动态地插入一些未与EXE打包在一起的神秘的缺少的组件……我有99.99999%的肯定不是我的代码,因为我的代码在Visual Studio中有效。哈哈idk。
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
Right after your line 39, make sure that dialog is not null, by adding something like:
C#:
if (dialog == null)
    Console.WriteLine("dialog not found.");
else
    Console.WriteLine("searching dialog to find the Save button");
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
But the random doesn't stop there. When I run it from PowerShell, then bring up the 另存为 dialog in Notepad, it not only crashes my program, but also PowerShell and Notepad! Returning to Visual Studio, if I try to re-compile my code, I get an error:
通常,这表明该程序仍在运行...或者该文件当前已被您的防病毒软件或某些其他保姆软件锁定。

确保您正在停止/终止该应用程序。

Try disabling your antivirus and other 保姆软件 when running your program.
 

灯塔麦克

新成员
已加入
2020年7月20日
留言内容
2
编程经验
5-10
嘿跳伞者
  • 我有一个像您一样的空检查,并在昨天的某个时候将其删除。抱歉,我忘了在这里添加它(大声笑)。重新添加它并没有真正的改变。好猜! :)
  • 我也想到了您所说的内容,因为该程序仍在运行。我发现的有关该错误的每个晦涩的Stack Overflow问题也都表明了这一点,但是它并未出现在任务管理器中。
  • 这留下了您的第三个想法,我怀疑这是罪魁祸首。这是唯一有意义的事情。我们使用BitDefender,这并不是第一次将其猴子扳手刺入我的作品中。不幸的是,开发人员不是这里的管理员,我不确定他们禁用我们的功能是否会很酷"nannyware"(顺便说一句,很喜欢这种表达方式-以前从未听说过这种表达方式),因为他们希望完成的软件可以在服务器上运行。所以我想我坚持使用Win32 / Pinvoke,这没关系。至少这些疯狂的小故障最终得到了解释。
无论如何,感谢您对此的快速回复。祝你有愉快的一天! :)

PS:我也从你的签名中删除了关于摧毁行星的报价。 :D
 
最佳 底部