使用 Delphi 10 从 c# dll 打开 windows 证书列表

Open windows certificate list from c# dll using Delphi 10

我一整天都在尝试遵循一些教程和关于这个主题的许多答案,但无法弄清楚我做错了什么。 Delphi 甚至无法编译,我需要签署一些 XML 文档,我认为 ref 或 out 字符串参数是最好的方式。在此先感谢您的帮助。

DLL:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Xml;
using RGiesecke.DllExport;
using System.Runtime.InteropServices;

    namespace Test
    {
        public class Test
        {

            [DllExport(CallingConvention = CallingConvention.StdCall)]
            [return: MarshalAs(UnmanagedType.LPWStr)]
            [ComVisible(true)]

            public static void ShowCertificatesList([MarshalAs(UnmanagedType.BStr)] ref string pXmlDoc)
            {
                pXmlDoc = "test";
                var store = new X509Store(StoreLocation.CurrentUser);
                store.Open(OpenFlags.ReadOnly);
                var certificates = store.Certificates;
                X509CertificateCollection vListaCertificados;

                vListaCertificados = X509Certificate2UI.SelectFromCollection(certificates, "test", "Certificate list", X509SelectionFlag.SingleSelection);
            }
        }
    }

它适用于 Windows 形式:

private void button1_Click(object sender, EventArgs e)
    {
        string TestStr= "123";
        Test.Test.ShowCertificatesList(ref TestStr);


    }

但不是来自 Delphi:

 var
   Form3: TForm3;

    procedure ShowCertificatesList(var pStrRef : String) ; stdcall; external 'Test.dll' name 'ShowCertificatesList';

    implementation

    {$R *.dfm}

  procedure TForm3.Button1Click(Sender: TObject);
    var
    vStrRef: String;
    begin
      vStrRef:=  'in' ;
      ShowCertificatesList(vStrRef);
      vStrRef := vStrRef;
  end;

只是为了说明另一种方法。

您始终可以直接通过本机 API 操作 Windows 证书存储(.NET 也使用此类),如博文中所揭示的那样,

http://vanillasky-room.cocolog-nifty.com/blog/2013/10/cryptoapi-and-c.html(日文,但Google可以翻译成英文)。

Delphi 函数声明不正确。使用WideString匹配BStr:

procedure ShowCertificatesList(var pStrRef: WideString);
  stdcall; external 'Test.dll';

应从 C# 代码中删除以下属性:

[return: MarshalAs(UnmanagedType.LPWStr)]
[ComVisible(true)]

该函数没有 return 值,您没有使用 COM。

如果是我,我会使用原生 Windows API。