| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Общие вопросы по .NET и C# > AccessViolationException не обработано |
| Автор: losko 8.8.2012, 06:43 |
| Доброго всем дня. Пишу программу на С# в Visual Studio 2010. Очень очень нужна ваша помощь. Сколько не бьюсь ничего не получается. Суть проблемы вкратце: есть некий сертификат в хранилище MY текущего пользователя , этому сертификату соответствует закрытый ключ, находящийся в контейнере в реестре системы. Мне нужно вывести в консоль имя контейнера с этим сертификатом и ссылку на хранилище этого контейнера. Чтобы в консоли отображалось примерно следующее: REGISTRY\\Имя контейнера Решение задачи сводится к реализации функции GetCertCertificateContextProperty через PInvoke. При компиляции кода выбрасывается исключение AccessViolationException. Вопрос как его обработать? код программы: using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Security.Permissions; using System.IO; using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using System.Runtime.InteropServices; namespace ConsoleApplication1 { class Crypto { [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Unicode)] public struct CRYPT_KEY_PROV_INFO { [MarshalAs(UnmanagedType.LPWStr)] public string pwszContainerName; [MarshalAs(UnmanagedType.LPWStr)] public string pwszProvName; public uint dwProvType; public uint dwFlags; public uint cProvParam; public IntPtr rgProvParam; public uint dwKeySpec; } [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)] public struct CRYPTOAPI_BLOB { public uint cbData; public IntPtr pbData; } [DllImport("crypt32.dll")] public static extern bool CertGetCertificateContextProperty( IntPtr pCertContext, uint dwPropId, IntPtr pvData, ref uint pcbData); public static CRYPT_KEY_PROV_INFO GetCertificateContextProperty(X509Certificate2 certificate) { try { IntPtr certhandle = certificate.Handle; uint pcbData = 0; if (CertGetCertificateContextProperty(certhandle, 2, IntPtr.Zero, ref pcbData)) { IntPtr memoryChunk = Marshal.AllocHGlobal((int)pcbData); try { if (CertGetCertificateContextProperty(certhandle, 2, memoryChunk, ref pcbData)) { CRYPT_KEY_PROV_INFO context = (CRYPT_KEY_PROV_INFO)Marshal.PtrToStructure (memoryChunk, typeof(CRYPT_KEY_PROV_INFO)); return context; } else { throw new Exception("Произошел сбой!"); } } finally { Marshal.FreeHGlobal(memoryChunk); } } } finally { throw new Exception("Произошел сбой: Context Property"); throw new AccessViolationException(); } } static void Main(string[] args) { X509Certificate2 mycertificate = new X509Certificate2(); CRYPT_KEY_PROV_INFO Info = GetCertificateContextProperty(mycertificate); Console.WriteLine("Имя контейнера:", Info.pwszContainerName.ToString()); Console.WriteLine("Криптопровайдер:", Info.pwszProvName.ToString()); var keyStore = new X509Store("MY", StoreLocation.CurrentUser); keyStore.Open(OpenFlags.OpenExistingOnly | OpenFlags.ReadWrite); var cert = keyStore.Certificates.Count; { Console.WriteLine("В хранилище текущего пользователя сертификатов: {0}", cert); } int kol = 0; List<X509Certificate> list = new List<X509Certificate>(); foreach (var c in keyStore.Certificates) { kol += c.HasPrivateKey ? 1 : 0; // если свойство HasPrivateKey равно true, то к kol прибавляется единица, иначе прибавляется нуль if (c.HasPrivateKey == true) { list.Add©; // выводим список всех сертификатов с закрытым ключом } } Console.WriteLine("Количество сертификатов с закрытым ключом: {0}", kol.ToString()); foreach (var item in list) { Console.WriteLine(item.ToString()); } Console.ReadKey(); } } } |