【问题标题】:How to P/Invoke CryptUIWizExport Function using .NET如何使用 .NET P/Invoke CryptUIWizExport 函数
【发布时间】:2010-07-11 18:08:48
【问题描述】:

任何人都可以将这两个 cryptui.dll 函数/结构翻译成 C#.NET [dllimport] 包装器吗?我想 P/Invoke CryptUIWizExport 函数以显示 Windows 证书导出向导。特别是,我需要将 .NET X509Certificate 作为参数传递给 CryptUIWizExport 函数。非常感谢您的帮助!!!

CryptUIWizExport function

BOOL WINAPI CryptUIWizExport(
  __in  DWORD dwFlags,
  __in  HWND hwndParent,
  __in  LPCWSTR pwszWizardTitle,
  __in  PCCRYPTUI_WIZ_EXPORT_INFO pExportInfo,
  __in  void *pvoid
);

typedef struct _CRYPTUI_WIZ_EXPORT_INFO {
  DWORD      dwSize;
  LPCWSTR    pwszExportFileName;
  DWORD      dwSubjectChoice;
  union {
    PCCERT_CONTEXT pCertContext;
    PCCTL_CONTEXT  pCTLContext;
    PCCRL_CONTEXT   pCRLContext;
    HCERTSTORE     hCertStore;
  } ;
  DWORD      cStores;
  HCERTSTORE *rghStores;
} CRYPTUI_WIZ_EXPORT_INFO, *PCRYPTUI_WIZ_EXPORT_INFO;

【问题讨论】:

  • 没有“C#.NET”之类的东西。它只是“C#”。

标签: c# .net security pinvoke x509certificate


【解决方案1】:

您可以在不同的情况下使用CryptUIWizExport 函数。这是导出证书的示例。可以轻松修改此示例,以便在您需要的情况下使用它。

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

【讨论】:

    【解决方案2】:

    尝试使用PInvoke Interop Assistant。您可以将它指向一个头文件,它会为您生成 p/invoke 签名。

    【讨论】:

    • 您好 Quartermeister,我曾尝试使用 PInvoke 互操作助手,但收效甚微 - 我没有此 dll 的头文件?谢谢
    • Windows 头文件应由 Visual Studio 安装在 %WindowsSdkDir% 中,类似于 C:\Program Files\Microsoft SDKs\Windows\v6.0A\。如果没有,可以从 Microsoft 下载 Windows SDK。
    • _CRYPTUI_WIZ_EXPORT_INFO stuct 包含一个联合,我不确定如何在 P/Invoke 中表示它。我想我需要使用 LayoutKind.Explicit 和/或 FieldOffsets 但我不确定如何使用?有什么想法吗?
    • 您可以只声明一个IntPtr 而不是union。如果你愿意,我可以发布一个在 C# 中使用 CryptUIWizExport 的小例子
    • 如果没问题我想要那个
    猜你喜欢
    • 1970-01-01
    • 2015-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-31
    • 1970-01-01
    • 1970-01-01
    • 2010-12-04
    相关资源
    最近更新 更多