C # SendKeys.SendWait для диалога другого процесса (notepad.exe) - PullRequest
2 голосов
/ 16 февраля 2012

Я пытаюсь сделать следующее в 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 );

это устанавливает фокус на главное окно блокнота вместо диалогового окна подтверждения. Я использовал метод GetForegroundWindow из user32.dll и обнаружил, что дескриптор диалога отличается от дескриптора блокнота (что довольно важно), но 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" );

Спасибо

1 Ответ

2 голосов
/ 17 февраля 2012

Вы не можете дать то, чего у вас нет - SetForegroundWindow() работает, только если ваше приложение в данный момент имеет фокус.

Современные версии Windows предотвращают кражу приложений, так как это было большим раздражением в дни Windows 9x.

Кроме того, «Alt + F, x» относится только к выходу в английских версиях Windows, но не работает на большинстве других языков. Избегайте использования SendKeys(), его невозможно использовать надежным способом.

...