使用进程将数据发送到记事本

本文关键字:记事本 数据 进程 | 更新日期: 2023-09-27 18:08:43

我想把列表框里的每一项都记录到记事本上,但是我的逻辑有点混乱。

private void send_Click(object sender, EventArgs e)
{
    var notepad = Process.GetProcessesByName("Notepad").FirstOrDefault(p => p.MainWindowTitle == "Untitled - Notepad");
    if (notepad != null)
    {
        if (IsIconic(notepad.MainWindowHandle))
            ShowWindow(notepad.MainWindowHandle, 9);
        SetForegroundWindow(notepad.MainWindowHandle);
        string text = "";
        foreach (var item in listBox1.Items)
        {
            text = item.ToString();
            Clipboard.SetText(text);
            SendKeys.Send("^V");
            SendKeys.Send("{ENTER}");
        }
    }
}

在我的逻辑中,这应该将列表框中的每个项目发送到记事本中,每个项目在不同的行上。但这并不是每次都发生,有时它只发送列表框中最后一个项目因为列表框中有很多项目。我错过什么了吗?

使用进程将数据发送到记事本

您可以使用FindWindowEx找到记事本的Edit控件,并使用SendMessage向其发送WM_SETTEXT消息。这样你就不需要把记事本窗口放在前面了。

using System.Diagnostics;
using System.Runtime.InteropServices;
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter,
    string lpszClass, string lpszWindow);
[DllImport("User32.dll")]
static extern int SendMessage(IntPtr hWnd, int uMsg, IntPtr wParam, string lParam);
const int WM_SETTEXT = 0x000C;
private void button1_Click(object sender, EventArgs e)
{
    //Find notepad by its name, or use the instance which you opened yourself
    var notepad = Process.GetProcessesByName("notepad").FirstOrDefault();
    if(notepad!=null)
    {
        var edit = FindWindowEx(notepad.MainWindowHandle, IntPtr.Zero, "Edit", null);
        SendMessage(edit, WM_SETTEXT, IntPtr.Zero, "This is a Text!");
    }
}

我有一个示例测试,如果您更改SendKeys,它就可以工作。发送到SendKeys。SendWait

    List<string> data = new List<string>() { "Test", "hope", "It", "works","Or" };
    foreach (var item in data)
    {
        Clipboard.Clear();
        Clipboard.SetText(item);
        //SendKeys.Send("^V");
        //SendKeys.Send("{ENTER}");
        SendKeys.SendWait("^V");
        SendKeys.SendWait("{ENTER}");
    }

因为键应用晚于更新剪贴板和循环,所以问题发生了

你可以用InputSimulator, Package Manage Console来做:安装包InputSimulator

 private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                var notepad = Process.GetProcessesByName("Notepad").FirstOrDefault(p => p.MainWindowTitle == "Untitled - Notepad");
                if (notepad != null)
                {
                    if (IsIconic(notepad.MainWindowHandle))
                        ShowWindow(notepad.MainWindowHandle, 9);
                    var input = new InputSimulator();
                    SetForegroundWindow(notepad.MainWindowHandle);
                    foreach (var item in listBox1.Items)
                    {
                        input.Keyboard.TextEntry(item.ToString());
                        input.Keyboard.KeyPress(VirtualKeyCode.RETURN);
                    }
                }
            }

await Task.Delay();比用System.Threading.Thread.Sleep();好https://stackoverflow.com/a/20084603/6886308

来自@GillBates的建议,我使用System.Threading.Thread.Sleep();,它现在似乎工作得很好。

private void send_Click(object sender, EventArgs e)
{
 var notepad = Process.GetProcessesByName("Notepad").FirstOrDefault(p => p.MainWindowTitle == "Untitled - Notepad");
            if (notepad != null)
            {
                if (IsIconic(notepad.MainWindowHandle))
                    ShowWindow(notepad.MainWindowHandle, 9);
                SetForegroundWindow(notepad.MainWindowHandle);
                string text = "";
                foreach (var item in listBox1.Items)
                {
                    text = item.ToString();
                    Clipboard.SetText(text);
                    SendKeys.Send("^V");
                    SendKeys.Send("{ENTER}");
                    System.Threading.Thread.Sleep(150);
                }
            }
}