Мне нужно запустить внешнюю программу через автоматизацию.
Эта программа обычно имеет нормальный интерфейс, но из-за моего специфического случая и из-за автоматизации она не будет показана.
Однако в некоторых случаях это откроет окно, и это окно должно быть расположено сверху.
Таким образом, ситуация ниже
![enter image description here](https://i.stack.imgur.com/QwNUV.png)
Итак, моя желаемая ситуация
![enter image description here](https://i.stack.imgur.com/tCcSj.png)
а не
![enter image description here](https://i.stack.imgur.com/e5Vqp.png)
Итак, с кодом, который я собираюсь описать, эта часть работает.
Единственная (основная) проблема заключается в том, что помимо вызова окна (здесь это окно сообщения), но это также минимизирует основную программу . И это проблема для меня.
Я должен сказать, что даже если внешняя программа показывает только 1 окно, неожиданно количество дочерних окон огромно (например, 650). Внешняя программа написана на C ++ и для меня она как черный ящик.
Итак, код следующий:
[DllImport("user32.dll", EntryPoint = "FindWindowEx")]
public static extern IntPtr FindWindowEx(IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
[DllImport("user32.dll")]
private static extern bool SetForegroundWindow(IntPtr hWnd);
public class WindowHandleInfo
{
private delegate bool EnumWindowProc(IntPtr hwnd, IntPtr lParam);
[DllImport("user32")]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool EnumChildWindows(IntPtr window, EnumWindowProc callback, IntPtr lParam);
private IntPtr _MainHandle;
public WindowHandleInfo(IntPtr handle)
{
this._MainHandle = handle;
}
public List<IntPtr> GetAllChildHandles()
{
List<IntPtr> childHandles = new List<IntPtr>();
GCHandle gcChildhandlesList = GCHandle.Alloc(childHandles);
IntPtr pointerChildHandlesList = GCHandle.ToIntPtr(gcChildhandlesList);
try
{
EnumWindowProc childProc = new EnumWindowProc(EnumWindow);
EnumChildWindows(this._MainHandle, childProc, pointerChildHandlesList);
}
finally
{
gcChildhandlesList.Free();
}
return childHandles;
}
private bool EnumWindow(IntPtr hWnd, IntPtr lParam)
{
GCHandle gcChildhandlesList = GCHandle.FromIntPtr(lParam);
if (gcChildhandlesList == null || gcChildhandlesList.Target == null)
{
return false;
}
List<IntPtr> childHandles = gcChildhandlesList.Target as List<IntPtr>;
childHandles.Add(hWnd);
return true;
}
}
public static void BringToFront(string strProcessNameNoExtension)
{
Process[] anotherApps = Process.GetProcessesByName(strProcessNameNoExtension);
if (anotherApps.Length == 0) return;
if (anotherApps[0] != null)
{
List<System.IntPtr> allChildWindows = new WindowHandleInfo(anotherApps[0].MainWindowHandle).GetAllChildHandles();
foreach (var childWindow in allChildWindows)
{
SetForegroundWindow(childWindow);
}
}
}
Короче говоря, я нахожу всех детей в процессе, а затем вывожу их всех вперед.
Как я уже говорил, основная программа минимизирована.