我需要找到打开的进程或应用程序文本框并更改其值。但我想用 c# 的方式来做。如果有人知道可以请分享给我吗?还是我必须使用 c++ 以及如何使用?
感谢您的建议。
就像另一个人说的那样,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。
一种方法是,如果应用程序在使用库和包装器方面超出您的控制范围:
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");
这将为您提供相关窗口的句柄。
另一种方法是找到窗口,然后将一些事件传递给它,例如使窗口成为焦点,然后以编程方式在文本框之间切换。但是,如果没有更多关于你到底想要做什么的信息,我不确定这里还能说什么。
您正在寻找的工具是UI Automation。它会让您看到其他程序的控件并将文本发送到这些控件。我过去曾这样做过,我必须从损坏的数据库中导出数据,并且每次遇到损坏的记录时都必须在对话框上单击“确定”。
这个主题太复杂了,无法在 SO 答案的空间中深入探讨如何做到这一点,但这是我在 CodePlex 上找到的一个教程,介绍了如何做到这一点。
还有 3rd 方包装库使其更容易做到。我个人最喜欢的是白色。