How to P/Invoke CryptUIWizExport Function using .NET

生来就可爱ヽ(ⅴ<●) 提交于 2019-12-06 09:24:12

You can use CryptUIWizExport function in different situations. Here is an example to export a certificate. This example can be easy modified for using it to the situations in which you need it.

using System;
using System.Runtime.InteropServices;
using System.Security.Cryptography.X509Certificates;

namespace CryptUIWizExportTest {
    using HCERTSTORE = IntPtr;
    using HWND = IntPtr;

    static internal class NativeMethods {
        internal enum CryptuiExportChoice : uint {
            CRYPTUI_WIZ_EXPORT_CERT_CONTEXT = 1,
            CRYPTUI_WIZ_EXPORT_CTL_CONTEXT = 2,
            CRYPTUI_WIZ_EXPORT_CRL_CONTEXT = 3,
            CRYPTUI_WIZ_EXPORT_CERT_STORE = 4,
            CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY = 5,
            CRYPTUI_WIZ_EXPORT_FORMAT_CRL = 6,
            CRYPTUI_WIZ_EXPORT_FORMAT_CTL = 7
        }

        [StructLayout (LayoutKind.Sequential)]
        internal struct CRYPTUI_WIZ_EXPORT_INFO {
            internal uint dwSize;
            //Required: should be set to sizeof(CRYPTUI_WIZ_EXPORT_INFO)

            internal string pwszExportFileName;
            //Required if the CRYPTUI_WIZ_NO_UI flag is set, Optional otherwise.
            //The fully qualified file name to export to, if this is
            //non-NULL and the CRYPTUI_WIZ_NO_UI flag is NOT set, then it is
            //displayed to the user as the default file name

            internal CryptuiExportChoice dwSubjectChoice;
            //Required: indicate the type of the subject:
            //          If can one of the following:
            //          CRYPTUI_WIZ_EXPORT_CERT_CONTEXT
            //          CRYPTUI_WIZ_EXPORT_CTL_CONTEXT
            //          CRYPTUI_WIZ_EXPORT_CRL_CONTEXT
            //          CRYPTUI_WIZ_EXPORT_CERT_STORE
            //          CRYPTUI_WIZ_EXPORT_CERT_STORE_CERTIFICATES_ONLY

            internal IntPtr pCertContext;
            //union
            //{
            //    PCCERT_CONTEXT      pCertContext;
            //    PCCTL_CONTEXT       pCTLContext;
            //    PCCRL_CONTEXT       pCRLContext;
            //    HCERTSTORE          hCertStore;
            //};

            internal uint cStores;
            // Optional: count of extra stores to search for the certs in the
            //           trust chain if the chain is being exported with a cert.
            //           this is ignored if dwSubjectChoice is anything other
            //           than CRYPTUI_WIZ_EXPORT_CERT_CONTEXT

            internal HCERTSTORE rghStores;
            // HCERTSTORE* !!!!
            // Optional: array of extra stores to search for the certs in the
            //           trust chain if the chain is being exported with a cert.
            //           this is ignored if dwSubjectChoice is anything other
            //           than CRYPTUI_WIZ_EXPORT_CERT_CONTEXT

        };

        [DllImport ("Cryptui.dll", CharSet = CharSet.Unicode,
                    ExactSpelling = true, SetLastError = true)]
        [return: MarshalAs (UnmanagedType.Bool)]
        internal static extern bool CryptUIWizExport (uint dwFlags,
            HWND hwndParent, string pwszWizardTitle,
            IntPtr pExportInfo, IntPtr pvoid);
    }
    class Program {
        static void Main (string[] args) {
            X509Certificate2 x509 = new X509Certificate2(@"c:\Test.pfx", "test");
            if (x509 == null)
                return;

            NativeMethods.CRYPTUI_WIZ_EXPORT_INFO exportInfo =
                new NativeMethods.CRYPTUI_WIZ_EXPORT_INFO ();
            exportInfo.dwSize = (uint)Marshal.SizeOf (
                typeof (NativeMethods.CRYPTUI_WIZ_EXPORT_INFO));
            //exportInfo.pwszExportFileName = @"C:\TEMP\tt.cer";
            exportInfo.dwSubjectChoice =
                NativeMethods.CryptuiExportChoice.CRYPTUI_WIZ_EXPORT_CERT_CONTEXT;
            exportInfo.pCertContext = x509.Handle;
            exportInfo.cStores = 0;

            IntPtr pExportInfo = Marshal.AllocHGlobal ((int)exportInfo.dwSize);
            Marshal.StructureToPtr (exportInfo, pExportInfo, false);
            NativeMethods.CryptUIWizExport (0, IntPtr.Zero,
                "Export of Certificate", pExportInfo, IntPtr.Zero);
        }
    }
}

Try using the PInvoke Interop Assistant. You can point it to a header file and it will generate p/invoke signatures for you.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!