Winforms 以编程方式关闭/取消打开X509Certificate2UI证书选择和pin对话框,无需进一步的用户交互

Winforms 以编程方式关闭/取消打开X509Certificate2UI证书选择和pin对话框,无需进一步的用户交互,winforms,cryptography,x509,Winforms,Cryptography,X509,我有一个在Winforms.NET 4.7.2应用程序的C任务对象部分执行的函数,该应用程序要求用户使用X509Certificate2UI类从windows证书存储中选择证书。 当使用取消令牌取消任务时,可能会出现相应的选择对话框打开并等待用户输入的情况。我的期望是选择对话框也会自动关闭/取消,但它仍然保持打开状态 同样的问题也适用于用于输入保护证书私钥的PIN的对话框 是否有任何干净的方法以编程方式取消对话框,或确保它与任务一起关闭 下面的代码演示了这个问题。一个任务打开选择对话框。第二个任

我有一个在Winforms.NET 4.7.2应用程序的C任务对象部分执行的函数,该应用程序要求用户使用X509Certificate2UI类从windows证书存储中选择证书。 当使用取消令牌取消任务时,可能会出现相应的选择对话框打开并等待用户输入的情况。我的期望是选择对话框也会自动关闭/取消,但它仍然保持打开状态

同样的问题也适用于用于输入保护证书私钥的PIN的对话框

是否有任何干净的方法以编程方式取消对话框,或确保它与任务一起关闭

下面的代码演示了这个问题。一个任务打开选择对话框。第二个任务模拟对话框打开后触发的事件。完成DoSomethingDifferent后,不再需要证书,因此应关闭选择对话框。但是,它会一直打开,直到程序退出

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CancelCertificateDialog
{
class Program
{



    private static X509Certificate2 SelectCertificate()
    {
        // Selecte certificate from store
        var store = new X509Store(StoreName.My, StoreLocation.CurrentUser);
        store.Open(OpenFlags.ReadOnly | OpenFlags.OpenExistingOnly);
        X509Certificate2Collection collection = (X509Certificate2Collection)store.Certificates;
        X509Certificate2Collection selectedCertificate = (X509Certificate2Collection)collection.Find(X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, false);// (X509FindType.FindByKeyUsage, X509KeyUsageFlags.DigitalSignature, true);

        selectedCertificate = X509Certificate2UI.SelectFromCollection(
        store.Certificates,
        "Certficates",
        "Select a certificate for signing the document",
        X509SelectionFlag.SingleSelection);


        return selectedCertificate[0];
    }


    private static void DoSomethingDifferent()
    {
        Thread.Sleep(4000);
        Console.WriteLine("I'm done");
    }


    static void Main(string[] args)
    {

        Console.WriteLine("Start");
        CancellationTokenSource tokenSource = new CancellationTokenSource();
        CancellationToken token = tokenSource.Token;
        Task<X509Certificate2> t1 = new Task<X509Certificate2>(() => SelectCertificate(), token);
        Task t2 = new Task(() => DoSomethingDifferent(), token);

        t1.Start();
        t2.Start();

        try
        {
            Task.WaitAny(t1, t2);
        }
        catch (AggregateException e)
        {

            for (int j = 0; j < e.InnerExceptions.Count; j++)
            {
                Console.WriteLine(e.InnerExceptions[j]);
            }

        }
        Console.WriteLine("The certificate is not required anymore. Get rid of the dialog");
        tokenSource.Cancel();
        Console.WriteLine("Press Key");
        Console.ReadKey();

    }
}
}

请共享一个。请注意,PIN对话框是由Windows还是由智能卡特定软件生成取决于一点。你知道这两个中的哪一个吗?它也是一个通用对话框,还是包括商标或公司名称@RezaAghaei:这有点棘手,因为包括Windows证书商店有点难。尽管如此,您当前用于生成/发送取消令牌的代码还是很有用的。我添加了一个小型C程序来演示这个问题。如何删除/停止打开对话框的任务,从而关闭对话框。