Folgende Klasse erleichtert die Arbeit beim
- Fenster finden
- Fenster in den Vordergrund holen
- Übersenden von Windows-Messages an Fenster
- Übersenden von Strings an Fenster
- Fenster schließen
- Anwendungen/Prozesse starten
- Anwendungen/Prozesse beenden
- Prozesse anhand der ID finden
Alle dazu benötigten Funktionen aus der User32.dll werden eingebunden und auch alle in der windows.h definierten Windows-Message-Konstanten sind enthalten.
- Aufrufbeispiel:
// eigene Message definieren private const int WM_MYOWNMESSAGE = 11111; // Hilfsobjekt erzeugen CAppCtrlObj wc = new CAppCtrlObj(); // Fenster-Handle von einer Beispielanwendung holen IntPtr hWnd = wc.GetWindowHandle("FensterTitelMeinerAnwendung", null); // Message an Fensterhandle schicken, in LParam wird beispielhaft die akt. Prozess-ID des aufrufenden Prozesses mitgesendet, auf Abarbeitung der Message warten IntPtr err = wc.SendMessageToWindow(hWnd, WM_MYOWNMESSAGE, IntPtr.Zero, (IntPtr)System.Diagnostics.Process.GetCurrentProcess().Id); if ((int)err != 0) { // Fehler } // Nachricht WM_CLOSE senden, Fenster schließen, nicht auf Abarbeitung der Message warten if (wc.PostMessageToWindow(hWnd, CAppCtrlObj.WM_CLOSE, IntPtr.Zero, IntPtr.Zero)) { // ok } // String an Fensterhandle schicken IntPtr err = wc.SendStringMessageToWindow(hWnd, IntPtr.Zero, "Hallo."); if ((int)err != 0) { // Fehler } // Fenster in den Vordergrund holen if (wc.ActivateWindow(hWnd)) { // ok } // Notepad mit Datei meintext.txt sichtbar und maximiert starten, ProzessID zurückholen int iProzessID = wc.StartApplication(@"c:\WINDOWS\notepad.exe", @"c:\meintext.txt", false, true); // zu ProzessID gehörendes Prozessobjekt holen Process proc = wc.GetProcess(iProzessID); if (proc != null) { // Hauptfenster des Prozesses schließen, 10s auf Schließen-Bestätigung warten, sonst Fehler if (wc.CloseWindow(proc, false, true, 10000)) { } }
- Klasse:
using System.Diagnostics; using System.Runtime.InteropServices; using System.IO; /// <summary> /// Struct für die Stringübergabe an andere Fenster /// </summary> public struct SCopyData { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } public class CAppCtrlObj { #region Message-Konstanten aus der Windows.h public const int WM_NULL = 0x00; public const int WM_CREATE = 0x01; public const int WM_DESTROY = 0x02; public const int WM_MOVE = 0x03; public const int WM_SIZE = 0x05; public const int WM_ACTIVATE = 0x06; public const int WM_SETFOCUS = 0x07; public const int WM_KILLFOCUS = 0x08; public const int WM_ENABLE = 0x0A; public const int WM_SETREDRAW = 0x0B; public const int WM_SETTEXT = 0x0C; public const int WM_GETTEXT = 0x0D; public const int WM_GETTEXTLENGTH = 0x0E; public const int WM_PAINT = 0x0F; public const int WM_CLOSE = 0x10; public const int WM_QUERYENDSESSION = 0x11; public const int WM_QUIT = 0x12; public const int WM_QUERYOPEN = 0x13; public const int WM_ERASEBKGND = 0x14; public const int WM_SYSCOLORCHANGE = 0x15; public const int WM_ENDSESSION = 0x16; public const int WM_SYSTEMERROR = 0x17; public const int WM_SHOWWINDOW = 0x18; public const int WM_CTLCOLOR = 0x19; public const int WM_WININICHANGE = 0x1A; public const int WM_SETTINGCHANGE = 0x1A; public const int WM_DEVMODECHANGE = 0x1B; public const int WM_ACTIVATEAPP = 0x1C; public const int WM_FONTCHANGE = 0x1D; public const int WM_TIMECHANGE = 0x1E; public const int WM_CANCELMODE = 0x1F; public const int WM_SETCURSOR = 0x20; public const int WM_MOUSEACTIVATE = 0x21; public const int WM_CHILDACTIVATE = 0x22; public const int WM_QUEUESYNC = 0x23; public const int WM_GETMINMAXINFO = 0x24; public const int WM_PAINTICON = 0x26; public const int WM_ICONERASEBKGND = 0x27; public const int WM_NEXTDLGCTL = 0x28; public const int WM_SPOOLERSTATUS = 0x2A; public const int WM_DRAWITEM = 0x2B; public const int WM_MEASUREITEM = 0x2C; public const int WM_DELETEITEM = 0x2D; public const int WM_VKEYTOITEM = 0x2E; public const int WM_CHARTOITEM = 0x2F; public const int WM_SETFONT = 0x30; public const int WM_GETFONT = 0x31; public const int WM_SETHOTKEY = 0x32; public const int WM_GETHOTKEY = 0x33; public const int WM_QUERYDRAGICON = 0x37; public const int WM_COMPAREITEM = 0x39; public const int WM_COMPACTING = 0x41; public const int WM_WINDOWPOSCHANGING = 0x46; public const int WM_WINDOWPOSCHANGED = 0x47; public const int WM_POWER = 0x48; public const int WM_COPYDATA = 0x4A; public const int WM_CANCELJOURNAL = 0x4B; public const int WM_NOTIFY = 0x4E; public const int WM_INPUTLANGCHANGEREQUEST = 0x50; public const int WM_INPUTLANGCHANGE = 0x51; public const int WM_TCARD = 0x52; public const int WM_HELP = 0x53; public const int WM_USERCHANGED = 0x54; public const int WM_NOTIFYFORMAT = 0x55; public const int WM_CONTEXTMENU = 0x7B; public const int WM_STYLECHANGING = 0x7C; public const int WM_STYLECHANGED = 0x7D; public const int WM_DISPLAYCHANGE = 0x7E; public const int WM_GETICON = 0x7F; public const int WM_SETICON = 0x80; public const int WM_NCCREATE = 0x81; public const int WM_NCDESTROY = 0x82; public const int WM_NCCALCSIZE = 0x83; public const int WM_NCHITTEST = 0x84; public const int WM_NCPAINT = 0x85; public const int WM_NCACTIVATE = 0x86; public const int WM_GETDLGCODE = 0x87; public const int WM_NCMOUSEMOVE = 0xA0; public const int WM_NCLBUTTONDOWN = 0xA1; public const int WM_NCLBUTTONUP = 0xA2; public const int WM_NCLBUTTONDBLCLK = 0xA3; public const int WM_NCRBUTTONDOWN = 0xA4; public const int WM_NCRBUTTONUP = 0xA5; public const int WM_NCRBUTTONDBLCLK = 0xA6; public const int WM_NCMBUTTONDOWN = 0xA7; public const int WM_NCMBUTTONUP = 0xA8; public const int WM_NCMBUTTONDBLCLK = 0xA9; public const int WM_KEYFIRST = 0x100; public const int WM_KEYDOWN = 0x100; public const int WM_KEYUP = 0x101; public const int WM_CHAR = 0x102; public const int WM_DEADCHAR = 0x103; public const int WM_SYSKEYDOWN = 0x104; public const int WM_SYSKEYUP = 0x105; public const int WM_SYSCHAR = 0x106; public const int WM_SYSDEADCHAR = 0x107; public const int WM_KEYLAST = 0x108; public const int WM_IME_STARTCOMPOSITION = 0x10D; public const int WM_IME_ENDCOMPOSITION = 0x10E; public const int WM_IME_COMPOSITION = 0x10F; public const int WM_IME_KEYLAST = 0x10F; public const int WM_INITDIALOG = 0x110; public const int WM_COMMAND = 0x111; public const int WM_SYSCOMMAND = 0x112; public const int WM_TIMER = 0x113; public const int WM_HSCROLL = 0x114; public const int WM_VSCROLL = 0x115; public const int WM_INITMENU = 0x116; public const int WM_INITMENUPOPUP = 0x117; public const int WM_MENUSELECT = 0x11F; public const int WM_MENUCHAR = 0x120; public const int WM_ENTERIDLE = 0x121; public const int WM_CTLCOLORMSGBOX = 0x132; public const int WM_CTLCOLOREDIT = 0x133; public const int WM_CTLCOLORLISTBOX = 0x134; public const int WM_CTLCOLORBTN = 0x135; public const int WM_CTLCOLORDLG = 0x136; public const int WM_CTLCOLORSCROLLBAR = 0x137; public const int WM_CTLCOLORSTATIC = 0x138; public const int WM_MOUSEFIRST = 0x200; public const int WM_MOUSEMOVE = 0x200; public const int WM_LBUTTONDOWN = 0x201; public const int WM_LBUTTONUP = 0x202; public const int WM_LBUTTONDBLCLK = 0x203; public const int WM_RBUTTONDOWN = 0x204; public const int WM_RBUTTONUP = 0x205; public const int WM_RBUTTONDBLCLK = 0x206; public const int WM_MBUTTONDOWN = 0x207; public const int WM_MBUTTONUP = 0x208; public const int WM_MBUTTONDBLCLK = 0x209; public const int WM_MOUSELAST = 0x20A; public const int WM_MOUSEWHEEL = 0x20A; public const int WM_PARENTNOTIFY = 0x210; public const int WM_ENTERMENULOOP = 0x211; public const int WM_EXITMENULOOP = 0x212; public const int WM_NEXTMENU = 0x213; public const int WM_SIZING = 0x214; public const int WM_CAPTURECHANGED = 0x215; public const int WM_MOVING = 0x216; public const int WM_POWERBROADCAST = 0x218; public const int WM_DEVICECHANGE = 0x219; public const int WM_MDICREATE = 0x220; public const int WM_MDIDESTROY = 0x221; public const int WM_MDIACTIVATE = 0x222; public const int WM_MDIRESTORE = 0x223; public const int WM_MDINEXT = 0x224; public const int WM_MDIMAXIMIZE = 0x225; public const int WM_MDITILE = 0x226; public const int WM_MDICASCADE = 0x227; public const int WM_MDIICONARRANGE = 0x228; public const int WM_MDIGETACTIVE = 0x229; public const int WM_MDISETMENU = 0x230; public const int WM_ENTERSIZEMOVE = 0x231; public const int WM_EXITSIZEMOVE = 0x232; public const int WM_DROPFILES = 0x233; public const int WM_MDIREFRESHMENU = 0x234; public const int WM_IME_SETCONTEXT = 0x281; public const int WM_IME_NOTIFY = 0x282; public const int WM_IME_CONTROL = 0x283; public const int WM_IME_COMPOSITIONFULL = 0x284; public const int WM_IME_SELECT = 0x285; public const int WM_IME_CHAR = 0x286; public const int WM_IME_KEYDOWN = 0x290; public const int WM_IME_KEYUP = 0x291; public const int WM_MOUSEHOVER = 0x2A1; public const int WM_NCMOUSELEAVE = 0x2A2; public const int WM_MOUSELEAVE = 0x2A3; public const int WM_CUT = 0x300; public const int WM_COPY = 0x301; public const int WM_PASTE = 0x302; public const int WM_CLEAR = 0x303; public const int WM_UNDO = 0x304; public const int WM_RENDERFORMAT = 0x305; public const int WM_RENDERALLFORMATS = 0x306; public const int WM_DESTROYCLIPBOARD = 0x307; public const int WM_DRAWCLIPBOARD = 0x308; public const int WM_PAINTCLIPBOARD = 0x309; public const int WM_VSCROLLCLIPBOARD = 0x30A; public const int WM_SIZECLIPBOARD = 0x30B; public const int WM_ASKCBFORMATNAME = 0x30C; public const int WM_CHANGECBCHAIN = 0x30D; public const int WM_HSCROLLCLIPBOARD = 0x30E; public const int WM_QUERYNEWPALETTE = 0x30F; public const int WM_PALETTEISCHANGING = 0x310; public const int WM_PALETTECHANGED = 0x311; public const int WM_HOTKEY = 0x312; public const int WM_PRINT = 0x317; public const int WM_PRINTCLIENT = 0x318; public const int WM_HANDHELDFIRST = 0x358; public const int WM_HANDHELDLAST = 0x35F; public const int WM_PENWINFIRST = 0x380; public const int WM_PENWINLAST = 0x38F; public const int WM_COALESCE_FIRST = 0x390; public const int WM_COALESCE_LAST = 0x39F; public const int WM_DDE_FIRST = 0x3E0; public const int WM_DDE_INITIATE = 0x3E0; public const int WM_DDE_TERMINATE = 0x3E1; public const int WM_DDE_ADVISE = 0x3E2; public const int WM_DDE_UNADVISE = 0x3E3; public const int WM_DDE_ACK = 0x3E4; public const int WM_DDE_DATA = 0x3E5; public const int WM_DDE_REQUEST = 0x3E6; public const int WM_DDE_POKE = 0x3E7; public const int WM_DDE_EXECUTE = 0x3E8; public const int WM_DDE_LAST = 0x3E8; public const int WM_USER = 0x400; public const int WM_APP = 0x8000; #endregion #region Importfunktionen aus User32.dll // Wenn möglich sollte beim Aufruf der Funktionen immer mit IntPtr gearbeitet werden, da es sonst zu Adressierungs-Fehlern auf 64Bit-Systemen kommen kann! // http://www.pinvoke.net/default.aspx/user32.GetDesktopWindow [DllImport("user32", SetLastError = true)] public static extern IntPtr GetDesktopWindow(); // http://www.pinvoke.net/default.aspx/user32.FindWindow [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr FindWindow(string lpClassName, string lpWindowName); // http://www.pinvoke.net/default.aspx/user32.GetWindowTextLength [DllImport("user32", SetLastError = true)] private static extern int GetWindowTextLength(IntPtr hWnd); // http://www.pinvoke.net/default.aspx/user32.GetWindowText [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private static extern int GetWindowText(IntPtr hWnd, StringBuilder lpString, int nMaxCount); // http://www.pinvoke.net/default.aspx/user32.SetForegroundWindow [DllImport("user32", SetLastError = true)] private static extern bool SetForegroundWindow(IntPtr hWnd); // http://www.pinvoke.net/default.aspx/user32.IsIconic [DllImport("user32", SetLastError = true)] private static extern bool IsIconic(IntPtr hWnd); // http://www.pinvoke.net/default.aspx/user32.OpenIcon [DllImport("user32", SetLastError = true)] private static extern bool OpenIcon(IntPtr hWnd); // http://www.pinvoke.net/default.aspx/user32.GetClassName [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private static extern int GetClassName(IntPtr hWnd, StringBuilder lpClassName, int nMaxCount); // http://www.pinvoke.net/default.aspx/user32.SendMessage [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SendMessage(IntPtr hWnd, uint uiMsg, IntPtr wParam, IntPtr lParam); // http://boycook.wordpress.com/2008/07/29/c-win32-messaging-with-sendmessage-and-wm_copydata/ // http://craigcook.co.uk/samples/MessageHelper.cs.txt [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private static extern IntPtr SendMessage(IntPtr hWnd, uint uiMsg, IntPtr wParam, ref SCopyData lParam); // http://www.pinvoke.net/default.aspx/user32.PostMessage [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] private static extern bool PostMessage(IntPtr hWnd, uint iMsg, IntPtr wParam, IntPtr lParam); #endregion public CAppCtrlObj() { } /// <summary> /// ermittelt Fensterhandle des Desktops /// </summary> /// <returns>Handle</returns> public IntPtr GetDesktopWindowHandle() { return GetDesktopWindow(); } /// <summary> /// ermittelt Fensterhandle /// </summary> /// <param name="sWindowTitle">Fenstertitel</param> /// <param name="sWindowClassName">Name der zugehörigen Fensterklasse, kann null sein</param> /// <returns>Handle</returns> public IntPtr GetWindowHandle(string sWindowTitle, string sWindowClassName) { return FindWindow(sWindowClassName, sWindowTitle); } /// <summary> /// versucht Fenster zu aktivieren /// </summary> /// <param name="iptrWindowHandle">Fensterhandle</param> /// <returns>true, false</returns> public bool ActivateWindow(IntPtr iptrWindowHandle) { bool bRetVal = false; if (iptrWindowHandle != null) { bool bGo = true; if (IsIconic(iptrWindowHandle)) { bGo = OpenIcon(iptrWindowHandle); } if (bGo) { bRetVal = SetForegroundWindow(iptrWindowHandle); } } return bRetVal; } /// <summary> /// versucht Fenster zu aktivieren /// </summary> /// <param name="process">Process-Objekt</param> /// <returns>true, false</returns> public bool ActivateWindow(Process process) { return (process != null) ? this.ActivateWindow(process.MainWindowHandle) : false; } /// <summary> /// ermittelt Klassenname eines Fensters /// </summary> /// <param name="sWindowTitle">Fenstername</param> /// <returns>Klassenname des Fensters</returns> public string GetWindowClassName(string sWindowTitle) { string sRetVal = string.Empty; IntPtr hWnd = FindWindow(null, sWindowTitle); if (hWnd != null) { StringBuilder classname = new StringBuilder(255); if (GetClassName(hWnd, classname, 255) != 0) { sRetVal = classname.ToString(); } } return sRetVal; } /// <summary> /// Nachricht an ein Fenster senden, wartet auf Ausführung /// </summary> /// <param name="hWnd">Fensterhandle</param> /// <param name="iMsg">Nachrichten-ID</param> /// <param name="wParam">1. Parameter, wenn nicht benötigt, dann IntPtr.Zero setzen</param> /// <param name="lParam">2. Parameter, wenn nicht benötigt, dann IntPtr.Zero setzen</param> /// <returns>Status</returns> public IntPtr SendMessageToWindow(IntPtr hWnd, uint uiMsg, IntPtr wParam, IntPtr lParam) { return SendMessage(hWnd, uiMsg, wParam, lParam); } /// <summary> /// String mittels WM_COPYDATA an ein Fenster senden, wartet auf Ausführung /// </summary> /// <param name="hWnd">Fensterhandle</param> /// <param name="wParam">1. Parameter, wenn nicht benötigt, dann IntPtr.Zero setzen</param> /// <param name="sMessage">2. Parameter als Nachrichtenstring</param> /// <returns>Status</returns> public IntPtr SendStringMessageToWindow(IntPtr hWnd, IntPtr wParam, string sMessage) { byte[] sarr = Encoding.Default.GetBytes(sMessage); SCopyData cds; cds.dwData = IntPtr.Zero; cds.lpData = sMessage; cds.cbData = sarr.Length + 1; return SendMessage(hWnd, WM_COPYDATA, wParam, ref cds); } /// <summary> /// Nachricht dem MessageQueue des Erzeugerthreads eines Fensters hinzufügen, wartet nicht auf Ausführung /// </summary> /// <param name="hWnd">Fensterhandle</param> /// <param name="iMsg">Nachrichten-ID</param> /// <param name="wParam">1. Parameter, wenn nicht benötigt, dann IntPtr.Zero setzen</param> /// <param name="lParam">2. Parameter, wenn nicht benötigt, dann IntPtr.Zero setzen</param> /// <returns>true, false</returns> public bool PostMessageToWindow(IntPtr hWnd, uint iMsg, IntPtr wParam, IntPtr lParam) { return PostMessage(hWnd, iMsg, wParam, lParam); } /// <summary> /// schließt das Hauptfenster eines Prozesses /// </summary> /// <param name="process">der Prozess, der beendet werden soll</param> /// <param name="bForce">Schließen erzwingen (Kill)?</param> /// <param name="bWaitForExit">Auf Beendigung warten?</param> /// <param name="iExitWaitTimeInMs">Zeit für das Warten auf Beendigung</param> /// <returns>true, false</returns> public bool CloseWindow(Process process, bool bForce, bool bWaitForExit, int iExitWaitTimeInMs) { bool bRetVal = false; if (process.CloseMainWindow()) { if (bWaitForExit) { bRetVal = process.WaitForExit(iExitWaitTimeInMs); } else { bRetVal = true; } } else { if (bForce) { process.Kill(); bRetVal = true; } } return bRetVal; } /// <summary> /// Startet eine Datei, prüft, ob Datei vorhanden /// </summary> /// <param name="sFileName">Pfad und Dateiname</param> /// <param name="sArguments">Argumentliste</param> /// <param name="bHidden">Prozess versteckt starten?</param> /// <param name="bMaximized">Wenn nicht versteckt, maximieren?</param> /// <returns>Prozess-ID, im Fehlerfall -1</returns> public int StartApplication(string sFileName, string sArguments, bool bHidden, bool bMaximized) { int iRetVal = -1; if (File.Exists(sFileName)) { Process process = new Process(); process.StartInfo.UseShellExecute = true; process.StartInfo.WindowStyle = bHidden ? ProcessWindowStyle.Hidden : bMaximized ? ProcessWindowStyle.Maximized : ProcessWindowStyle.Normal; process.StartInfo.FileName = sFileName; process.StartInfo.Arguments = sArguments; if (process.Start()) { iRetVal = process.Id; } } return iRetVal; } /// <summary> /// Prozess anhand einer Prozess-ID im System ermitteln /// </summary> /// <param name="iProcessID">eindeutige systemweite Prozess-ID</param> /// <returns>Prozess</returns> public Process GetProcess(int iProcessID) { return Process.GetProcessById(iProcessID); } }