我正在从我的C#代码向系统添加新的磁盘设备,所以我想调用
[System.Runtime.InteropServices.DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static void SHChangeNotify(long wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
如下所示
MyWin32Functions.SHChangeNotify(0x00000100/*ADDRIVE*/, 0x0005/*PATHW*/, driveLetter, IntPtr.Zero);
dwItem1是void *,在这种情况下我们应该传递包含驱动器根的wchar_t *(指向空终止字符串);所以上面的driveLetter是
string letter = "Z:\\";
byte[] data = Encoding.Default.GetBytes(letter);
byte[] zdata = new byte[data.Length + 1];
data.CopyTo(zdata, 0);
IntPtr p = System.Runtime.InteropServices.Marshal.AllocHGlobal(zdata.Length);
System.Runtime.InteropServices.Marshal.Copy(zdata, 0, p, zdata.Length);
(我的代码几乎与代码中的代码相同:How to call SHChangeNotify from C# without error 14007 但我得到System.AccessViolationException)
有什么建议我做错了吗?
答案 0 :(得分:2)
互操作签名中的第一个参数应为int
,而不是long
。虽然Win32函数声明为LONG,但Win32中的LONG是32位。
[System.Runtime.InteropServices.DllImport("Shell32.dll")]
public extern static void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);
This MSDN article显示了Win32类型与Platform Invoke的.NET类型之间的公共映射。