【问题标题】:Get Open Process Windows Textbox with C#使用 C# 获取打开进程 Windows 文本框
【发布时间】:2013-05-03 21:44:17
【问题描述】:

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

感谢您的建议。

【问题讨论】:

  • 您要查找窗口吗?还是内存中的实际过程?更改其值是指您可以从应用程序控制的窗口吗?
  • 我正在尝试查找 some.exe 及其打开的窗口以及其中的文本框。我实际上将不得不给出字符串。我想我需要更改内存值。但我不知道该怎么做。
  • 您打开应用程序的过程是您编写的吗?如果是这样,您可以使用 IPC 库与该进程进行通信。
  • 不,它不是我的程序。它是用delphi编写的。我的用户试图手动输入保存路径。我必须拯救他们的一天。

标签: c# process


【解决方案1】:

正如另一个人所说,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,如果有的话,您的应用程序将需要它来查看其 AutomationId。

【讨论】:

    【解决方案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");
    

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

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

    【讨论】:

    • 嗯,我想首先你想解释什么?哪种战术?
    • 嗯。我只需要注入我的文件夹路径即可打开 someprogramme.exe 文本框。而已。我将决定它是哪个文件夹。这个应用程序的目的很简单。只需找到特定程序打开的文本框。让我们说它的记事本++,我想在它的新文档上写点东西。就是这样。
    • 好吧,如果是这样的话,我不得不说去@canhazbits 发布的答案,除非你不能使用 UIAutomation 的想法,在这种情况下你需要使用上面的方法并找到具体的文本框保存字符串的内存位置,具体取决于应用程序。这只是搜索和找到正确位置的问题。您可以使用各种工具执行此操作,只需 google 进程内存搜索。您可以查看此以获取更多信息stackoverflow.com/questions/781716/…
    【解决方案3】:

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

    这个话题太复杂了,无法在 SO 答案的空间中深入探讨如何做到这一点,但 here is a tutorial I found on CodePlex 会介绍如何做到这一点。

    还有 3rd 方包装库使其更易于操作。我个人最喜欢的是White

    【讨论】:

      猜你喜欢
      • 2012-03-16
      • 1970-01-01
      • 2011-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-04
      • 1970-01-01
      相关资源
      最近更新 更多