862 lines
38 KiB
C#
862 lines
38 KiB
C#
//----------------------------------------------------------------------------------------------------------------------
|
|
// <copyright file="NativeMethods.cs" company="Microsoft">
|
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// </copyright>
|
|
// <summary>Wrapper class for storing P/Invoke and COM Interop definitions.</summary>
|
|
//----------------------------------------------------------------------------------------------------------------------
|
|
|
|
namespace Conhost.UIA.Tests.Common.NativeMethods
|
|
{
|
|
using System;
|
|
using System.Drawing;
|
|
using System.Runtime.CompilerServices;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
using Microsoft.Win32;
|
|
using WEX.TestExecution;
|
|
using WEX.Logging.Interop;
|
|
|
|
// Small extension method helpers to make C# feel closer to native.
|
|
public static class NativeExtensions
|
|
{
|
|
public static int LoWord(this int val)
|
|
{
|
|
return val & 0xffff;
|
|
}
|
|
|
|
public static int HiWord(this int val)
|
|
{
|
|
return (val >> 16) & 0xffff;
|
|
}
|
|
}
|
|
|
|
public static class NativeMethods
|
|
{
|
|
public static void Win32BoolHelper(bool result, string actionMessage)
|
|
{
|
|
if (!result)
|
|
{
|
|
string errorMsg = string.Format("Win32 error occurred: 0x{0:X}", Marshal.GetLastWin32Error());
|
|
Log.Comment(errorMsg);
|
|
}
|
|
|
|
Verify.IsTrue(result, actionMessage);
|
|
}
|
|
|
|
public static void Win32NullHelper(IntPtr result, string actionMessage)
|
|
{
|
|
if (result == IntPtr.Zero)
|
|
{
|
|
string errorMsg = string.Format("Win32 error occurred: 0x{0:X}", Marshal.GetLastWin32Error());
|
|
Log.Comment(errorMsg);
|
|
}
|
|
|
|
Verify.IsNotNull(result, actionMessage);
|
|
}
|
|
}
|
|
|
|
public static class WinCon
|
|
{
|
|
[Flags()]
|
|
public enum CONSOLE_SELECTION_INFO_FLAGS : uint
|
|
{
|
|
CONSOLE_NO_SELECTION = 0x0,
|
|
CONSOLE_SELECTION_IN_PROGRESS = 0x1,
|
|
CONSOLE_SELECTION_NOT_EMPTY = 0x2,
|
|
CONSOLE_MOUSE_SELECTION = 0x4,
|
|
CONSOLE_MOUSE_DOWN = 0x8
|
|
}
|
|
|
|
public enum CONSOLE_STD_HANDLE : int
|
|
{
|
|
STD_INPUT_HANDLE = -10,
|
|
STD_OUTPUT_HANDLE = -11,
|
|
STD_ERROR_HANDLE = -12
|
|
}
|
|
|
|
public enum CONSOLE_ATTRIBUTES : ushort
|
|
{
|
|
FOREGROUND_BLUE = 0x1,
|
|
FOREGROUND_GREEN = 0x2,
|
|
FOREGROUND_RED = 0x4,
|
|
FOREGROUND_INTENSITY = 0x8,
|
|
FOREGROUND_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN,
|
|
FOREGROUND_CYAN = FOREGROUND_GREEN | FOREGROUND_BLUE,
|
|
FOREGROUND_MAGENTA = FOREGROUND_RED | FOREGROUND_BLUE,
|
|
FOREGROUND_COLORS = FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_GREEN,
|
|
FOREGROUND_ALL = FOREGROUND_COLORS | FOREGROUND_INTENSITY,
|
|
BACKGROUND_BLUE = 0x10,
|
|
BACKGROUND_GREEN = 0x20,
|
|
BACKGROUND_RED = 0x40,
|
|
BACKGROUND_INTENSITY = 0x80,
|
|
BACKGROUND_YELLOW = BACKGROUND_RED | BACKGROUND_GREEN,
|
|
BACKGROUND_CYAN = BACKGROUND_GREEN | BACKGROUND_BLUE,
|
|
BACKGROUND_MAGENTA = BACKGROUND_RED | BACKGROUND_BLUE,
|
|
BACKGROUND_COLORS = BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN,
|
|
BACKGROUND_ALL = BACKGROUND_COLORS | BACKGROUND_INTENSITY,
|
|
COMMON_LVB_LEADING_BYTE = 0x100,
|
|
COMMON_LVB_TRAILING_BYTE = 0x200,
|
|
COMMON_LVB_GRID_HORIZONTAL = 0x400,
|
|
COMMON_LVB_GRID_LVERTICAL = 0x800,
|
|
COMMON_LVB_GRID_RVERTICAL = 0x1000,
|
|
COMMON_LVB_REVERSE_VIDEO = 0x4000,
|
|
COMMON_LVB_UNDERSCORE = 0x8000
|
|
}
|
|
|
|
public enum CONSOLE_OUTPUT_MODES : uint
|
|
{
|
|
ENABLE_PROCESSED_OUTPUT = 0x1,
|
|
ENABLE_WRAP_AT_EOL_OUTPUT = 0x2,
|
|
ENABLE_VIRTUAL_TERMINAL_PROCESSING = 0x4
|
|
}
|
|
|
|
//CHAR_INFO struct, which was a union in the old days
|
|
// so we want to use LayoutKind.Explicit to mimic it as closely
|
|
// as we can
|
|
[StructLayout(LayoutKind.Explicit)]
|
|
public struct CHAR_INFO
|
|
{
|
|
[FieldOffset(0)]
|
|
internal char UnicodeChar;
|
|
[FieldOffset(0)]
|
|
internal char AsciiChar;
|
|
[FieldOffset(2)] //2 bytes seems to work properly
|
|
internal CONSOLE_ATTRIBUTES Attributes;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct COORD
|
|
{
|
|
public short X;
|
|
public short Y;
|
|
|
|
public override string ToString()
|
|
{
|
|
return string.Format("(X:{0} Y:{1})", X, Y);
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct SMALL_RECT
|
|
{
|
|
public short Left;
|
|
public short Top;
|
|
public short Right;
|
|
public short Bottom;
|
|
|
|
public short Width
|
|
{
|
|
get
|
|
{
|
|
// The API returns bottom/right as the inclusive lower-right
|
|
// corner, so we need +1 for the true width
|
|
return (short)(this.Right - this.Left + 1);
|
|
}
|
|
}
|
|
|
|
public short Height
|
|
{
|
|
get
|
|
{
|
|
// The API returns bottom/right as the inclusive lower-right
|
|
// corner, so we need +1 for the true height
|
|
return (short)(this.Bottom - this.Top + 1);
|
|
}
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return string.Format("(L:{0} T:{1} R:{2} B:{3})", Left, Top, Right, Bottom);
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct CONSOLE_CURSOR_INFO
|
|
{
|
|
public uint dwSize;
|
|
public bool bVisible;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct CONSOLE_FONT_INFO
|
|
{
|
|
public int nFont;
|
|
public COORD dwFontSize;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct CONSOLE_SELECTION_INFO
|
|
{
|
|
public CONSOLE_SELECTION_INFO_FLAGS Flags;
|
|
public COORD SelectionAnchor;
|
|
public SMALL_RECT Selection;
|
|
|
|
public override string ToString()
|
|
{
|
|
return string.Format("Flags:{0:X} Anchor:{1} Selection:{2}", Flags, SelectionAnchor, Selection);
|
|
}
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct CONSOLE_SCREEN_BUFFER_INFO
|
|
{
|
|
public COORD dwSize;
|
|
public COORD dwCursorPosition;
|
|
public CONSOLE_ATTRIBUTES wAttributes;
|
|
public SMALL_RECT srWindow;
|
|
public COORD dwMaximumWindowSize;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct CONSOLE_SCREEN_BUFFER_INFO_EX
|
|
{
|
|
public uint cbSize;
|
|
public COORD dwSize;
|
|
public COORD dwCursorPosition;
|
|
public CONSOLE_ATTRIBUTES wAttributes;
|
|
public SMALL_RECT srWindow;
|
|
public COORD dwMaximumWindowSize;
|
|
|
|
public CONSOLE_ATTRIBUTES wPopupAttributes;
|
|
public bool bFullscreenSupported;
|
|
|
|
internal COLORREF black;
|
|
internal COLORREF darkBlue;
|
|
internal COLORREF darkGreen;
|
|
internal COLORREF darkCyan;
|
|
internal COLORREF darkRed;
|
|
internal COLORREF darkMagenta;
|
|
internal COLORREF darkYellow;
|
|
internal COLORREF gray;
|
|
internal COLORREF darkGray;
|
|
internal COLORREF blue;
|
|
internal COLORREF green;
|
|
internal COLORREF cyan;
|
|
internal COLORREF red;
|
|
internal COLORREF magenta;
|
|
internal COLORREF yellow;
|
|
internal COLORREF white;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct COLORREF
|
|
{
|
|
internal uint ColorDWORD;
|
|
|
|
public COLORREF(Color color)
|
|
{
|
|
ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
|
|
}
|
|
|
|
public COLORREF(uint r, uint g, uint b)
|
|
{
|
|
ColorDWORD = r + (g << 8) + (b << 16);
|
|
}
|
|
|
|
public Color GetColor()
|
|
{
|
|
return Color.FromArgb((int)(0x000000FFU & ColorDWORD),
|
|
(int)(0x0000FF00U & ColorDWORD) >> 8, (int)(0x00FF0000U & ColorDWORD) >> 16);
|
|
}
|
|
|
|
public void SetColor(Color color)
|
|
{
|
|
ColorDWORD = (uint)color.R + (((uint)color.G) << 8) + (((uint)color.B) << 16);
|
|
}
|
|
}
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern IntPtr GetStdHandle(CONSOLE_STD_HANDLE nStdHandle);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool AttachConsole(UInt32 dwProcessId);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool FreeConsole();
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
|
public static extern bool SetConsoleTitle(string ConsoleTitle);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool GetConsoleMode(IntPtr hConsoleOutputHandle, out CONSOLE_OUTPUT_MODES lpMode);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
|
public static extern uint GetConsoleTitle(StringBuilder lpConsoleTitle, int nSize);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern IntPtr GetConsoleWindow();
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool GetConsoleSelectionInfo(out CONSOLE_SELECTION_INFO lpConsoleSelectionInfo);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool SetConsoleWindowInfo(IntPtr hConsoleOutput, bool bAbsolute, [In] ref SMALL_RECT lpConsoleWindow);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool GetConsoleCursorInfo(IntPtr hConsoleOutput, out CONSOLE_CURSOR_INFO lpConsoleCursorInfo);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool GetConsoleScreenBufferInfo(IntPtr hConsoleOutput, out CONSOLE_SCREEN_BUFFER_INFO lpConsoleScreenBufferInfo);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool GetConsoleScreenBufferInfoEx(IntPtr hConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfo);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool SetConsoleScreenBufferInfoEx(IntPtr ConsoleOutput, ref CONSOLE_SCREEN_BUFFER_INFO_EX ConsoleScreenBufferInfoEx);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool GetCurrentConsoleFont(IntPtr hConsoleOutput, bool bMaximumWindow, out CONSOLE_FONT_INFO lpConsoleCurrentFont);
|
|
|
|
[DllImport("kernel32.dll", EntryPoint = "ReadConsoleOutputW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
public static extern bool ReadConsoleOutput(
|
|
IntPtr hConsoleOutput,
|
|
/* This pointer is treated as the origin of a two-dimensional array of CHAR_INFO structures
|
|
whose size is specified by the dwBufferSize parameter.*/
|
|
[MarshalAs(UnmanagedType.LPArray), Out] CHAR_INFO[,] lpBuffer,
|
|
COORD dwBufferSize,
|
|
COORD dwBufferCoord,
|
|
ref SMALL_RECT lpReadRegion);
|
|
|
|
[DllImport("kernel32.dll", EntryPoint = "WriteConsoleOutputCharacterW", CharSet = CharSet.Unicode, SetLastError = true)]
|
|
public static extern bool WriteConsoleOutputCharacter(
|
|
IntPtr hConsoleOutput,
|
|
string lpCharacter,
|
|
UInt32 nLength,
|
|
COORD dwWriteCoord,
|
|
ref UInt32 lpNumberOfCharsWritten);
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// The definitions within this file match the winconp.h file that is generated from wincon.w
|
|
/// Please see /windows/published/main/wincon.w
|
|
/// </summary>
|
|
public static class WinConP
|
|
{
|
|
private static readonly Guid PKEY_Console_FormatId = new Guid(0x0C570607, 0x0396, 0x43DE, new byte[] { 0x9D, 0x61, 0xE3, 0x21, 0xD7, 0xDF, 0x50, 0x26 });
|
|
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_ForceV2 = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 1 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_WrapText = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 2 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_FilterOnPaste = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 3 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_CtrlKeysDisabled = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 4 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_LineSelection = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 5 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_WindowTransparency = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 6 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_TrimZeros = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 7 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_CursorType = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 8 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_CursorColor = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 9 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_InterceptCopyPaste = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 10 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_DefaultForeground = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 11 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_DefaultBackground = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 12 };
|
|
public static readonly Wtypes.PROPERTYKEY PKEY_Console_TerminalScrolling = new Wtypes.PROPERTYKEY() { fmtid = PKEY_Console_FormatId, pid = 13 };
|
|
|
|
public static readonly uint NT_CONSOLE_PROPS_SIG = 0xA0000002;
|
|
public static readonly uint NT_FE_CONSOLE_PROPS_SIG = 0xA0000004;
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
public struct NT_CONSOLE_PROPS
|
|
{
|
|
public Shell32.DATABLOCK_HEADER dbh;
|
|
public short wFillAttribute;
|
|
public short wPopupFillAttribute;
|
|
public WinCon.COORD dwScreenBufferSize;
|
|
public WinCon.COORD dwWindowSize;
|
|
public WinCon.COORD dwWindowOrigin;
|
|
public int nFont;
|
|
public int nInputBufferSize;
|
|
public WinCon.COORD dwFontSize;
|
|
public uint uFontFamily;
|
|
public uint uFontWeight;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
|
|
public string FaceName;
|
|
public uint uCursorSize;
|
|
public int bFullScreen;
|
|
public int bQuickEdit;
|
|
public int bInsertMode;
|
|
public int bAutoPosition;
|
|
public uint uHistoryBufferSize;
|
|
public uint uNumberOfHistoryBuffers;
|
|
public int bHistoryNoDup;
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
|
|
public int[] ColorTable;
|
|
public uint CursorType;
|
|
public WinCon.COLORREF CursorColor;
|
|
public bool InterceptCopyPaste;
|
|
public WinCon.COLORREF DefaultForeground;
|
|
public WinCon.COLORREF DefaultBackground;
|
|
public bool TerminalScrolling;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct NT_FE_CONSOLE_PROPS
|
|
{
|
|
Shell32.DATABLOCK_HEADER dbh;
|
|
uint uCodePage;
|
|
}
|
|
}
|
|
|
|
public static class User32
|
|
{
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/dd162897(v=vs.85).aspx
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct RECT
|
|
{
|
|
public Int32 left;
|
|
public Int32 top;
|
|
public Int32 right;
|
|
public Int32 bottom;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct POINT
|
|
{
|
|
public Int32 x;
|
|
public Int32 y;
|
|
}
|
|
|
|
public const int WHEEL_DELTA = 120;
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool GetClientRect(IntPtr hWnd, out RECT lpRect);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);
|
|
|
|
public const int GWL_STYLE = (-16);
|
|
public const int GWL_EXSTYLE = (-20);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern int GetWindowLong(IntPtr hWnd, int nIndex);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool AdjustWindowRectEx(ref RECT lpRect, int dwStyle, bool bMenu, int dwExStyle);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool ClientToScreen(IntPtr hWnd, ref POINT lpPoint);
|
|
|
|
public enum WindowMessages : UInt32
|
|
{
|
|
WM_KEYDOWN = 0x0100,
|
|
WM_KEYUP = 0x0101,
|
|
WM_CHAR = 0x0102,
|
|
WM_MOUSEWHEEL = 0x020A,
|
|
WM_MOUSEHWHEEL = 0x020E,
|
|
WM_USER = 0x0400,
|
|
CM_SET_KEY_STATE = WM_USER + 18
|
|
}
|
|
|
|
[DllImport("user32.dll", CharSet = CharSet.Auto)]
|
|
public static extern IntPtr SendMessage(IntPtr hWnd, WindowMessages Msg, Int32 wParam, IntPtr lParam);
|
|
|
|
public enum SPI : uint
|
|
{
|
|
SPI_GETWHEELSCROLLLINES = 0x0068,
|
|
SPI_GETWHEELSCROLLCHARACTERS = 0x006C
|
|
}
|
|
|
|
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
public static extern bool SystemParametersInfo(SPI uiAction, uint uiParam, ref uint pvParam, uint fWinIni);
|
|
|
|
|
|
public enum WinEventId : uint
|
|
{
|
|
EVENT_CONSOLE_CARET = 0x4001,
|
|
EVENT_CONSOLE_UPDATE_REGION = 0x4002,
|
|
EVENT_CONSOLE_UPDATE_SIMPLE = 0x4003,
|
|
EVENT_CONSOLE_UPDATE_SCROLL = 0x4004,
|
|
EVENT_CONSOLE_LAYOUT = 0x4005,
|
|
EVENT_CONSOLE_START_APPLICATION = 0x4006,
|
|
EVENT_CONSOLE_END_APPLICATION = 0x4007
|
|
}
|
|
|
|
[Flags]
|
|
public enum WinEventFlags : uint
|
|
{
|
|
WINEVENT_OUTOFCONTEXT = 0x0000, // Events are ASYNC
|
|
WINEVENT_SKIPOWNTHREAD = 0x0001, // Don't call back for events on installer's thread
|
|
WINEVENT_SKIPOWNPROCESS = 0x0002, // Don't call back for events on installer's process
|
|
WINEVENT_INCONTEXT = 0x0004, // Events are SYNC, this causes your dll to be injected into every process
|
|
}
|
|
|
|
public delegate void WinEventDelegate(IntPtr hWinEventHook, WinEventId eventType, IntPtr hwnd, int idObject, int idChild, uint dwEventThread, uint dwmsEventTime);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern IntPtr SetWinEventHook(WinEventId eventMin, WinEventId eventMax, IntPtr hmodWinEventProc, WinEventDelegate lpfnWinEventProc, uint idProcess, uint idThread, WinEventFlags dwFlags);
|
|
|
|
[DllImport("user32.dll")]
|
|
public static extern bool UnhookWinEvent(IntPtr hWinEventHook);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern uint GetWindowThreadProcessId(IntPtr hWnd, out uint lpdwProcessId);
|
|
|
|
public struct MSG
|
|
{
|
|
public IntPtr hwnd;
|
|
public uint message;
|
|
public IntPtr wParam;
|
|
public IntPtr lParam;
|
|
public uint time;
|
|
public POINT pt;
|
|
}
|
|
|
|
public enum PM : uint
|
|
{
|
|
PM_NOREMOVE = 0x0000,
|
|
PM_REMOVE = 0x0001,
|
|
PM_NOYIELD = 0x0002,
|
|
}
|
|
|
|
[DllImport("user32.dll")]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
public static extern bool PeekMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax, PM wRemoveMsg);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern int GetMessage(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
|
|
|
|
[DllImport("user32.dll", SetLastError = true)]
|
|
public static extern IntPtr DispatchMessage(ref MSG lpmsg);
|
|
}
|
|
|
|
public static class Shell32
|
|
{
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773249(v=vs.85).aspx
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct DATABLOCK_HEADER
|
|
{
|
|
public int cbSize;
|
|
public int dwSignature;
|
|
}
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774944(v=vs.85).aspx
|
|
// http://pinvoke.net/default.aspx/Enums/SLGP_FLAGS.html
|
|
/// <summary>IShellLink.GetPath fFlags: Flags that specify the type of path information to retrieve</summary>
|
|
[Flags()]
|
|
public enum SLGP_FLAGS
|
|
{
|
|
/// <summary>Retrieves the standard short (8.3 format) file name</summary>
|
|
SLGP_SHORTPATH = 0x1,
|
|
/// <summary>Retrieves the Universal Naming Convention (UNC) path name of the file</summary>
|
|
SLGP_UNCPRIORITY = 0x2,
|
|
/// <summary>Retrieves the raw path name. A raw path is something that might not exist and may include environment variables that need to be expanded</summary>
|
|
SLGP_RAWPATH = 0x4
|
|
}
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774952(v=vs.85).aspx
|
|
// http://pinvoke.net/default.aspx/Enums/SLR_FLAGS.html
|
|
/// <summary>IShellLink.Resolve fFlags</summary>
|
|
[Flags()]
|
|
public enum SLR_FLAGS
|
|
{
|
|
/// <summary>
|
|
/// Do not display a dialog box if the link cannot be resolved. When SLR_NO_UI is set,
|
|
/// the high-order word of fFlags can be set to a time-out value that specifies the
|
|
/// maximum amount of time to be spent resolving the link. The function returns if the
|
|
/// link cannot be resolved within the time-out duration. If the high-order word is set
|
|
/// to zero, the time-out duration will be set to the default value of 3,000 milliseconds
|
|
/// (3 seconds). To specify a value, set the high word of fFlags to the desired time-out
|
|
/// duration, in milliseconds.
|
|
/// </summary>
|
|
SLR_NO_UI = 0x1,
|
|
/// <summary>Obsolete and no longer used</summary>
|
|
SLR_ANY_MATCH = 0x2,
|
|
/// <summary>If the link object has changed, update its path and list of identifiers.
|
|
/// If SLR_UPDATE is set, you do not need to call IPersistFile::IsDirty to determine
|
|
/// whether or not the link object has changed.</summary>
|
|
SLR_UPDATE = 0x4,
|
|
/// <summary>Do not update the link information</summary>
|
|
SLR_NOUPDATE = 0x8,
|
|
/// <summary>Do not execute the search heuristics</summary>
|
|
SLR_NOSEARCH = 0x10,
|
|
/// <summary>Do not use distributed link tracking</summary>
|
|
SLR_NOTRACK = 0x20,
|
|
/// <summary>Disable distributed link tracking. By default, distributed link tracking tracks
|
|
/// removable media across multiple devices based on the volume name. It also uses the
|
|
/// Universal Naming Convention (UNC) path to track remote file systems whose drive letter
|
|
/// has changed. Setting SLR_NOLINKINFO disables both types of tracking.</summary>
|
|
SLR_NOLINKINFO = 0x40,
|
|
/// <summary>Call the Microsoft Windows Installer</summary>
|
|
SLR_INVOKE_MSI = 0x80
|
|
}
|
|
|
|
[ComImport, Guid("00021401-0000-0000-C000-000000000046")]
|
|
public class ShellLink
|
|
{
|
|
// Making new of this class will call CoCreate e.g. new ShellLink();
|
|
// Cast to one of the interfaces below will QueryInterface. e.g. (IPersistFile)new ShellLink();
|
|
}
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774950(v=vs.85).aspx
|
|
// http://pinvoke.net/default.aspx/Interfaces/IShellLinkW.html
|
|
/// <summary>The IShellLink interface allows Shell links to be created, modified, and resolved</summary>
|
|
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("000214F9-0000-0000-C000-000000000046")]
|
|
public interface IShellLinkW
|
|
{
|
|
/// <summary>Retrieves the path and file name of a Shell link object</summary>
|
|
void GetPath([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, int cchMaxPath, out WinBase.WIN32_FIND_DATAW pfd, SLGP_FLAGS fFlags);
|
|
/// <summary>Retrieves the list of item identifiers for a Shell link object</summary>
|
|
void GetIDList(out IntPtr ppidl);
|
|
/// <summary>Sets the pointer to an item identifier list (PIDL) for a Shell link object.</summary>
|
|
void SetIDList(IntPtr pidl);
|
|
/// <summary>Retrieves the description string for a Shell link object</summary>
|
|
void GetDescription([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName);
|
|
/// <summary>Sets the description for a Shell link object. The description can be any application-defined string</summary>
|
|
void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName);
|
|
/// <summary>Retrieves the name of the working directory for a Shell link object</summary>
|
|
void GetWorkingDirectory([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath);
|
|
/// <summary>Sets the name of the working directory for a Shell link object</summary>
|
|
void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir);
|
|
/// <summary>Retrieves the command-line arguments associated with a Shell link object</summary>
|
|
void GetArguments([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath);
|
|
/// <summary>Sets the command-line arguments for a Shell link object</summary>
|
|
void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs);
|
|
/// <summary>Retrieves the hot key for a Shell link object</summary>
|
|
void GetHotkey(out short pwHotkey);
|
|
/// <summary>Sets a hot key for a Shell link object</summary>
|
|
void SetHotkey(short wHotkey);
|
|
/// <summary>Retrieves the show command for a Shell link object</summary>
|
|
void GetShowCmd(out int piShowCmd);
|
|
/// <summary>Sets the show command for a Shell link object. The show command sets the initial show state of the window.</summary>
|
|
void SetShowCmd(int iShowCmd);
|
|
/// <summary>Retrieves the location (path and index) of the icon for a Shell link object</summary>
|
|
void GetIconLocation([Out(), MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath,
|
|
int cchIconPath, out int piIcon);
|
|
/// <summary>Sets the location (path and index) of the icon for a Shell link object</summary>
|
|
void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon);
|
|
/// <summary>Sets the relative path to the Shell link object</summary>
|
|
void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved);
|
|
/// <summary>Attempts to find the target of a Shell link, even if it has been moved or renamed</summary>
|
|
void Resolve(IntPtr hwnd, SLR_FLAGS fFlags);
|
|
/// <summary>Sets the path and file name of a Shell link object</summary>
|
|
void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile);
|
|
}
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774916(v=vs.85).aspx
|
|
// http://pinvoke.net/default.aspx/Interfaces/IShellLonkDataList.html
|
|
[ComImport(), InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("45e2b4ae-b1c3-11d0-b92f-00a0c90312e1")]
|
|
public interface IShellLinkDataList
|
|
{
|
|
void AddDataBlock(IntPtr pDataBlock);
|
|
void CopyDataBlock(uint dwSig, out IntPtr ppDataBlock);
|
|
void RemoveDataBlock(uint dwSig);
|
|
void GetFlags(out uint pdwFlags);
|
|
void SetFlags(uint dwFlags);
|
|
}
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms688695(v=vs.85).aspx
|
|
// http://pinvoke.net/default.aspx/Interfaces/IPersist.html
|
|
[ComImport, Guid("0000010c-0000-0000-c000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
public interface IPersist
|
|
{
|
|
[PreserveSig]
|
|
void GetClassID(out Guid pClassID);
|
|
}
|
|
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms687223(v=vs.85).aspx
|
|
// http://www.pinvoke.net/default.aspx/Interfaces/IPersistFile.html
|
|
[ComImport, Guid("0000010b-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
public interface IPersistFile : IPersist
|
|
{
|
|
new void GetClassID(out Guid pClassID);
|
|
|
|
[PreserveSig]
|
|
int IsDirty();
|
|
|
|
[PreserveSig]
|
|
void Load([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode);
|
|
|
|
[PreserveSig]
|
|
void Save([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName,
|
|
[In, MarshalAs(UnmanagedType.Bool)] bool fRemember);
|
|
|
|
[PreserveSig]
|
|
void SaveCompleted([In, MarshalAs(UnmanagedType.LPWStr)] string pszFileName);
|
|
|
|
[PreserveSig]
|
|
void GetCurFile([In, MarshalAs(UnmanagedType.LPWStr)] string ppszFileName);
|
|
}
|
|
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb761474(v=vs.85).aspx
|
|
// http://www.pinvoke.net/default.aspx/Interfaces/IPropertyStore.html
|
|
[ComImport, Guid("886D8EEB-8CF2-4446-8D02-CDBA1DBDCF99"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|
public interface IPropertyStore
|
|
{
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
|
void GetCount([Out] out uint cProps);
|
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
|
void GetAt([In] uint iProp, out Wtypes.PROPERTYKEY pkey);
|
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
|
void GetValue([In] ref Wtypes.PROPERTYKEY key, out object pv);
|
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
|
void SetValue([In] ref Wtypes.PROPERTYKEY key, [In] ref object pv);
|
|
|
|
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
|
|
void Commit();
|
|
}
|
|
}
|
|
|
|
public static class WinBase
|
|
{
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa365740(v=vs.85).aspx
|
|
// http://www.pinvoke.net/default.aspx/Structures/WIN32_FIND_DATA.html
|
|
// The CharSet must match the CharSet of the corresponding PInvoke signature
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
public struct WIN32_FIND_DATAW
|
|
{
|
|
public uint dwFileAttributes;
|
|
public System.Runtime.InteropServices.ComTypes.FILETIME ftCreationTime;
|
|
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastAccessTime;
|
|
public System.Runtime.InteropServices.ComTypes.FILETIME ftLastWriteTime;
|
|
public uint nFileSizeHigh;
|
|
public uint nFileSizeLow;
|
|
public uint dwReserved0;
|
|
public uint dwReserved1;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
|
|
public string cFileName;
|
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 14)]
|
|
public string cAlternateFileName;
|
|
}
|
|
|
|
public enum STARTF : Int32
|
|
{
|
|
STARTF_TITLEISLINKNAME = 0x00000800
|
|
}
|
|
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
public struct STARTUPINFO
|
|
{
|
|
public Int32 cb;
|
|
public string lpReserved;
|
|
public string lpDesktop;
|
|
public string lpTitle;
|
|
public Int32 dwX;
|
|
public Int32 dwY;
|
|
public Int32 dwXSize;
|
|
public Int32 dwYSize;
|
|
public Int32 dwXCountChars;
|
|
public Int32 dwYCountChars;
|
|
public Int32 dwFillAttribute;
|
|
public STARTF dwFlags;
|
|
public Int16 wShowWindow;
|
|
public Int16 cbReserved2;
|
|
public IntPtr lpReserved2;
|
|
public IntPtr hStdInput;
|
|
public IntPtr hStdOutput;
|
|
public IntPtr hStdError;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct PROCESS_INFORMATION
|
|
{
|
|
public IntPtr hProcess;
|
|
public IntPtr hThread;
|
|
public int dwProcessId;
|
|
public int dwThreadId;
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
|
public struct STARTUPINFOEX
|
|
{
|
|
public STARTUPINFO StartupInfo;
|
|
public IntPtr lpAttributeList;
|
|
}
|
|
|
|
[Flags]
|
|
public enum CP_CreationFlags : uint
|
|
{
|
|
CREATE_SUSPENDED = 0x4,
|
|
CREATE_NEW_CONSOLE = 0x10,
|
|
}
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
|
|
public static extern bool CreateProcess(string lpApplicationName,
|
|
string lpCommandLine,
|
|
IntPtr lpProcessAttributes,
|
|
IntPtr lpThreadAttributes,
|
|
bool bInheritHandles,
|
|
CP_CreationFlags dwCreationFlags,
|
|
IntPtr lpEnvironment,
|
|
string lpCurrentDirectory,
|
|
[In] ref STARTUPINFO lpStartupInfo,
|
|
out PROCESS_INFORMATION lpProcessInformation);
|
|
|
|
|
|
[DllImport("kernel32.dll", CharSet = CharSet.Unicode)]
|
|
public static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, IntPtr lpName);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
public static extern bool TerminateJobObject(IntPtr hJob, uint uExitCode);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
public static extern int ResumeThread(IntPtr hThread);
|
|
|
|
public enum JOBOBJECTINFOCLASS : uint
|
|
{
|
|
JobObjectBasicProcessIdList = 3
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Sequential)]
|
|
public struct JOBOBJECT_BASIC_PROCESS_ID_LIST
|
|
{
|
|
public uint NumberOfAssignedProcesses;
|
|
public uint NumberOfProcessIdsInList;
|
|
public IntPtr ProcessId;
|
|
public IntPtr ProcessId2;
|
|
}
|
|
|
|
[DllImport("kernel32.dll")]
|
|
public static extern bool QueryInformationJobObject(IntPtr hJob,
|
|
JOBOBJECTINFOCLASS JobObjectInformationClass,
|
|
IntPtr lpJobObjectInfo,
|
|
int cbJobObjectInfoLength,
|
|
IntPtr lpReturnLength);
|
|
}
|
|
|
|
public static class Wtypes
|
|
{
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb773381(v=vs.85).aspx
|
|
// http://pinvoke.net/default.aspx/Structures/PROPERTYKEY.html
|
|
[StructLayout(LayoutKind.Sequential, Pack = 4)]
|
|
public struct PROPERTYKEY
|
|
{
|
|
public Guid fmtid;
|
|
public uint pid;
|
|
}
|
|
}
|
|
|
|
public static class ObjBase
|
|
{
|
|
// http://msdn.microsoft.com/en-us/library/windows/desktop/aa380337(v=vs.85).aspx
|
|
// http://www.pinvoke.net/default.aspx/Enums/StgmConstants.html
|
|
[Flags]
|
|
public enum STGM
|
|
{
|
|
STGM_READ = 0x0,
|
|
STGM_WRITE = 0x1,
|
|
STGM_READWRITE = 0x2,
|
|
STGM_SHARE_DENY_NONE = 0x40,
|
|
STGM_SHARE_DENY_READ = 0x30,
|
|
STGM_SHARE_DENY_WRITE = 0x20,
|
|
STGM_SHARE_EXCLUSIVE = 0x10,
|
|
STGM_PRIORITY = 0x40000,
|
|
STGM_CREATE = 0x1000,
|
|
STGM_CONVERT = 0x20000,
|
|
STGM_FAILIFTHERE = 0x0,
|
|
STGM_DIRECT = 0x0,
|
|
STGM_TRANSACTED = 0x10000,
|
|
STGM_NOSCRATCH = 0x100000,
|
|
STGM_NOSNAPSHOT = 0x200000,
|
|
STGM_SIMPLE = 0x8000000,
|
|
STGM_DIRECT_SWMR = 0x400000,
|
|
STGM_DELETEONRELEASE = 0x4000000
|
|
}
|
|
}
|
|
}
|