C# - 如何重命名我开始的进程窗口?

djd*_*d87 6 c# window process titlebar

有没有办法可以重命名我启动的应用程序的窗口标题栏?即如果我启动了Notepad.exe,我可以将其标题栏从"Untitled - Notepad"重命名为"New Notepad Name".

Fre*_*örk 15

你可以使用P/Invoke来做到这一点:

[DllImport("user32.dll")]
static extern int SetWindowText(IntPtr hWnd, string text);



private void StartMyNotepad()
{
    Process p = Process.Start("notepad.exe");
    Thread.Sleep(100);  // <-- ugly hack
    SetWindowText(p.MainWindowHandle, "My Notepad");
}
Run Code Online (Sandbox Code Playgroud)

代码示例中丑陋黑客的背景是,似乎您在启动进程后立即调用SetWindowText,标题不会更改.也许消息在记事本的消息队列中过早结束,因此记事本将在之后再次设置标题.

还要注意,这是一个非常短暂的变化; 如果用户选择文件 - >新建(或做任何其他会导致记事本更新窗口标题的东西),原始标题将返回...

  • MS建议您在Sleep呼叫的地方调用WaitForInputIdle.http://msdn.microsoft.com/en-us/library/system.diagnostics.process.mainwindowhandle.aspx这从"Hack"到"推荐实践"(我在某些时候发现这是必要的) (7认同)
  • 这是解决我的问题的方法,因为我正在使用的应用程序永远不会将其重新设置。我仅以记事本为例。另外,如果您确实愿意,创建您自己的事件以处理窗口句柄的标题更改然后再次将其重置非常简单。 (2认同)

djd*_*d87 5

实际上,我自己对它进行了排序,并且效果很好。不管怎么说,还是要谢谢你。

[DllImport("user32.dll")]
static extern SetWindowText(IntPtr hWnd, string windowName);

IntPtr handle = p.MainWindowHandle;
SetWindowText(handle, "This is my new title");
Run Code Online (Sandbox Code Playgroud)


Dav*_*zzo 5

正如 @Fredrik M\xc3\xb6rk 所认为的,问题在于需要等待窗口能够接收消息,然后才能设置其标题。等待 100 毫秒可能会破坏程序的内部消息循环,这只是一种解决方法。\n要接收消息,窗口必须有一个用于引用该窗口的句柄,因此您只需等待窗口有一个句柄即可,像这样:

\n
Process p = Process.Start("notepad.exe");\nwhile (p.MainWindowHandle == IntPtr.Zero)\n    Application.DoEvents();\nSetWindowText(p.MainWindowHandle, "My Notepad");\n
Run Code Online (Sandbox Code Playgroud)\n

使用Application.DoEvents()该程序将继续接收和处理系统消息,因此它不会阻塞(也不会崩溃),尽管它不是异步的。

\n

您还可以考虑通过用调用(来自)替换while语句来避免 CPU 开销:SpinWait.SpinUntilSystem.Threading

\n
Process p = Process.Start("notepad.exe");\nSpinWait.SpinUntil(() => p.MainWindowHandle != IntPtr.Zero);\nSetWindowText(p.MainWindowHandle, "My Notepad");\n
Run Code Online (Sandbox Code Playgroud)\n