2012-02-16 2 views
2

Я пытаюсь сделать следующее в C#:C# SendKeys.SendWait к диалогу другого процесса (notepad.exe)

  • Открыть новый процесс (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» для «Не сохранять». Тем не менее

работает только в том случае, если мое приложение не потеряло фокус (после 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"); 

Спасибо

ответ

2

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

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

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

+0

Спасибо, это имеет смысл. Я остался с 'SendKeys', потому что моему приложению необходимо автоматизировать ввод пользователей в другое стороннее приложение. p.s. Я использовал ALT + F x только для демонстрации здесь – scibuff

Смежные вопросы