using System; using System.Collections.Generic; using System.Text; using System.IO; using System.Diagnostics; using System.Threading; using System.Windows.Forms; using System.Drawing; using System.Reflection; using System.Runtime.InteropServices; using System.Runtime.InteropServices.ComTypes; // TODO Move most of this to the Platform project namespace Foo.Platform.Win32 { public class MyWin32Wnd : IWin32Window { private IntPtr m_Handle = IntPtr.Zero; public IntPtr Handle { get{return m_Handle;} set{m_Handle = value;} } } //// // Win32 Enums //// #region Win32 Enums public enum WindowAction : int { SW_HIDE = 0, SW_SHOWNORMAL = 1, SW_NORMAL = 1, SW_SHOWMINIMIZED = 2, SW_SHOWMAXIMIZED = 3, SW_MAXIMIZE = 3, SW_SHOWNOACTIVATE = 4, SW_SHOW = 5, SW_MINIMIZE = 6, SW_SHOWMINNOACTIVE = 7, SW_SHOWNA = 8, SW_RESTORE = 9, SW_SHOWDEFAULT = 10, SW_FORCEMINIMIZE = 11, SW_MAX = 11 } public enum WindowLong : int { GWL_EXSTYLE = -20, GWL_STYLE = -16, GWL_WNDPROC = -4, GWL_HINSTANCE = -6, GWL_ID = -12, GWL_USERDATA = -21, DWL_DLGPROC = 4, DWL_MSGRESULT = 0, DWL_USER = 8 } public enum WindowStyles : uint { WS_MAXIMIZE = 0x01000000, WS_VISIBLE = 0x10000000, WS_POPUP = 0x80000000, WS_BORDER = 0x00800000, WS_CAPTION = 0x00C00000, WS_CHILD = 0x40000000, WS_CHILDWINDOW = 0x40000000, WS_CLIPCHILDREN = 0x02000000, WS_CLIPSIBLINGS = 0x04000000, WS_DISABLED = 0x08000000, WS_DLGFRAME = 0x00400000, WS_GROUP = 0x00020000 } public enum WindowMessage : int { WM_NULL = 0x0000, WM_CREATE = 0x0001, WM_DESTROY = 0x0002, WM_MOVE = 0x0003, WM_SIZE = 0x0005, WM_ACTIVATE = 0x0006, WM_SETFOCUS = 0x0007, WM_KILLFOCUS = 0x0008, WM_ENABLE = 0x000A, WM_SETREDRAW = 0x000B, WM_SETTEXT = 0x000C, WM_GETTEXT = 0x000D, WM_GETTEXTLENGTH = 0x000E, WM_PAINT = 0x000F, WM_CLOSE = 0x0010, WM_QUERYENDSESSION = 0x0011, WM_QUIT = 0x0012, WM_QUERYOPEN = 0x0013, WM_ERASEBKGND = 0x0014, WM_SYSCOLORCHANGE = 0x0015, WM_ENDSESSION = 0x0016, WM_SHOWWINDOW = 0x0018, WM_CTLCOLOR = 0x0019, WM_WININICHANGE = 0x001A, WM_SETTINGCHANGE = 0x001A, WM_DEVMODECHANGE = 0x001B, WM_ACTIVATEAPP = 0x001C, WM_FONTCHANGE = 0x001D, WM_TIMECHANGE = 0x001E, WM_CANCELMODE = 0x001F, WM_SETCURSOR = 0x0020, WM_MOUSEACTIVATE = 0x0021, WM_CHILDACTIVATE = 0x0022, WM_QUEUESYNC = 0x0023, WM_GETMINMAXINFO = 0x0024, WM_PAINTICON = 0x0026, WM_ICONERASEBKGND = 0x0027, WM_NEXTDLGCTL = 0x0028, WM_SPOOLERSTATUS = 0x002A, WM_DRAWITEM = 0x002B, WM_MEASUREITEM = 0x002C, WM_DELETEITEM = 0x002D, WM_VKEYTOITEM = 0x002E, WM_CHARTOITEM = 0x002F, WM_SETFONT = 0x0030, WM_GETFONT = 0x0031, WM_SETHOTKEY = 0x0032, WM_GETHOTKEY = 0x0033, WM_QUERYDRAGICON = 0x0037, WM_COMPAREITEM = 0x0039, WM_GETOBJECT = 0x003D, WM_COMPACTING = 0x0041, WM_COMMNOTIFY = 0x0044, WM_WINDOWPOSCHANGING = 0x0046, WM_WINDOWPOSCHANGED = 0x0047, WM_POWER = 0x0048, WM_COPYDATA = 0x004A, WM_CANCELJOURNAL = 0x004B, WM_NOTIFY = 0x004E, WM_INPUTLANGCHANGEREQUEST = 0x0050, WM_INPUTLANGCHANGE = 0x0051, WM_TCARD = 0x0052, WM_HELP = 0x0053, WM_USERCHANGED = 0x0054, WM_NOTIFYFORMAT = 0x0055, WM_CONTEXTMENU = 0x007B, WM_STYLECHANGING = 0x007C, WM_STYLECHANGED = 0x007D, WM_DISPLAYCHANGE = 0x007E, WM_GETICON = 0x007F, WM_SETICON = 0x0080, WM_NCCREATE = 0x0081, WM_NCDESTROY = 0x0082, WM_NCCALCSIZE = 0x0083, WM_NCHITTEST = 0x0084, WM_NCPAINT = 0x0085, WM_NCACTIVATE = 0x0086, WM_GETDLGCODE = 0x0087, WM_SYNCPAINT = 0x0088, WM_NCMOUSEMOVE = 0x00A0, WM_NCLBUTTONDOWN = 0x00A1, WM_NCLBUTTONUP = 0x00A2, WM_NCLBUTTONDBLCLK = 0x00A3, WM_NCRBUTTONDOWN = 0x00A4, WM_NCRBUTTONUP = 0x00A5, WM_NCRBUTTONDBLCLK = 0x00A6, WM_NCMBUTTONDOWN = 0x00A7, WM_NCMBUTTONUP = 0x00A8, WM_NCMBUTTONDBLCLK = 0x00A9, WM_KEYDOWN = 0x0100, WM_KEYUP = 0x0101, WM_CHAR = 0x0102, WM_DEADCHAR = 0x0103, WM_SYSKEYDOWN = 0x0104, WM_SYSKEYUP = 0x0105, WM_SYSCHAR = 0x0106, WM_SYSDEADCHAR = 0x0107, WM_KEYLAST = 0x0108, WM_IME_STARTCOMPOSITION = 0x010D, WM_IME_ENDCOMPOSITION = 0x010E, WM_IME_COMPOSITION = 0x010F, WM_IME_KEYLAST = 0x010F, WM_INITDIALOG = 0x0110, WM_COMMAND = 0x0111, WM_SYSCOMMAND = 0x0112, WM_TIMER = 0x0113, WM_HSCROLL = 0x0114, WM_VSCROLL = 0x0115, WM_INITMENU = 0x0116, WM_INITMENUPOPUP = 0x0117, WM_MENUSELECT = 0x011F, WM_MENUCHAR = 0x0120, WM_ENTERIDLE = 0x0121, WM_MENURBUTTONUP = 0x0122, WM_MENUDRAG = 0x0123, WM_MENUGETOBJECT = 0x0124, WM_UNINITMENUPOPUP = 0x0125, WM_MENUCOMMAND = 0x0126, WM_CTLCOLORMSGBOX = 0x0132, WM_CTLCOLOREDIT = 0x0133, WM_CTLCOLORLISTBOX = 0x0134, WM_CTLCOLORBTN = 0x0135, WM_CTLCOLORDLG = 0x0136, WM_CTLCOLORSCROLLBAR = 0x0137, WM_CTLCOLORSTATIC = 0x0138, WM_MOUSEMOVE = 0x0200, WM_LBUTTONDOWN = 0x0201, WM_LBUTTONUP = 0x0202, WM_LBUTTONDBLCLK = 0x0203, WM_RBUTTONDOWN = 0x0204, WM_RBUTTONUP = 0x0205, WM_RBUTTONDBLCLK = 0x0206, WM_MBUTTONDOWN = 0x0207, WM_MBUTTONUP = 0x0208, WM_MBUTTONDBLCLK = 0x0209, WM_MOUSEWHEEL = 0x020A, WM_PARENTNOTIFY = 0x0210, WM_ENTERMENULOOP = 0x0211, WM_EXITMENULOOP = 0x0212, WM_NEXTMENU = 0x0213, WM_SIZING = 0x0214, WM_CAPTURECHANGED = 0x0215, WM_MOVING = 0x0216, WM_DEVICECHANGE = 0x0219, WM_MDICREATE = 0x0220, WM_MDIDESTROY = 0x0221, WM_MDIACTIVATE = 0x0222, WM_MDIRESTORE = 0x0223, WM_MDINEXT = 0x0224, WM_MDIMAXIMIZE = 0x0225, WM_MDITILE = 0x0226, WM_MDICASCADE = 0x0227, WM_MDIICONARRANGE = 0x0228, WM_MDIGETACTIVE = 0x0229, WM_MDISETMENU = 0x0230, WM_ENTERSIZEMOVE = 0x0231, WM_EXITSIZEMOVE = 0x0232, WM_DROPFILES = 0x0233, WM_MDIREFRESHMENU = 0x0234, WM_IME_SETCONTEXT = 0x0281, WM_IME_NOTIFY = 0x0282, WM_IME_CONTROL = 0x0283, WM_IME_COMPOSITIONFULL = 0x0284, WM_IME_SELECT = 0x0285, WM_IME_CHAR = 0x0286, WM_IME_REQUEST = 0x0288, WM_IME_KEYDOWN = 0x0290, WM_IME_KEYUP = 0x0291, WM_MOUSEHOVER = 0x02A1, WM_MOUSELEAVE = 0x02A3, WM_CUT = 0x0300, WM_COPY = 0x0301, WM_PASTE = 0x0302, WM_CLEAR = 0x0303, WM_UNDO = 0x0304, WM_RENDERFORMAT = 0x0305, WM_RENDERALLFORMATS = 0x0306, WM_DESTROYCLIPBOARD = 0x0307, WM_DRAWCLIPBOARD = 0x0308, WM_PAINTCLIPBOARD = 0x0309, WM_VSCROLLCLIPBOARD = 0x030A, WM_SIZECLIPBOARD = 0x030B, WM_ASKCBFORMATNAME = 0x030C, WM_CHANGECBCHAIN = 0x030D, WM_HSCROLLCLIPBOARD = 0x030E, WM_QUERYNEWPALETTE = 0x030F, WM_PALETTEISCHANGING = 0x0310, WM_PALETTECHANGED = 0x0311, WM_HOTKEY = 0x0312, WM_PRINT = 0x0317, WM_PRINTCLIENT = 0x0318, WM_HANDHELDFIRST = 0x0358, WM_HANDHELDLAST = 0x035F, WM_AFXFIRST = 0x0360, WM_AFXLAST = 0x037F, WM_PENWINFIRST = 0x0380, WM_PENWINLAST = 0x038F, WM_APP = 0x8000, WM_USER = 0x0400, WM_REFLECT = WM_USER + 0x1c00, WM_CHANGEUISTATE = 0x0127, WM_UPDATEUISTATE = 0x0128, WM_QUERYUISTATE = 0x0129 } public enum WindowUIState : int { UIS_SET = 1, UIS_CLEAR = 2, UIS_INITIALIZE = 3 } public enum CSIDL : int { CSIDL_DESKTOP = 0x0000, // CSIDL_INTERNET = 0x0001, // Internet Explorer (icon on desktop) CSIDL_PROGRAMS = 0x0002, // Start Menu\Programs CSIDL_CONTROLS = 0x0003, // My Computer\Control Panel CSIDL_PRINTERS = 0x0004, // My Computer\Printers CSIDL_PERSONAL = 0x0005, // My Documents CSIDL_FAVORITES = 0x0006, // \Favorites CSIDL_STARTUP = 0x0007, // Start Menu\Programs\Startup CSIDL_RECENT = 0x0008, // \Recent CSIDL_SENDTO = 0x0009, // \SendTo CSIDL_BITBUCKET = 0x000a, // \Recycle Bin CSIDL_STARTMENU = 0x000b, // \Start Menu CSIDL_MYDOCUMENTS = 0x000c, // logical "My Documents" desktop icon CSIDL_MYMUSIC = 0x000d, // "My Music" folder CSIDL_MYVIDEO = 0x000e, // "My Videos" folder CSIDL_DESKTOPDIRECTORY = 0x0010, // \Desktop CSIDL_DRIVES = 0x0011, // My Computer CSIDL_NETWORK = 0x0012, // Network Neighborhood (My Network Places) CSIDL_NETHOOD = 0x0013, // \nethood CSIDL_FONTS = 0x0014, // windows\fonts CSIDL_TEMPLATES = 0x0015, CSIDL_COMMON_STARTMENU = 0x0016, // All Users\Start Menu CSIDL_COMMON_PROGRAMS = 0X0017, // All Users\Start Menu\Programs CSIDL_COMMON_STARTUP = 0x0018, // All Users\Startup CSIDL_COMMON_DESKTOPDIRECTORY = 0x0019, // All Users\Desktop CSIDL_APPDATA = 0x001a, // \Application Data CSIDL_PRINTHOOD = 0x001b, // \PrintHood CSIDL_LOCAL_APPDATA = 0x001c, // \Local Settings\Applicaiton Data (non roaming) CSIDL_ALTSTARTUP = 0x001d, // non localized startup CSIDL_COMMON_ALTSTARTUP = 0x001e, // non localized common startup CSIDL_COMMON_FAVORITES = 0x001f, CSIDL_INTERNET_CACHE = 0x0020, CSIDL_COOKIES = 0x0021, CSIDL_HISTORY = 0x0022, CSIDL_COMMON_APPDATA = 0x0023, // All Users\Application Data CSIDL_WINDOWS = 0x0024, // GetWindowsDirectory() CSIDL_SYSTEM = 0x0025, // GetSystemDirectory() CSIDL_PROGRAM_FILES = 0x0026, // C:\Program Files CSIDL_MYPICTURES = 0x0027, // C:\Program Files\My Pictures CSIDL_PROFILE = 0x0028, // USERPROFILE CSIDL_SYSTEMX86 = 0x0029, // x86 system directory on RISC CSIDL_PROGRAM_FILESX86 = 0x002a, // x86 C:\Program Files on RISC CSIDL_PROGRAM_FILES_COMMON = 0x002b, // C:\Program Files\Common CSIDL_PROGRAM_FILES_COMMONX86 = 0x002c, // x86 Program Files\Common on RISC CSIDL_COMMON_TEMPLATES = 0x002d, // All Users\Templates CSIDL_COMMON_DOCUMENTS = 0x002e, // All Users\Documents CSIDL_COMMON_ADMINTOOLS = 0x002f, // All Users\Start Menu\Programs\Administrative Tools CSIDL_ADMINTOOLS = 0x0030, // \Start Menu\Programs\Administrative Tools CSIDL_CONNECTIONS = 0x0031, // Network and Dial-up Connections CSIDL_COMMON_MUSIC = 0x0035, // All Users\My Music CSIDL_COMMON_PICTURES = 0x0036, // All Users\My Pictures CSIDL_COMMON_VIDEO = 0x0037, // All Users\My Video CSIDL_CDBURN_AREA = 0x003b // USERPROFILE\Local } public enum SHGFP_TYPE : int { SHGFP_TYPE_CURRENT = 0, SHGFP_TYPE_DEFAULT = 1 } public enum DesiredAccess : int { DELETE = 0x00010000, // Required to delete the object. READ_CONTROL = 0x00020000, // Required to read information in the security descriptor for the object, not including the information in the SACL. To read or write the SACL, you must request the ACCESS_SYSTEM_SECURITY access right. For more information, see SACL Access Right. SYNCHRONIZE = 0x00100000, // The right to use the object for synchronization. This enables a thread to wait until the object is in the signaled state. WRITE_DAC = 0x00040000, // Required to modify the DACL in the security descriptor for the object. WRITE_OWNER = 0x00080000 // Required to change the owner in the security descriptor for the object. } public enum WaitTime : uint { IGNORE = 0, // Ignore signal INFINITE = 0xFFFFFFFF // Infinite timeout } public enum SystemMetric : int { SM_CXSCREEN = 0, SM_CYSCREEN = 1, SM_CXVSCROLL = 2, SM_CYHSCROLL = 3, SM_CYCAPTION = 4, SM_CXBORDER = 5, SM_CYBORDER = 6, SM_CXDLGFRAME = 7, SM_CYDLGFRAME = 8, SM_CYVTHUMB = 9, SM_CXHTHUMB = 10, SM_CXICON = 11, SM_CYICON = 12, SM_CXCURSOR = 13, SM_CYCURSOR = 14, SM_CYMENU = 15, SM_CXFULLSCREEN = 16, SM_CYFULLSCREEN = 17, SM_CYKANJIWINDOW = 18, SM_MOUSEPRESENT = 19, SM_CYVSCROLL = 20, SM_CXHSCROLL = 21, SM_DEBUG = 22, SM_SWAPBUTTON = 23, SM_RESERVED1 = 24, SM_RESERVED2 = 25, SM_RESERVED3 = 26, SM_RESERVED4 = 27, SM_CXMIN = 28, SM_CYMIN = 29, SM_CXSIZE = 30, SM_CYSIZE = 31, SM_CXFRAME = 32, SM_CYFRAME = 33, SM_CXMINTRACK = 34, SM_CYMINTRACK = 35, SM_CXDOUBLECLK = 36, SM_CYDOUBLECLK = 37, SM_CXICONSPACING = 38, SM_CYICONSPACING = 39, SM_MENUDROPALIGNMENT = 40, SM_PENWINDOWS = 41, SM_DBCSENABLED = 42, SM_CMOUSEBUTTONS = 43 } public enum SetWindowPosFlags : uint { SWP_NOSIZE = 0x0001, SWP_NOMOVE = 0x0002, SWP_NOZORDER = 0x0004, SWP_NOREDRAW = 0x0008, SWP_NOACTIVATE = 0x0010, SWP_FRAMECHANGED = 0x0020, SWP_SHOWWINDOW = 0x0040, SWP_HIDEWINDOW = 0x0080, SWP_NOCOPYBITS = 0x0100, SWP_NOOWNERZORDER = 0x0200, SWP_NOSENDCHANGING = 0x0400, SWP_DRAWFRAME = SWP_FRAMECHANGED, SWP_NOREPOSITION = SWP_NOOWNERZORDER } public enum WindowLayerAttributes { LWA_COLORKEY = 0x00000001, LWA_ALPHA = 0x00000002 } public enum WindowPos : int { HWND_TOP = 0, HWND_BOTTOM = 1, HWND_TOPMOST = -1, HWND_NOTOPMOST = -2 } public enum VK : ushort { SHIFT = 0x10, CONTROL = 0x11, MENU = 0x12, ESCAPE = 0x1B, BACK = 0x08, TAB = 0x09, RETURN = 0x0D, PRIOR = 0x21, NEXT = 0x22, END = 0x23, HOME = 0x24, LEFT = 0x25, UP = 0x26, RIGHT = 0x27, DOWN = 0x28, SELECT = 0x29, PRINT = 0x2A, EXECUTE = 0x2B, SNAPSHOT = 0x2C, INSERT = 0x2D, DELETE = 0x2E, HELP = 0x2F, NUMPAD0 = 0x60, NUMPAD1 = 0x61, NUMPAD2 = 0x62, NUMPAD3 = 0x63, NUMPAD4 = 0x64, NUMPAD5 = 0x65, NUMPAD6 = 0x66, NUMPAD7 = 0x67, NUMPAD8 = 0x68, NUMPAD9 = 0x69, MULTIPLY = 0x6A, ADD = 0x6B, SEPARATOR = 0x6C, SUBTRACT = 0x6D, DECIMAL = 0x6E, DIVIDE = 0x6F, F1 = 0x70, F2 = 0x71, F3 = 0x72, F4 = 0x73, F5 = 0x74, F6 = 0x75, F7 = 0x76, F8 = 0x77, F9 = 0x78, F10 = 0x79, F11 = 0x7A, F12 = 0x7B, OEM_1 = 0xBA, // ',:' for US OEM_PLUS = 0xBB, // '+' any country OEM_COMMA = 0xBC, // ',' any country OEM_MINUS = 0xBD, // '-' any country OEM_PERIOD = 0xBE, // '.' any country OEM_2 = 0xBF, // '/?' for US OEM_3 = 0xC0, // '`~' for US MEDIA_NEXT_TRACK = 0xB0, MEDIA_PREV_TRACK = 0xB1, MEDIA_STOP = 0xB2, MEDIA_PLAY_PAUSE = 0xB3, LWIN = 0x5B, RWIN = 0x5C } public enum AssocF : ushort { Init_NoRemapCLSID = 0x1, Init_ByExeName = 0x2, Open_ByExeName = 0x2, Init_DefaultToStar = 0x4, Init_DefaultToFolder = 0x8, NoUserSettings = 0x10, NoTruncate = 0x20, Verify = 0x40, RemapRunDll = 0x80, NoFixUps = 0x100, IgnoreBaseClass = 0x200 } public enum AssocStr : ushort { Command = 1, Executable, FriendlyDocName, FriendlyAppName, NoOpen, ShellNewValue, DDECommand, DDEIfExec, DDEApplication, DDETopic } #endregion //// // Win32 Structures //// #region Win32 Structures [StructLayout(LayoutKind.Sequential)] public struct RECT { public int left; public int top; public int right; public int bottom; public Rectangle AsRectangle { get { return new Rectangle(this.left, this.top, this.right - this.left, this.bottom - this.top); } } public static RECT FromXYWH(int x, int y, int width, int height) { RECT rect = new RECT(); rect.left = x; rect.top = y; rect.right = x + width; rect.bottom = y + height; return rect; } public static RECT FromRectangle(Rectangle rectangle) { RECT rect = new RECT(); rect.left = rectangle.Left; rect.top = rectangle.Top; rect.right = rectangle.Right; rect.bottom = rectangle.Bottom; return rect; } } [StructLayout(LayoutKind.Sequential)] public struct SIZE { public int cx; public int cy; } [StructLayout(LayoutKind.Sequential)] public struct ShellExecuteInfo { public int cbSize; public uint fMask; public IntPtr hwnd; public string lpVerb; public string lpFile; public string lpParameters; public string lpDirectory; public uint nShow; public IntPtr hInstApp; public IntPtr lpIDList; public string lpClass; public IntPtr hkeyClass; public uint dwHotKey; public IntPtr hIcon_Monitor; // union DUMMYUNIONNAME public IntPtr hProcess; } [StructLayout(LayoutKind.Explicit, Size = 28)] public struct INPUT { [FieldOffset(0)] public uint type; [FieldOffset(4)] public KEYBDINPUT ki; }; [StructLayout(LayoutKind.Sequential)] public struct KEYBDINPUT { public ushort wVk; public ushort wScan; public uint dwFlags; public long time; public uint dwExtraInfo; }; [StructLayout(LayoutKind.Sequential)] public struct MONITORINFOEX { public int cbSize; public RECT rcMonitor; public RECT rcWork; public int dwFlags; [MarshalAs(UnmanagedType.ByValTStr,SizeConst=32)] public string szDeviceName; } #endregion //// // .Net Win32 Wrapper Functions //// public class Win32_WrapperFunc { /// /// Get a windows client rectangle in a .NET structure /// /// The window handle to look up /// The rectangle public static Rectangle GetClientRect(IntPtr hwnd) { RECT rect = new RECT(); Win32Functions.GetClientRect(hwnd, out rect); return rect.AsRectangle; } /// /// Get a windows rectangle in a .NET structure /// /// The window handle to look up /// The rectangle public static Rectangle GetWindowRect(IntPtr hwnd) { RECT rect = new RECT(); Win32Functions.GetWindowRect(hwnd, out rect); return rect.AsRectangle; } /// /// Get's the System's registered file for the corresponding File /// /// full file name and path /// Returns Registered exe for file in Uppercase public static string GetRegisteredExeForFile(string fileNameAndPath) { if (!String.IsNullOrEmpty(fileNameAndPath)) { bool bIsValidExe = false; string strExeOrDllPath = string.Empty; bool bSuccess = Win32_WrapperFunc.FindExeOrDll(fileNameAndPath, out strExeOrDllPath, out bIsValidExe); if (bSuccess && bIsValidExe) return Path.GetFileName(strExeOrDllPath).ToUpper(); } return string.Empty; } /// /// Useful for finding who is responsible by Shell32 to handle this file /// /// full qualifying path to File /// will contain that path that is found in the registry /// true if the return value is a valid exe, false if it is a Dll /// true if a match was found, false otherwise public static bool FindExeOrDll(string fileNameAndPath, out string strExeOrDllPath, out bool IsValidExe) { if (!String.IsNullOrEmpty(fileNameAndPath)) { // Try FindExecutable first StringBuilder retStr = new StringBuilder(); int ret = (int)Win32Functions.FindExecutable(fileNameAndPath, null, retStr); strExeOrDllPath = retStr.ToString(); // If FindExe Failed, try AssocQueryString instead if (String.IsNullOrEmpty(strExeOrDllPath)) { string Ext = Path.GetExtension(fileNameAndPath); StringBuilder retStr2 = new StringBuilder(); uint pcchOut = Win32_Constants.MAX_PATH; Win32Functions.AssocQueryString(0, AssocStr.Executable, Ext, "open", retStr2, ref pcchOut); if (retStr2.Length > 0) strExeOrDllPath = retStr2.ToString(); } IsValidExe = false; if (!String.IsNullOrEmpty(strExeOrDllPath)) { string Ext = Path.GetExtension(strExeOrDllPath); IsValidExe = (Ext.ToUpper() == ".EXE"); return true; } } strExeOrDllPath = string.Empty; IsValidExe = false; return false; } /// /// Uses Shell32 to get the Windows location on this computer /// /// path to windows dir on this machine public static string GetWindowsPath() { StringBuilder windowsPath = new StringBuilder(); Win32Functions.SHGetFolderPath(IntPtr.Zero, (int)CSIDL.CSIDL_WINDOWS, IntPtr.Zero, (int)SHGFP_TYPE.SHGFP_TYPE_CURRENT, windowsPath); return windowsPath.ToString(); } /// /// Use this function to set transparency of a layered top level window. /// This will only work on Windows that are part of your own Process Space. calling this on external windows, /// outside of your process SetLayeredWindowAttributes() will fail. /// /// the window to make or unmake transparent /// 0 for transparent 255 for totally visible public static void SetAlphaChannel(IntPtr hWnd, byte alpha) { long dwStyle = (long) Win32Functions.GetWindowLong(hWnd, (int) ((int) WindowLong.GWL_EXSTYLE | (int) Win32_Constants.WS_EX_LAYERED)); long retVal = Win32Functions.SetWindowLong(hWnd, (int) WindowLong.GWL_EXSTYLE, (int) dwStyle); if (retVal == 0) Trace.Write("SetAlphaChannel's SetWindowLong Failed"); bool bSuccess = Win32Functions.SetLayeredWindowAttributes(hWnd, (int)Win32Functions.RGB(0, 0, 0), alpha, (uint)(WindowLayerAttributes.LWA_ALPHA)); if (!bSuccess) Trace.Write("SetAlphaChannel's SetLayeredWindowAttributes Failed"); } /// /// Could be useful later - maybe /// /// //public static Rectangle GetAbsoluteClientRect(IntPtr hWnd) //{ // //Rectangle windowRect = Win32Functions.GetWindowRect(hWnd); // //Rectangle clientRect = Win32Functions.GetClientRect(hWnd); // //// This gives us the width of the left, right and bottom chrome - we can then determine the top height // //int chromeWidth = (int)((windowRect.Width - clientRect.Width) / 2); // //return new Rectangle(new Point(windowRect.X + chromeWidth, windowRect.Y + (windowRect.Height - clientRect.Height - chromeWidth)), clientRect.Size); //} } //// // Win32 Constants //// public class Win32_Constants { public const ushort KEYEVENTF_KEYUP = 0x0002; public const int SRCCOPY = 0x00CC0020; public const int CAPTUREBLT = 0x40000000; public const int MONITOR_DEFAULTTONEAREST = 0x00000002; public const int WM_USER = 0x0400; public const int WS_EX_LAYERED = 0x00080000; public const int MAX_PATH = 260; } //// // Win32 Functions //// public class Win32Functions { // Declare the Log4net Variable private static log4net.ILog Log = Logger.GetLog4NetInterface(MethodBase.GetCurrentMethod().DeclaringType); public static int LOWORD(int n) { return (n & 0xffff); } public static int HIWORD(int n) { return ((n >> 16) & 0xffff); } public static int RGB(int r, int g, int b) { int rs = r & 0xffff; int gs = (g << 8) & 0xffff; int bs = (b << 16) & 0xffff; return (rs | gs | bs); } //// // Shell32 //// #region Shell32 [DllImport("shell32.dll")] public static extern IntPtr ShellExecute(IntPtr hwnd, string lpOperation, string lpFile, string lpParameters, string lpDirectory, int nShowCmd); [DllImport("shell32.dll", SetLastError = true)] extern public static bool ShellExecuteEx(ref ShellExecuteInfo lpExecInfo); [DllImport("shell32.dll")] extern public static IntPtr FindExecutable(string lfFile, string lpDirectory, [Out] StringBuilder lpResult); [DllImport("shell32.dll")] extern public static long SHGetFolderPath(IntPtr hwndOwner, int nFolder, IntPtr hToken, int dwFlags, [Out] StringBuilder pszPath); #endregion //// // User32 //// #region User32 [DllImport("user32.dll")] public static extern IntPtr SetFocus(IntPtr hwnd); [DllImport("user32.dll")] public static extern IntPtr GetFocus(); [DllImport("user32.dll")] public static extern IntPtr SetActiveWindow(IntPtr hWnd); [DllImport("user32.dll")] extern public static IntPtr SetParent(IntPtr child, IntPtr newParent); [DllImport("user32.dll")] extern public static long SetWindowLong(IntPtr hWnd, int nIndex, Int32 dwNewLong); [DllImport("user32.dll")] extern public static long GetWindowLong(IntPtr hWnd, int nIndex); [DllImport("User32.dll")] extern public static int SetForegroundWindow(IntPtr hWnd); [DllImport("user32.dll")] extern public static bool SetLayeredWindowAttributes(IntPtr hwnd, Int32 crKey, byte bAlpha, uint dwFlags); [DllImport("User32.dll")] extern public static IntPtr GetForegroundWindow(); [DllImport("User32.dll")] extern public static bool IsWindow(IntPtr hwnd); [DllImport("user32.dll")] extern public static int ShowWindow(IntPtr hwnd, int nCmdShow); [DllImport("user32.dll")] extern public static int GetWindowText(IntPtr hWnd, StringBuilder text, int count); [DllImport("user32.dll")] extern public static bool GetWindowRect(IntPtr hWnd, out RECT rect); [DllImport("user32.dll")] extern public static bool GetClientRect(IntPtr hWnd, out RECT rect); [DllImport("User32.dll")] extern public static bool EnumWindows(Delegate lpEnumFunc, IntPtr lParam); [DllImport("User32.dll")] extern public static int GetWindowThreadProcessId(IntPtr hWnd, ref int lpdwProcessId); [DllImport("User32.dll")] extern public static bool PostMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] public static extern uint SendInput(uint nInputs, ref INPUT pInputs, int cbSize); [DllImport("User32.dll")] extern public static int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, IntPtr lParam); [DllImport("user32.dll")] extern public static int GetSystemMetrics(int index); [DllImport("user32.dll")] extern public static bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags); [DllImport("user32.dll")] public static extern IntPtr GetDesktopWindow(); [DllImport("user32.dll")] public static extern IntPtr GetDC(IntPtr ptr); [DllImport("user32.dll")] public static extern IntPtr GetWindowDC(IntPtr hWnd); [DllImport("user32.dll")] public static extern IntPtr GetDCEx(IntPtr hWnd, IntPtr hrgnClip, int flags); [DllImport("user32.dll")] public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc); [DllImport("user32.dll")] public static extern bool EmptyClipboard(); [DllImport("user32.dll")] public static extern int GetClipboardSequenceNumber(); [DllImport("user32.dll")] public static extern bool GetMonitorInfo(IntPtr hMonitor, ref MONITORINFOEX monitorinfo); [DllImport("user32.dll")] public static extern IntPtr MonitorFromRect(ref RECT rect, int dwFlags); #endregion //// // Kernel32 //// #region Kernel32 [DllImport("kernel32.dll")] internal static extern IntPtr LoadLibrary(String dllname); [DllImport("kernel32.dll")] internal static extern IntPtr GetProcAddress(IntPtr hModule, String procname); [DllImport("kernel32.dll")] extern public static int GetProcessId(IntPtr hProcess); [DllImport("kernel32.dll")] extern public static IntPtr OpenProcess(int dwDesiredAccess, bool bInheritHandle, int dwProcessId); [DllImport("kernel32.dll")] extern public static int WaitForSingleObject(IntPtr hHandle, uint dwMilliseconds); [DllImport("kernel32.dll")] extern public static int GetLastError(); [DllImport("kernel32.dll")] // lpEventAttributes should be a ref to a SECURITY_ATTRIBUTES struct, but we only pass in NULL so we can just make it an IntPtr extern public static IntPtr CreateEvent(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, [In] StringBuilder lpName); [DllImport("kernel32.dll")] extern public static IntPtr SetEvent(IntPtr hEvent); [DllImport("kernel32.dll")] extern public static bool CloseHandle(IntPtr hHandle); [DllImport("kernel32.dll")] extern public static int GlobalAddAtom([In] StringBuilder lpString); [DllImport("kernel32.dll")] extern public static int GlobalDeleteAtom(int nAtom); #endregion //// // Shlwapi //// [DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Auto)] public static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, [In][Out] ref uint pcchOut); //// // Ole32 //// [DllImport("ole32.dll")] public static extern int CreateBindCtx(int reserved, out IBindCtx ppbc); //// // Uxtheme //// [DllImport("uxTheme.dll")] extern public static bool IsAppThemed(); //// // Dwmapi //// [DllImport("dwmapi.dll")] extern public static long DwmIsCompositionEnabled(ref bool pfEnabled); //// // GDI32 //// #region GDI32 [DllImport("gdi32.dll")] public static extern IntPtr DeleteDC(IntPtr hDc); [DllImport("gdi32.dll")] public static extern IntPtr DeleteObject(IntPtr hDc); [DllImport("gdi32.dll")] public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, int RasterOp); [DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight); [DllImport("gdi32.dll")] public static extern IntPtr CreateCompatibleDC(IntPtr hdc); [DllImport("gdi32.dll")] public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp); [DllImport("gdi32.dll")] public static extern IntPtr CreateDC(string lpszDriver, IntPtr passNULL, IntPtr passNULL2, IntPtr passNULL3); #endregion //// // Helper .Net Functions //// // .net implementation of EnumWindowsProc Callback public delegate bool EnumWindowsProc(IntPtr hWnd, IntPtr lParam); public interface IWindowHandleAccess { IntPtr hWnd { get; set; } } public static IntPtr GetWindowHandle(EnumWindowsProc proc, Context context) where Context : IWindowHandleAccess { // Initialize unmanged memory to hold the struct. IntPtr pContext = Marshal.AllocHGlobal(Marshal.SizeOf(context)); try { // Copy the struct to unmanaged memory. Marshal.StructureToPtr(context, pContext, false); bool bFound = false; int numTries = 5; while (!bFound && numTries != 0) { Win32Functions.EnumWindows(proc, pContext); // Marshall context back to managed context = (Context)Marshal.PtrToStructure(pContext, typeof(Context)); if (context.hWnd != IntPtr.Zero) { bFound = true; } else { // Sleep a little and try again Thread.Sleep(500); --numTries; } } } finally { Log.ErrorFormat("{0}() - Unknown exception occured!", MethodBase.GetCurrentMethod().Name); // Free the unmanaged memory. Marshal.FreeHGlobal(pContext); } return context.hWnd; } [StructLayout(LayoutKind.Sequential)] public struct EnumWindowsContext_pid_filename : IWindowHandleAccess { public int targetPid; public string filePath; private IntPtr _hWnd; public IntPtr hWnd { get { return _hWnd; } set { _hWnd = value; } } } [StructLayout(LayoutKind.Sequential)] public struct EnumWindowsContext_filePath : IWindowHandleAccess { public string filePath; private IntPtr _hWnd; public IntPtr hWnd { get { return _hWnd; } set { _hWnd = value; } } } public static bool EnumWindowProcImpl_filePath(IntPtr hWnd, IntPtr pContext) { bool bContinueEnumerating = true; // Marshall context back to managed EnumWindowsContext_filePath context = new EnumWindowsContext_filePath(); context = (EnumWindowsContext_filePath)Marshal.PtrToStructure(pContext, typeof(EnumWindowsContext_filePath)); // Check if filePath is the text in the window title bar if (IsTitleBar(hWnd, context.filePath)) { Log.InfoFormat("{0}() - found!", MethodBase.GetCurrentMethod().Name); context.hWnd = hWnd; // Marshall changed data back to unmanaged Marshal.StructureToPtr(context, pContext, false); bContinueEnumerating = false; } return bContinueEnumerating; } public static bool EnumWindowProcImpl_pid_filename(IntPtr hWnd, IntPtr pContext) { bool bContinueEnumerating = true; int currentPid = 0; GetWindowThreadProcessId(hWnd, ref currentPid); // Marshall context back to managed EnumWindowsContext_pid_filename context = new EnumWindowsContext_pid_filename(); context = (EnumWindowsContext_pid_filename)Marshal.PtrToStructure(pContext, typeof(EnumWindowsContext_pid_filename)); if (currentPid == context.targetPid) { Log.InfoFormat("{0}() - currentpid = {1} vs. targetPid = {2} hwnd = {3}", MethodBase.GetCurrentMethod().Name, currentPid, context.targetPid, hWnd.ToString("X")); // Check if fileName is in window title bar if (IsFilenameInTitleBar(hWnd, context.filePath)) { Log.InfoFormat("{0}() - found!", MethodBase.GetCurrentMethod().Name); context.hWnd = hWnd; // Marshall changed data back to unmanaged Marshal.StructureToPtr(context, pContext, false); bContinueEnumerating = false; } } return bContinueEnumerating; } public static bool IsFilenameInTitleBar(IntPtr hWnd, string filePath) { bool bFound = false; int maxTextSize = 256; StringBuilder titleBarText = new StringBuilder(maxTextSize); if (GetWindowText(hWnd, titleBarText, maxTextSize) > 0) { string fileName = Path.GetFileName(filePath); if (fileName.Length > 0) { if (titleBarText.ToString().ToLower().IndexOf(fileName.ToLower()) != -1) { bFound = true; } } } return bFound; } public static bool IsTitleBar(IntPtr hWnd, string filePath) { bool bFound = false; int maxTextSize = 256; StringBuilder titleBarText = new StringBuilder(maxTextSize); if (GetWindowText(hWnd, titleBarText, maxTextSize) > 0) { if (filePath.Length > 0) { if (titleBarText.ToString().ToLower().CompareTo(filePath.ToLower()) == 0) { bFound = true; } } } return bFound; } public static string GetProcessName(IntPtr hWnd) { int currentPid = 0; Win32Functions.GetWindowThreadProcessId(hWnd, ref currentPid); Process process; try { process = Process.GetProcessById(currentPid); } catch (ArgumentException e) { // This is thrown when Process.GetProcessById cannot find the process throw e; } return process.ProcessName; } /// /// Returns the .Net Process Object that owns the passed in hWnd /// /// handle to a Window /// a .Net Process or throws an error public static Process GetProcessFromHandle(IntPtr hWnd) { try { int currentPid = 0; Win32Functions.GetWindowThreadProcessId(hWnd, ref currentPid); Process process; process = Process.GetProcessById(currentPid); return process; } catch (ArgumentException e) { // This is thrown when Process.GetProcessById cannot find the process throw e; } } /// /// Attaches to instance of COM object matching progid /// and returns an object. Client must cast and know /// expected type. /// public static Object GetCOMObject(string progId) { Object app = null; try { app = Marshal.GetActiveObject(progId); } catch (SystemException e) { string d = e.ToString(); } return app; } public struct RunningObject { public string name; public object o; } /// /// Use this to Get All Running Objects in the ROT /// public static List GetRunningObjects() { // Get the table. var res = new List(); IBindCtx bc; CreateBindCtx(0, out bc); IRunningObjectTable runningObjectTable; bc.GetRunningObjectTable(out runningObjectTable); IEnumMoniker monikerEnumerator; runningObjectTable.EnumRunning(out monikerEnumerator); monikerEnumerator.Reset(); // Enumerate and fill our nice dictionary. IMoniker[] monikers = new IMoniker[1]; IntPtr numFetched = IntPtr.Zero; while (monikerEnumerator.Next(1, monikers, numFetched) == 0) { RunningObject running; monikers[0].GetDisplayName(bc, null, out running.name); runningObjectTable.GetObject(monikers[0], out running.o); res.Add(running); } return res; } /// /// Use this to Get A specific type of Object from the ROT /// public static List GetRunningObjectsOfType() { // Get the table. var res = new List(); IBindCtx bc; CreateBindCtx(0, out bc); IRunningObjectTable runningObjectTable; bc.GetRunningObjectTable(out runningObjectTable); IEnumMoniker monikerEnumerator; runningObjectTable.EnumRunning(out monikerEnumerator); monikerEnumerator.Reset(); // Enumerate and fill our nice dictionary. IMoniker[] monikers = new IMoniker[1]; IntPtr numFetched = IntPtr.Zero; while (monikerEnumerator.Next(1, monikers, numFetched) == 0) { object o; runningObjectTable.GetObject(monikers[0], out o); if (o is T) { res.Add((T) o); } o = null; } return res; } } }