C# SendKeys.SendWait 到另一个进程的对话框 (notepad.exe)

发布于 2025-01-06 11:08:17 字数 1963 浏览 3 评论 0原文

我正在尝试在 C# 中执行以下操作:

  • 打开一个新进程 (notepad.exe)
  • 输入一些文本(使用 SendKeys)
  • 关闭记事本(处理任何确认对话框)

这是我得到的

Process p = new Process();
p.StartInfo.Filename = "notepad.exe";
p.Start();

// use the user32.dll SetForegroundWindow method
SetForegroundWindow( p.MainWindowHandle ); // make sure notepad has focus

SendKeys.SendWait( "some text" );

SendKeys.SendWait( "%f" ); // send ALT+f
SendKeys.SendWait( "x" ); // send x = exit

// a confirmation dialog appears

所有这些都按预期工作,但现在之后我已发送 ALT+f+x 我收到 “是否要保存更改为无标题”对话框,我想从内部关闭它 我的应用程序通过“按”“n”表示“不保存”。但是,

SendKeys.SendWait( "n" ); 

仅当我的应用程序没有失去焦点时(在 ALT+f+x 之后)才有效。如果确实如此,并且我尝试返回,则将

SetForegroundWindow( p.MainWindowHandle );

焦点设置到主记事本窗口而不是确认对话框。我使用了 user32.dll 中的 GetForegroundWindow 方法,发现对话框句柄与记事本句柄不同(这有点道理),但 SetForegroundWindow 甚至无法使用使用对话框窗口

句柄知道如何将焦点返回到对话框以便我可以成功使用 SendKeys 吗?

这是完整的代码

[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);        

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();             

[DllImport("User32.DLL")] 
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 

public const int SW_RESTORE = 9;        

    ...

Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.Start();
Thread.Sleep( 1000 );

SendKeys.SendWait( "some text" );
SendKeys.SendWait( "%f" ); // send ALT+F
SendKeys.SendWait( "x" ); // send x = exit

IntPtr dialogHandle = GetForegroundWindow();
System.Diagnostics.Trace.WriteLine( "notepad handle: " + p.MainWindowHandle );
System.Diagnostics.Trace.WriteLine( "dialog handle: " + dialogHandle );

Thread.Sleep( 5000 ); // switch to a different application to lose focus

SetForegroundWindow( p.MainWindowHandle );
ShowWindow( dialogHandle, SW_RESTORE );

Thread.Sleep( 1000 );
SendKeys.SendWait( "n" );

谢谢

I'm trying to do the following in C#:

  • Open a new process (notepad.exe)
  • Enter some text (using SendKeys)
  • Close Notepad (deal with any confirmation dialogs)

Here's what I got

Process p = new Process();
p.StartInfo.Filename = "notepad.exe";
p.Start();

// use the user32.dll SetForegroundWindow method
SetForegroundWindow( p.MainWindowHandle ); // make sure notepad has focus

SendKeys.SendWait( "some text" );

SendKeys.SendWait( "%f" ); // send ALT+f
SendKeys.SendWait( "x" ); // send x = exit

// a confirmation dialog appears

All this works just as expected, but now after I've sent ALT+f+x I get a
"Do you want to save changed to Untitled" dialog and I would like to close it from within
my applications by "pressing" 'n' for "Don't Save". However

SendKeys.SendWait( "n" ); 

works only if my application has not lost focus (after ALT+f+x). If it did and I try to go back using

SetForegroundWindow( p.MainWindowHandle );

this sets the focus to the main notepad window instead of the confirmation dialog. I used the GetForegroundWindow method from user32.dll and found out that the dialog handle is different than the notepad handle (which kinda makes sence) but SetForegroundWindow doesn't work with even with the dialog window handle

Any idea how I can give the focus back to the dialog so that I can successfully use SendKeys?

here's the full code

[DllImport("user32.dll")]
static extern bool SetForegroundWindow(IntPtr hWnd);        

[DllImport("user32.dll")]
static extern IntPtr GetForegroundWindow();             

[DllImport("User32.DLL")] 
static extern bool ShowWindow(IntPtr hWnd, int nCmdShow); 

public const int SW_RESTORE = 9;        

    ...

Process p = new Process();
p.StartInfo.FileName = "notepad.exe";
p.Start();
Thread.Sleep( 1000 );

SendKeys.SendWait( "some text" );
SendKeys.SendWait( "%f" ); // send ALT+F
SendKeys.SendWait( "x" ); // send x = exit

IntPtr dialogHandle = GetForegroundWindow();
System.Diagnostics.Trace.WriteLine( "notepad handle: " + p.MainWindowHandle );
System.Diagnostics.Trace.WriteLine( "dialog handle: " + dialogHandle );

Thread.Sleep( 5000 ); // switch to a different application to lose focus

SetForegroundWindow( p.MainWindowHandle );
ShowWindow( dialogHandle, SW_RESTORE );

Thread.Sleep( 1000 );
SendKeys.SendWait( "n" );

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凉城凉梦凉人心 2025-01-13 11:08:17

您无法提供您没有的东西 - SetForegroundWindow() 仅在您的应用程序当前获得焦点时才有效。

现代 Windows 版本可防止应用程序窃取焦点,因为这在 Windows 9x 时代是一个主要烦恼。

另外,“Alt+F, x”仅指英语 Windows 版本上的退出,它不适用于大多数其他语言。避免使用 SendKeys(),它不可能以可靠的方式使用。

You can't give what you don't have - SetForegroundWindow() only works if your application currently has the focus.

Modern Windows versions prevent applications from stealing focus, as that was a major annoyance back in the Windows 9x days.

Also, 'Alt+F, x' only refers to exit on English Windows versions, it won't work on most other languages. Avoid using SendKeys(), it's impossible to use in a reliable way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文