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;
  }

  

 

posted on 2011-12-30 16:00 chuncn 阅读(...) 评论(...) 编辑 收藏

导航