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; } |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步