C# - 我如何可以重命名,我启动了一个进程窗口?(C# - How can I rename a

2019-06-23 15:49发布

有没有什么办法可以重命名,我已经启动的应用程序的窗口的标题栏中? 也就是说,如果我推出Notepad.exe的,我可以从它的标题栏重命名“无标题 - 记事本”到“新记事本名称”。

Answer 1:

您可以以P做/调用:

[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,标题不会改变。 或许消息结束了在记事本中的消息队列太早,让记事本将再次之后设置标题。

另外请注意,这是一个非常简单的变化; 如果用户选择文件 - >新建(或没有其他任何会导致记事本更新窗口标题),原题会回来的......



Answer 2:

其实,我整理我自己和它完美的作品。 不管怎么说,还是要谢谢你。

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

IntPtr handle = p.MainWindowHandle;
SetWindowText(handle, "This is my new title");


Answer 3:

你不能做到这一点在C#中,但你可以使用低级别的API做。 注入线程进入的过程中,调用函数SetWindowText()从它



Answer 4:

作为@Fredrik莫克认为,问题是,有需要等待该窗口可以接收消息来设置其标题。 等待100毫秒能打破程序的内部消息,尺蠖,它只是一种变通方法。 接收消息时,窗口必须具有的选择用于引用到窗口句柄,因此你可以简单地等待窗口,它在启动时应该是手柄IntPtr.Zero (空句柄)。

下面是这种方法的一个例子:

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

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

你也可以认为通过更换,以避免CPU开销while与语句SpinWait.SpinUntil调用(因此,你需要进口System.Threading ):

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


Answer 5:

没有。

这就要求在目标应用程序允许窗口标题在所有被修改。 许多程序使用他们的头衔显示出有用的信息(如文件打开记事本编辑,或名称<TITLE> HTML文档中的Firefox打开的)。

在一个案例中我知道,让用户设置的标题文字很少限制是CMD.EXE在控制台窗口中运行。 CMD支持TITLE内置的命令,其基于它的参数窗口的标题。 但是,这不能被第二个窗口,但不注入击键到特定的控制台窗口,它一般不建议做。

编辑:

由于这个想法是浮动是SetWindowText()会为你做到这一点,让我澄清。

这个API函数确实改变顶层窗口的标题栏。 这是,事实上,像记事本应用程序很可能使用来设定自己的标题就认为标题已经改变的任何时间通话。

我宣称这是不是一个解决方案的原因是,当它要记事本确实更改标题。 那些支持它的标题任意变化的应用程序将有某种机制要记住,标题被改变,而不是武断地恢复其首选标题字符串。



文章来源: C# - How can I rename a process window that I started?