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

有没有什么办法可以重命名我启动的应用程序的窗口标题栏? 即如果我启动Notepad.exe,我可以将其标题栏从“无标题 – 记事本”重命名为“新记事本名称”。

你可以使用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"); } 

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

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

实际上,我自己整理了它并且它完美地工作。 不管怎么说,还是要谢谢你。

 [DllImport("user32.dll")] static extern SetWindowText(IntPtr hWnd, string windowName); IntPtr handle = p.MainWindowHandle; SetWindowText(handle, "This is my new title"); 

您无法在C#中执行此操作,但可以使用低级API执行此操作。 将一个线程注入进程,从中调用SetWindowText()

正如@FredrikMörk所认为的,问题是需要等待窗口可以接收消息来设置其标题。 等待100毫秒可以打破程序的内部消息循环,这只是一个解决方法。 要接收消息,窗口必须有一个用于引用该窗口的句柄,因此您只需等待窗口的句柄,在启动时应该是IntPtr.Zero (一个空句柄)。

以下是此方法的示例:

 Process p = Process.Start("notepad.exe"); while (p.MainWindowHandle == IntPtr.Zero) Application.DoEvents(); SetWindowText(p.MainWindowHandle, "My Notepad"); 

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

您还可以通过使用SpinWait.SpinUntil调用替换while语句来避免内存泄漏(因此,您需要导入System.Threading ):

 Process p = Process.Start("notepad.exe"); SpinWait.SpinUntil(delegate { return p.MainWindowHandle != IntPtr.Zero; }); SetWindowText(p.MainWindowHandle, "My Notepad"); 

没有。

这将要求目标应用程序允许完全修改窗口标题。 许多程序使用它们的标题来显示有用的信息(例如在记事本中打开以进行编辑的文件的名称,或在Firefox中打开的HTML文档的 )。

我知道的一个案例是让用户设置标题文本的限制很少是在控制台窗口中运行的CMD.EXE。 CMD支持TITLE内置命令,该命令根据参数设置窗口标题。 但是,如果不将关键笔划注入特定控制台窗口,则无法通过第二个窗口完成此操作,这通常不建议使用。

编辑:

由于这个想法是浮动的, SetWindowText()会为你做这件事,让我澄清一下。

该API函数确实改变了顶级窗口的标题栏。 事实上,这是一个调用,像Notepad这样的应用程序可能会在它认为标题发生变化时设置自己的标题。

我声称这不是一个解决方案的原因是记事本确实在它想要的时候改变了标题。 支持对其标题进行任意更改的应用程序将具有某种机制来记住标题已更改,而不是任意恢复其首选标题字符串。