Question

I'm adding new disk device to system from my C# code, so I want to call

[System.Runtime.InteropServices.DllImport("Shell32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
public extern static void SHChangeNotify(long wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

like below

MyWin32Functions.SHChangeNotify(0x00000100/*ADDRIVE*/, 0x0005/*PATHW*/, driveLetter, IntPtr.Zero); 

dwItem1 is void* and we should pass a wchar_t* (pointing to null terminated string) containing drive root in this case; so driveLetter above is

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

(my code almost same as code in similiar case: How to call SHChangeNotify from C# without error 14007 but I get System.AccessViolationException)

Any suggestions what am I doing wrong?

Was it helpful?

Solution

The first parameter in your interop signature should be an int, not a long. Though the Win32 function is declared as LONG, a LONG in Win32 is 32-bit.

[System.Runtime.InteropServices.DllImport("Shell32.dll")]
public extern static void SHChangeNotify(int wEventId, uint uFlags, IntPtr dwItem1, IntPtr dwItem2);

This MSDN article shows the common mapping between Win32 types an .NET types for Platform Invoke.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top