简体   繁体   English

使用 sendkey function 将键盘键发送到 C# 中的浏览器

[英]Sending keyboard key to browser in C# using sendkey function

Hello i am trying to send a key to browser using the code below, the new chrome window opens for me but it does not send the key to the browser.您好,我正在尝试使用下面的代码向浏览器发送密钥,新的 chrome window 会为我打开,但它不会向浏览器发送密钥。

When i debugged i found out chrome process does not have any title name how can i solve this problem?当我调试时,我发现 chrome 进程没有任何标题名称,我该如何解决这个问题?

 Process.Start("chrome.exe", "https://labs.sketchfab.com/sculptfab/");
        System.Threading.Thread.Sleep(2000);
        foreach (System.Diagnostics.Process p in System.Diagnostics.Process.GetProcesses())
        {
            if (p.ProcessName == "chrome" && p.MainWindowTitle == "SculptFab - SculptGL + Sketchfab" &&
                p.MainWindowHandle != IntPtr.Zero)
            {
                System.Threading.Thread.Sleep(2000);
                for (int i = 0; i < 50; i++)
                {
                    KeyHandle.SetForeGround(p.MainWindowHandle);
                    SendKeys.Send("s");
                    System.Threading.Thread.Sleep(2000);
                }

            }
        }

In the above mentioned page when "S" is pressed on the keyboard it zooms out of the object i want too achieve this using my C# code在上面提到的页面中,当在键盘上按下“S”时,它会缩小 object 我也想使用我的 C# 代码来实现这一点

You can create a new instance of Process use it to send your keystrokes. 您可以创建一个Process的新实例,使用它来发送您的击键。 See https://stackoverflow.com/a/12892316/2058898 for further information. 有关详细信息,请参阅https://stackoverflow.com/a/12892316/2058898

Update 更新

I've done some researching and it seems Chrome does in fact not react to the SendKeys.Send method. 我做了一些研究,看来Chrome确实没有对SendKeys.Send方法做出反应。 However you can use the Windows API to call the SendMessage function and send Keydown/-up signals to the window. 但是,您可以使用Windows API调用SendMessage函数并将Keydown / -up信号发送到窗口。 Here's a simple wrapper for using in Chrome: 这是一个在Chrome中使用的简单包装:

public class ChromeWrapper
{
    // you might as well use those methods from your helper class
    [DllImport("User32.dll")]
    private static extern int SetForegroundWindow(IntPtr point);
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    // the keystroke signals. you can look them up at the msdn pages
    private static uint WM_KEYDOWN = 0x100, WM_KEYUP = 0x101;

    // the reference to the chrome process
    private Process chromeProcess;

    public ChromeWrapper(string url)
    {
        // i'm using the process class as it gives you the MainWindowHandle by default
        chromeProcess = new Process();
        chromeProcess.StartInfo = new ProcessStartInfo("chrome.exe", url);
        chromeProcess.Start();
    }

    public void SendKey(char key)
    {
        if (chromeProcess.MainWindowHandle != IntPtr.Zero)
        {
            // send the keydown signal
            SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);

            // give the process some time to "realize" the keystroke
            System.Threading.Thread.Sleep(100); 

            // send the keyup signal
            SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYUP, (IntPtr)key, IntPtr.Zero);
        }
    }
}

Using this class is pretty simple: 使用这个类非常简单:

ChromeWrapper chrome = new ChromeWrapper("https://labs.sketchfab.com/sculptfab/");
System.Threading.Thread.Sleep(5000);

chrome.SendKey('S');

Works on my machine™ (Windows 8.1 Pro N, Google Chrome 42). 适用于我的机器™(Windows 8.1 Pro N,谷歌浏览器42)。

Additional information 附加信息

This solution only works if there's no Chrome running yet, as Chrome only sends the new URL to it's main process which opens it then. 此解决方案仅在尚未运行Chrome的情况下才有效,因为Chrome仅将新网址发送到其主要流程,然后打开它。 So either close other Chrome instances beforehand or use the SendMessage method on the process you found using Process.GetProcesses 因此,要么事先关闭其他Chrome实例,要么在使用Process.GetProcesses找到的进程上使用SendMessage方法

Here is an updated version of ChromeWrapper that: 以下是ChromeWrapper的更新版本:

  • Works also when chrome was already open ( attaches to existing chrome window ) 当chrome已经打开时也可以工作( 连接到现有的chrome窗口
  • Works when the computer is locked (unlike SendKeys.SendWait) 计算机锁定时工作 (与SendKeys.SendWait不同)

.

public class ChromeWrapper
{
    [DllImport("user32.dll")]
    private static extern IntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
    // the keystroke signals. you can look them up at the msdn pages
    private static uint WM_KEYDOWN = 0x100, WM_KEYUP = 0x101;

    // the reference to the chrome process
    private Process chromeProcess;

    public ChromeWrapper(string url)
    {
        Process.Start("chrome.exe", url); //no need to keep reference to this process, because if chrome is already opened, this is NOT the correct reference.
        Thread.Sleep(600);

        Process[] procsChrome = Process.GetProcessesByName("chrome");
        foreach (Process chrome in procsChrome)
        {
            if (chrome.MainWindowHandle == IntPtr.Zero)// the chrome process must have a window
                continue;
            chromeProcess = chrome; //now you have a handle to the main chrome (either a new one or the one that was already open).
            return;
        }
    }

    public void SendKey(char key)
    {
        try
        {
            if (chromeProcess.MainWindowHandle != IntPtr.Zero)
            {
                // send the keydown signal
                SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYDOWN, (IntPtr)key, IntPtr.Zero);
                // give the process some time to "realize" the keystroke
                Thread.Sleep(30); //On my system it works fine without this Sleep.
                // send the keyup signal
                SendMessage(chromeProcess.MainWindowHandle, ChromeWrapper.WM_KEYUP, (IntPtr)key, IntPtr.Zero);
            }
        }
        catch (Exception e) //without the GetProcessesByName you'd get an exception.
        {
        }
    }
}

I use it as below, for sending Tab and Enter keys. 我用它如下,用于发送Tab键和Enter键。

ChromeWrapper chrome = new ChromeWrapper(@"https://stackoverflow.com");
Thread.Sleep(300);
chrome.SendKey((char)9);// tab
chrome.SendKey((char)13);//enter

I modified Guy's code to run properly in .NET6我修改了 Guy 的代码以在 .NET6 中正常运行

Just replace this:只需替换这个:

Process.Start("chrome.exe", url); //no need to keep reference to this process, because if chrome is already opened, this is NOT the correct reference.
Thread.Sleep(600);

by this:这样:

 // i'm using the process class as it gives you the MainWindowHandle by default
 chromeProcess = new Process();
 chromeProcess.StartInfo = new ProcessStartInfo("chrome.exe", url);
 chromeProcess.StartInfo.UseShellExecute = true;
 chromeProcess.Start();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM