C# 将键盘键发送到同一项目上启动的另一个应用程序

C# 将键盘键发送到同一项目上启动的另一个应用程序,c#,sendkeys,C#,Sendkeys,我试图发送一些键盘键来控制在同一项目上启动的game boy advance模拟器,但它找不到过程 public partial class MainWindow : Window { [DllImport("User32.dll")] static extern int SetForegroundWindow(IntPtr point); /////////////////////// /// <summary> /// Method

我试图发送一些键盘键来控制在同一项目上启动的game boy advance模拟器,但它找不到过程

 public partial class MainWindow : Window
{
    [DllImport("User32.dll")]
    static extern int SetForegroundWindow(IntPtr point);

    ///////////////////////

    /// <summary>
    /// Method used to run VisualBoyAdvance emulator with a GBA ROM
    /// </summary>
    /// <param name="command"></param>
    public void RunProgram()
    {

        // PATH of the ROM
        const string ex1 = @"C:\GameBoy\marioKart.gba";

        // Use ProcessStartInfo class
        ProcessStartInfo startInfo = new ProcessStartInfo();
        startInfo.CreateNoWindow = false;
        startInfo.UseShellExecute = false;
        //Name of the emulator, PATH
        startInfo.FileName = @"C:\GameBoy\VisualBoyAdvance-SDL.exe";

        //Can be set to hidden to hide.
        startInfo.WindowStyle = ProcessWindowStyle.Normal;
        //Arguments if needed
        startInfo.Arguments ="  " + ex1;
    try
    {

            // Start the process with the info we specified.
            // Call WaitForExit and then the using statement will close.
            using (Process execProcess = Process.Start(startInfo))
            {
                //Select the process to send the keys

                Process[] localAll = Process.GetProcesses();
                Process p = localAll[0];
                Console.WriteLine(p);
                if( p != null)
                {
                    IntPtr h = p.MainWindowHandle;
                    SetForegroundWindow(h);
                    //Sending some "Enter" keys
                    SendKeys.SendWait("~");
                    SendKeys.SendWait("~");
                    SendKeys.SendWait("~");
                    SendKeys.SendWait("{ENTER}");
                }
                execProcess.WaitForExit();


            }
        }
        catch
        {
            Console.Write("~");
            Console.Write("Error.");
        }

    }
公共部分类主窗口:窗口
{
[DllImport(“User32.dll”)]
静态外部int SetForegroundWindow(IntPtr点);
///////////////////////
/// 
///用于使用GBA ROM运行VisualBoyAdvance仿真器的方法
/// 
/// 
公共程序()
{
//ROM的路径
常量字符串ex1=@“C:\GameBoy\marioKart.gba”;
//使用ProcessStartInfo类
ProcessStartInfo startInfo=新的ProcessStartInfo();
startInfo.CreateNoWindow=false;
startInfo.UseShellExecute=false;
//仿真器的名称,路径
startInfo.FileName=@“C:\GameBoy\VisualBoyAdvance SDL.exe”;
//可以设置为“隐藏”以隐藏。
startInfo.WindowStyle=ProcessWindowStyle.Normal;
//如果需要,请提供参数
startInfo.Arguments=“”+ex1;
尝试
{
//使用我们指定的信息启动流程。
//调用WaitForExit,然后using语句将关闭。
使用(processexecprocess=Process.Start(startInfo))
{
//选择发送密钥的过程
Process[]localAll=Process.getprocesss();
进程p=localAll[0];
控制台写入线(p);
如果(p!=null)
{
IntPtr h=p.MainWindowHandle;
SetforeGroundindow(h);
//发送一些“回车”键
SendKeys.SendWait(“~”);
SendKeys.SendWait(“~”);
SendKeys.SendWait(“~”);
SendKeys.SendWait(“{ENTER}”);
}
execProcess.WaitForExit();
}
}
抓住
{
控制台。写(“~”;
控制台。写入(“错误”);
}
}

我不知道我发送的密钥是否正确。谢谢大家!

很可能您的密钥被发送到了正确的进程
localAll[0]
。请确保您将它们发送到了正确的应用程序(例如
process[]processs=process.getprocesss()。其中(p=>p.ProcessName==“VisualBoyAdvance SDL”)
Process p=Process.getProcessByName(“VisualBoyAdvance SDL”)
。请确保在第一种情况下检查长度为0的数组,或在第二种情况下检查长度为null的数组


除此之外,使用SendKeys.SendWait应该对您有用,因为这本质上就是Win32 API SendMessage(SendKeys.Send将使用Win32 API PostMessage).

是否有可能在进程完成打开之前发送密钥的速度过快?也许您希望在进程打开和密钥发送之间引入一个小的延迟。我刚刚尝试了这个方法,但它不起作用:System.Threading.Thread.Sleep(5000)请尝试使用
p.WaitForInputIdle()
,而不是使用
Thread.Sleep
。请将其放在
IntPtr h=p.MainWindowHandle
前面。另请参见来自MSDN的:已为.NET Framework 3.0更新SendKeys类,以使其能够在Windows Vista上运行的应用程序中使用。增强了Windows Vista的安全性(称为用户帐户控制或UAC)阻止以前的实现按预期工作。。。