C # - Как я могу переименовать окно процесса, которое я запустил?

StackOverflow https://stackoverflow.com/questions/1016823

  •  06-07-2019
  •  | 
  •  

Вопрос

Есть ли какой-нибудь способ переименовать строку заголовка окна приложения, которое я запустил?То есть.если бы я запустил 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 () из него

Как считает @Fredrik M & # 246; rk, проблема в том, что нужно дождаться, пока окно сможет получать сообщения, чтобы установить его заголовок. Ожидание 100 миллисекунд может сломать внутреннюю петлю сообщений программы, и это всего лишь обходной путь. Чтобы получить сообщение, окно должно иметь дескриптор, который используется для ссылки на это окно, поэтому вы можете просто дождаться дескриптора окна, который при запуске должен быть IntPtr.Zero (пустой дескриптор).

Вот пример такого подхода:

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

Используя Application.DoEvents(), программа продолжит получать и обрабатывать системные сообщения, поэтому она не будет блокироваться (или аварийно завершать работу), хотя она не является асинхронной.

Можно также избежать загрузки ЦП, заменив оператор while вызовом SpinWait.SpinUntil (поэтому вам нужно импортировать System.Threading):

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

Нет.

Для этого потребуется, чтобы целевое приложение вообще разрешило изменять заголовок окна.Многие программы используют свои названия для отображения полезной информации (например, имени файла, открытого для редактирования в Блокноте, или <TITLE> из HTML-документа, открытого в Firefox).

Единственный известный мне случай, который позволяет пользователю устанавливать текст заголовка с небольшими ограничениями, - это CMD.EXE запуск в окне консоли.CMD поддерживает TITLE встроенная команда, которая задает заголовок окна на основе его аргументов.Но это не может быть сделано вторым окном без ввода нажатий клавиш в конкретное окно консоли, что обычно не рекомендуется.

Редактировать:

Поскольку идея витает в воздухе, что SetWindowText() сделаю это за вас, позвольте мне уточнить.

Эта функция API действительно изменяет строку заголовка окна верхнего уровня.Фактически, это вызов, который приложение, подобное Notepad, скорее всего, использует для установки собственного заголовка в любой момент, когда оно считает, что заголовок изменился.

Причина, по которой я утверждаю, что это нет решение заключается в том, что Notepad действительно меняет заголовок, когда хочет.Приложение, поддерживающее произвольные изменения своего заголовка, должно иметь какой-то механизм, который запоминает, что заголовок был изменен, и не восстанавливает произвольно предпочитаемую строку заголовка.

scroll top