Silverlight5通过P/Invoke调用系统win32的三个示例
调用Win32函数
public partial class MainPage : UserControl { [DllImportAttribute("user32.dll", EntryPoint = "MessageBoxW")] public static extern int MessageBoxW( [In]System.IntPtr hWnd, [In][MarshalAs(UnmanagedType.LPWStr)] string lpText, [In][MarshalAs(UnmanagedType.LPWStr)] string lpCaption, uint uType); [DllImport("user32.dll", EntryPoint = "MessageBoxA")] static extern int MsgBox(int hWnd, string msg, string caption, int type); [DllImport("kernel32.dll")] public static extern bool Beep(int frequency, int duration); [DllImport("learnDll.dll")]//, EntryPoint = "fnlearnDll" public static extern int fnlearnDll(); public void PlaySound() { Random random = new Random(); for (int i = 0; i < 50; i++) { Beep(random.Next(10000), 100); } } public MainPage() { InitializeComponent(); } private void button1_Click(object sender, RoutedEventArgs e) { PlaySound(); MsgBox(0, "Hello", "Interop", 0); //MessageBoxW(IntPtr.Zero, "Hello", "Interop", 0); fnlearnDll(); } }
-------------------------------------------------------------------------------------------------------------------------------------------------------------
USB设备插取识别
public partial class SilverlightControl1 : UserControl { // Importing a set of necessary native methods from Win32 API. [DllImport("User32", EntryPoint = "CreateWindowEx", CharSet = CharSet.Auto, SetLastError = true)] static extern IntPtr CreateWindowEx(int dwExStyle, string lpszClassName, string lpszWindowName, int style, int x, int y, int width, int height, IntPtr hWndParent, IntPtr hMenu, IntPtr hInst, [MarshalAs(UnmanagedType.AsAny)] object pvParam); [DllImport("user32.dll")] static extern IntPtr DefWindowProc(IntPtr hWnd, int uMsg, IntPtr wParam, IntPtr lParam); [DllImport("user32", CharSet = CharSet.Auto, SetLastError = true)] public static extern short RegisterClass(WNDCLASS wc); // Marshaling the Window structure. [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)] public class WNDCLASS { public int style; public WndProc lpfnWndProc; public int cbClsExtra; public int cbWndExtra; public IntPtr hInstance; public IntPtr hIcon; public IntPtr hCursor; public IntPtr hbrBackground; public string lpszMenuName; public string lpszClassName; } //system detects USB insertion/removal const int WM_DEVICECHANGE = 0x0219; // system detects a new device const int DBT_DEVICEARRIVAL = 0x8000; // device removed const int DBT_DEVICEREMOVECOMPLETE = 0x8004; // Callbacks must have AllowReversePInvokeCalls attribute. [AllowReversePInvokeCalls] private IntPtr Callback(IntPtr hWnd, int msg, IntPtr wparam, IntPtr lparam) { if (msg == WM_DEVICECHANGE) { if (wparam.ToInt32() == DBT_DEVICEARRIVAL) textBlock1.Text = "USB inserted"; if (wparam.ToInt32() == DBT_DEVICEREMOVECOMPLETE) textBlock1.Text = "USB removed"; } return DefWindowProc(hWnd, msg, wparam, lparam); } public delegate IntPtr WndProc( IntPtr hWnd, int msg, IntPtr wParam, IntPtr lParam); // Preventing garbage collection of the delegate private static WndProc dontGCthis; public SilverlightControl1() { InitializeComponent(); WNDCLASS wc = new WNDCLASS(); // Preventing garbage collection of the delegate dontGCthis = new WndProc(Callback); wc.lpfnWndProc = dontGCthis; // Note that you need to ensure unique names // for each registered class. // For example, if you open the same plugin // in two different tabs of the browser, // you still should not end up with // two registered classes with identical names. wc.lpszClassName = "foobar" + (new Random()).Next(); RegisterClass(wc); IntPtr createResult = CreateWindowEx(0, wc.lpszClassName, "Window title", 0, 100, 100, 500, 500, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero, 0); } }
-----------------------------------------------------------------------------------------------------------------
进程实时管理
<UserControl x:Class="SilverlightApplication10.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400" xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" xmlns:local="clr-namespace:SilverlightApplication10"> <UserControl.DataContext> <local:ProcessViewModel /> </UserControl.DataContext> <Grid x:Name="LayoutRoot" Margin="6" Background="White"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> </Grid.RowDefinitions> <TextBlock Text="Process Information" FontSize="16" /> <sdk:DataGrid Grid.Row="1" Margin="2" AutoGenerateColumns="true" ItemsSource="{Binding Processes}"/> </Grid> </UserControl>
public class PropertyChangeNotification : INotifyPropertyChanged { protected void RaisePropertyChanged(string property) { if (this.PropertyChanged != null) { this.PropertyChanged(this, new PropertyChangedEventArgs(property)); } } public event PropertyChangedEventHandler PropertyChanged; }
using System.ComponentModel; using System.Collections.Generic; using System.Windows; using System.Collections.ObjectModel; using System.Linq; using System.Windows.Threading; using System; using System.Threading.Tasks; public class ProcessViewModel : PropertyChangeNotification { public ProcessViewModel() { if (Application.Current.HasElevatedPermissions) { BuildInitialProcessList(); } } void BuildInitialProcessList() { this.Processes = new ObservableCollection<Process>(); BuildProcessList(); DispatcherTimer timer = new DispatcherTimer(); timer.Interval = TimeSpan.FromMilliseconds(500); timer.Tick += (s, e) => BuildProcessList(); timer.Start(); } void BuildProcessList() { IEnumerable<Process> newProcesses = Process.EnumerateCurrentList(); var newProcsOuterJoinedExisting = from np in newProcesses join op in this.Processes on np.Id equals op.Id into joinGroup from gp in joinGroup.DefaultIfEmpty() select new { NewProcess = np, OldProcess = gp }; foreach (var item in newProcsOuterJoinedExisting.ToList()) { if (item.OldProcess == null) { this.Processes.Add(item.NewProcess); } else { item.OldProcess.Refresh(); } } var remainingListOuterJoinedNewProcs = from cp in this.Processes join np in newProcesses on cp.Id equals np.Id into joinGroup from gp in joinGroup.DefaultIfEmpty() select new { CurrentProcess = cp, NewProcess = gp }; foreach (var item in remainingListOuterJoinedNewProcs.ToList()) { if (item.NewProcess == null) { this.Processes.Remove(item.CurrentProcess); } } } public ObservableCollection<Process> Processes { get { return (_Processes); } set { _Processes = value; RaisePropertyChanged("Processes"); } } ObservableCollection<Process> _Processes; }
using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.IO; internal class Win32Exception : Exception { public Win32Exception(string message, int errorCode) : base(message) { this.ErrorCode = errorCode; } public int ErrorCode { get; private set; } } public class Process : PropertyChangeNotification { [StructLayout(LayoutKind.Sequential)] struct PROCESS_MEMORY_COUNTERS { public UInt32 cb; public UInt32 PageFaultCount; public UIntPtr PeakWorkingSetSize; public UIntPtr WorkingSetSize; public UIntPtr QuotaPeakPagedPoolUsage; public UIntPtr QuotaPagedPoolUsage; public UIntPtr QuotaPeakNonPagedPoolUsage; public UIntPtr QuotaNonPagedPoolUsage; public UIntPtr PagefileUsage; public UIntPtr PeakPagefileUsage; }; public Process(UInt32 processId) { this.Id = processId; } public UInt32 Id { get; private set; } public UInt64 WorkingSetBytes { get { PROCESS_MEMORY_COUNTERS counters; IntPtr handle = GetHandle(); try { if (!GetProcessMemoryInfo(handle, out counters, (UInt32)Marshal.SizeOf(typeof(PROCESS_MEMORY_COUNTERS)))) { throw new Win32Exception("Failed to get memory info", Marshal.GetLastWin32Error()); } } finally { CloseHandle(handle); } return (counters.WorkingSetSize.ToUInt64()); } } public void Refresh() { this.RaisePropertyChanged("WorkingSetBytes"); } public string ImageName { get { if (string.IsNullOrEmpty(this.imageName)) { UInt32 capacity = 128; StringBuilder builder = new StringBuilder((int)capacity); IntPtr handle = GetHandle(); try { while (GetProcessImageFileName(handle, builder, capacity) == 0) { int errorCode = Marshal.GetLastWin32Error(); if (errorCode == ERROR_INSUFFICIENT_BUFFER) { capacity *= 2; builder = new StringBuilder((int)capacity); } else { throw new Win32Exception("Failed to get image name", errorCode); } } this.imageName = Path.GetFileName(builder.ToString()); } finally { CloseHandle(handle); } } return (this.imageName); } } string imageName; IntPtr GetHandle() { IntPtr handle = OpenProcess(PROCESS_QUERY_INFORMATION, false, this.Id); if (handle == IntPtr.Zero) { throw new Win32Exception("Failed to open process", Marshal.GetLastWin32Error()); } return (handle); } static bool TryOpenProcess(UInt32 id) { IntPtr ptr = OpenProcess(PROCESS_QUERY_INFORMATION, false, id); if (ptr != IntPtr.Zero) { CloseHandle(ptr); } return (ptr != IntPtr.Zero); } public static IEnumerable<Process> EnumerateCurrentList() { foreach (var processId in EnumerateProcessIds()) { if (TryOpenProcess(processId)) { yield return new Process(processId); } } } static IEnumerable<UInt32> EnumerateProcessIds() { UInt32[] processIds = new UInt32[32]; bool retry = true; while (retry) { processIds = new UInt32[processIds.Length * 2]; UInt32 arraySize = (UInt32)(Marshal.SizeOf(typeof(UInt32)) * processIds.Length); UInt32 bytesCopied = 0; retry = EnumProcesses(processIds, arraySize, out bytesCopied); if (retry) { retry = (bytesCopied == arraySize); } else { throw new Win32Exception("Failed enumerating processes", Marshal.GetLastWin32Error()); } } return (processIds); } [DllImport("psapi", SetLastError = true)] static extern bool EnumProcesses( [MarshalAs(UnmanagedType.LPArray)] [In] [Out] UInt32[] processIds, UInt32 processIdsSizeBytes, out UInt32 bytesCopied); [DllImport("kernel32", SetLastError = true)] static extern IntPtr OpenProcess(UInt32 dwAccess, bool bInheritHandle, UInt32 dwProcessId); [DllImport("kernel32")] static extern bool CloseHandle(IntPtr handle); [DllImport("psapi", SetLastError = true)] static extern UInt32 GetProcessImageFileName( IntPtr processHandle, [In] [Out] StringBuilder lpImageFileName, UInt32 bufferSizeCharacters); [DllImport("psapi", SetLastError = true)] static extern bool GetProcessMemoryInfo( IntPtr processHandle, out PROCESS_MEMORY_COUNTERS counters, UInt32 dwSize); static readonly UInt32 PROCESS_QUERY_INFORMATION = 0x0400; const int ERROR_ACCESS_DENIED = 5; const int ERROR_INVALID_PARAMETER = 87; const int ERROR_INSUFFICIENT_BUFFER = 122; }