How do I solve this "P/Invoke declarations should be portable"?

c#, pinvoke

Solution

The MSDN page that the warning refers to is the documentation of the native function `SHGetFileInfo`. It gives the signature as:

DWORD_PTR SHGetFileInfo(
  __in     LPCTSTR pszPath,
  DWORD dwFileAttributes,
  __inout  SHFILEINFO *psfi,
  UINT cbFileInfo,
  UINT uFlags
);

So the first warning is referring to the fact that `DWORD_PTR` is a pointer sized unsigned integer. That means you should use `UIntPtr`.

The next thing that jumps out is that the `SHFILEINFO` struct is indicated as `__inout`. That means you need to pass it by `ref`.

So the p/invoke declaration should be:

[DllImport("shell32", CharSet=CharSet.Unicode)]
private static extern UIntPtr SHGetFileInfo(
    string pszPath, 
    uint dwFileAttributes, 
    ref SHFILEINFO psfi, 
    uint cbFileInfo, 
    uint flags
);

The final warning is simple to resolve. Simply place your p/invoke declaration inside a class named `NativeMethods`.

Problem

This code: ``` [DllImport("shell32", CharSet=CharSet.Unicode)] private static extern int SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint flags); ``` Causes the following Code Analysis problem: CA1901 P/Invoke declarations should be portable As it is declared in your code, the return type of P/Invoke 'IconUtil.SHGetFileInfo(string, uint, out IconUtil.SHFILEINFO, uint, uint)' will be 4 bytes wide on 64-bit platforms. This is not correct, as the actual native declaration of this API indicates it should be 8 bytes wide on 64-bit platforms. Consult the MSDN Platform SDK documentation for help determining what data type should be used instead of 'int'. What am I supposed to do? I tried "consulting MSDN", but I'm not really sure what the problem even means. I also get this for the same line: CA1060 Move P/Invokes to NativeMethods class Because it is a P/Invoke method, 'IconUtil.SHGetFileInfo(string, uint, out IconUtil.SHFILEINFO, uint, uint)' should be defined in a class named NativeMethods, SafeNativeMethods, or UnsafeNativeMethods.

Original source