See the question and my original answer on StackOverflow

Your interface definition is wrong because you did not defined methods in the same order as MSDN does (in fact, names are not important, what's important is the interface methods layout: matching binary signatures in the correct order). The order must be exactly what's defined in .h files available with the Windows SDK, not what MSDN displays - this is actually misleading :-). In this case, the header file is Shobjidl.h. This is how it's defined in C/C++:

MIDL_INTERFACE("D11AD862-66DE-4DF4-BF6C-1F5621996AF1")
IOpenControlPanel : public IUnknown
{
public:
    virtual HRESULT STDMETHODCALLTYPE Open( 
        /* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszName,
        /* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszPage,
        /* [unique][in] */ __RPC__in_opt IUnknown *punkSite) = 0;

    virtual HRESULT STDMETHODCALLTYPE GetPath( 
        /* [string][unique][in] */ __RPC__in_opt_string LPCWSTR pszName,
        /* [size_is][string][out] */ __RPC__out_ecount_full_string(cchPath) LPWSTR pszPath,
        /* [in] */ UINT cchPath) = 0;

    virtual HRESULT STDMETHODCALLTYPE GetCurrentView( 
        /* [out] */ __RPC__out CPVIEW *pView) = 0;

};

There are multiple equivalent definition in .NET, C#, but here is one that should work:

    [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    [Guid("D11AD862-66DE-4DF4-BF6C-1F5621996AF1")]
    public interface IOpenControlPanel
    {
        [PreserveSig]
        int Open([MarshalAs(UnmanagedType.LPWStr)] string name,
                 [MarshalAs(UnmanagedType.LPWStr)] string page,
                                                   IntPtr punkSite);
        [PreserveSig]
        int GetPath([MarshalAs(UnmanagedType.LPWStr)] string name,
                    [MarshalAs(UnmanagedType.LPWStr)] StringBuilder refPath,
                                                      int bufferSize);

        // if you remove PreserveSig, you can return the [out] param directly
        // note in this case, the function could throw instead of returning an error int like with PreserveSig
        ControlPanelView GetCurrentView();
    }