2

我需要找到打开的进程或应用程序文本框并更改其值。但我想用 c# 的方式来做。如果有人知道可以请分享给我吗?还是我必须使用 c++ 以及如何使用?

感谢您的建议。

4

3 回答 3

3

就像另一个人说的那样,UIAutomation 是要走的路。http://msdn.microsoft.com/en-us/library/ms753107.aspx

以下代码将打开 Notepad.exe,打开其文件对话框,然后在文件名字段中输入一些文本。

        Process notepad = Process.Start("notepad");

        Thread.Sleep(5000);

        SendKeys.SendWait("^o"); //ctrl+o to open the File Dialog

        var notepadTextBox = AutomationElement.RootElement.FindFirst(TreeScope.Descendants, 
            new PropertyCondition(AutomationElement.AutomationIdProperty, "1148"));

        object valuePattern = null;

        if (notepadTextBox.TryGetCurrentPattern(ValuePattern.Pattern, out valuePattern))
        {
            ((ValuePattern)valuePattern).SetValue("THERE YOU GO"); // this text will be entered in the textbox
        }
        else 
        {
            //ERROR
        }

所以这实际上是发送击键来控制 UI(打开文件打开对话框)和 UIAutomation 的组合,但是如果需要,您可以将其更改为像用户一样驱动菜单。

此外,您可能想知道魔术字符串“1148”的来源——即记事本中文件名输入字段的“自动化 ID”。我使用了inspect.exe(包含在Windows SDK 中)来查找自动化ID,如果有的话,您的应用程序将需要它来查看它的AutomationIds。

于 2013-05-03T23:18:15.297 回答
2

一种方法是,如果应用程序在使用库和包装器方面超出您的控制范围:

Process[] Procs = Process.GetProcessesByName("NameofProcess");

这将为您提供相关过程。现在这是变得棘手的地方,取决于您到底需要做什么。

您最终需要找到字符串在内存中的存储位置,您可以使用内存分析器来执行此操作或类似 CheatEngine 的东西来查找值,而不是了解您使用 CheatEngine 的目的或使用它的方式,但它只是查找内存位置的一种简单方法。

然后,您可以使用以下方式读取/写入内存位置:

    [DllImport("kernel32.dll")]
    public static extern Int32 ReadProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, [In, Out] byte[] buffer, UInt32 size, out IntPtr lpNumberOfBytesRead);
    [DllImport("kernel32.dll", SetLastError = true)]
    static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, uint nSize, out int lpNumberOfBytesWritten);
    public static byte[] ReadMem(IntPtr MemAddy, uint bytestoread, Process Proc)
    {
        //
        //Create new Memory buffer and pointer to that buffer
        //
        byte[] buffer = new byte[bytestoread];
        IntPtr bufferptr;
        //
        //Read Process Memory and output to buffer
        //
        ReadProcessMemory(Proc.Handle, MemAddy, buffer, bytestoread, out bufferptr);
        //
        //Return the buffer
        //
        return buffer;
    }

    public static bool WriteMem(IntPtr MemAddy, byte[] buffer, Process Proc)
    {
        int NumWriten;
        WriteProcessMemory(Proc.Handle, MemAddy, buffer, (uint)buffer.Length, out NumWriten);
        if (NumWriten != buffer.Length)
        {
            return false;
        }
        else return true;
    }

这两个函数将允许您读取和写入一些任意进程的内存位置。

如果你想要有问题的窗口,你可以使用:

    [DllImport("user32.dll")]
    public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);

像这样:

    IntPtr HWND = FindWindow(null, "WinName");

这将为您提供相关窗口的句柄。

另一种方法是找到窗口,然后将一些事件传递给它,例如使窗口成为焦点,然后以编程方式在文本框之间切换。但是,如果没有更多关于你到底想要做什么的信息,我不确定这里还能说什么。

于 2013-05-03T22:01:56.050 回答
0

您正在寻找的工具是UI Automation。它会让您看到其他程序的控件并将文本发送到这些控件。我过去曾这样做过,我必须从损坏的数据库中导出数据,并且每次遇到损坏的记录时都必须在对话框上单击“确定”。

这个主题太复杂了,无法在 SO 答案的空间中深入探讨如何做到这一点,但这是我在 CodePlex 上找到的一个教程,介绍了如何做到这一点。

还有 3rd 方包装库使其更容易做到。我个人最喜欢的是白色

于 2013-05-03T22:52:03.083 回答