CoInitializeSecurity выбрасывает RPC_E_TOO_LATE в Visual Studio 2017 - PullRequest
0 голосов
/ 30 января 2019

Я пытаюсь запустить приложение, звонящее на CoInitializeSecurity при запуске.Это работает в Visual Studio 2013, но не работает в Visual Studio 2017 - и мне любопытно, почему это так.

При вызове CoInitializeSecurity при запуске в Visual Studio 2017 я получаю COMException с ошибкойкод RPC_E_TOO_LATE (0x80010119), который указывает, что вызов уже был сделан на CoInitialize, этого не происходит в Visual Studio 2013.

Я видел такое поведение ранее в Visual Studio 2013, когда включен процесс размещения Visual Studioили когда сборка с использованием COM загружена до вызова CoInitializeSecurity.

Загруженные сборки отличаются в Visual Studio 2013 и 2017 (снимок, сделанный при входе в конструктор App), выделенные различия:

2013:

'WPFTestVS2017.exe' (CLR v4.0.30319: DefaultDomain): загружен 'C: \ windows \ Microsoft.Net \ Assembly \ GAC_64 \ mscorlib\ v4.0_4.0.0.0__b77a5c561934e089 \ mscorlib.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: DefaultDomain): загружен' C: \ WPFTestVS2017 \ bin \ Debug \ WPFTestVS2017.exe '.

'WPFTestVS2017.exe' (CLR v4.0.30319: WPFTestVS2017.exe): загруженный файл C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ PresentationFramework \ v4.0_4.0.0.0__31bf3856ad364e35 \ PresentationFramework.dll'.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружен' C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ WindowsBase \ v4.0_4.0.0.0__31bf3856ad364e35 \ WindowsBase.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружен' C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ System \ v4.0_4.0.0.0__b77a5c561934e089\ System.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загруженный файл C: \ windows \ Microsoft.Net \ assembly \ GAC_64 \ PresentationCore \ v4.0_4.0.0.0__31bf3856ad364e35 \ PresentationCore.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружено' C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ System.Xaml \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Xaml.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружен'C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ System.Configuration \ v4.0_4.0.0.0__b03f5f7f11d50a3a \ System.Configuration.dll'.

'WPFTestVS2017.exe' (CLR v4.0.30319:WPFTestVS2017.exe): загруженный файл C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ System.Xml \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Xml.dll '.

2017:

'WPFTestVS2017.exe' (CLR v4.0.30319: DefaultDomain): загружен 'C: \ windows \ Microsoft.Net \ assembly \ GAC_64 \ mscorlib \ v4.0_4.0.0.0__b77a5c561934e089 \ mscorlib.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: DefaultDomain): загружен' C: \ WPFTestVS2017 \ bin \ Debug \ WPFTestVS2017.exe '.

«WPFTestVS2017.exe» (CLR v4.0.30319: WPFTestVS2017.exe): загружен «C: \ windows \ Microsoft.Net \ Assembly \ GAC_MSIL \ PresentationFramework \ v4.0_4.0.0.0__31bf3856ad364e35 \ PresentationFramework.dll '.

«WPFTestVS2017.exe» (CLR v4.0.30319: WPFTestVS2017.exe): загружен «C: \ windows \ Microsoft.Net \ assembly \ GAC_MSIL \ WindowsBase \ v4.0_4.0.0.0__31bf3856ad364e35 \ W»indowsBase.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружен' C: \ windows \ Microsoft.Net \ Assembly \ GAC_MSIL \ System.Core \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Core.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружено' C: \ windows \ Microsoft.Net \Assembly \ GAC_MSIL \ System \ v4.0_4.0.0.0__b77a5c561934e089 \ System.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружено' C: \ windows \ Microsoft.Net \ assembly \ GAC_64 \ PresentationCore \ v4.0_4.0.0.0__31bf3856ad364e35 \ PresentationCore.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загруженный файл C: \ windows \Microsoft.Net \ сборка \ GAC_MSIL \ System.Xaml \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Xaml.dll».

«WPFTestVS2017.exe» (CLR v4.0.30319: WPFTestVS2017.exe): загружен «C: \ Program Files (x86) \ Microsoft Visual Studio \ 2017 \ Enterprise \ Common7 \ IDE \ Remote Debugger \ x64 \»Runtime \ Microsoft.VisualStudio.Debugger.Runtime.dll '.

«WPFTestVS2017.exe» (CLR v4.0.30319: WPFTestVS2017.exe): загружен «C: \ windows \ Microsoft.Net \ assembly»\ GAC_MSIL \ System.Configuration \ v4.0_4.0.0.0__b03f5f7f11d50a3a \ System.Configuration.dll '.

' WPFTestVS2017.exe '(CLR v4.0.30319: WPFTestVS2017.exe): загружен C: \ windows\ Microsoft.Net \ assembly \ GAC_MSIL \ System.Xml \ v4.0_4.0.0.0__b77a5c561934e089 \ System.Xml.dll '.

Удаленный отладчик вызывает у меня подозрения, поскольку напоминает визуальныйСтудия хостинга.Другая отличающаяся строка - это System.Core.dll, который не отображается в загруженных сборках в VS2013.

Код:

App.xaml

<Application x:Class="WPFTestVS2017.App"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            StartupUri="MainWindow.xaml">
</Application>

App.xaml.cs

using System;
using System.Runtime.InteropServices;
using System.Windows;

namespace WPFTestVS2017
{
    internal static class NativeMethods
    {
        private enum RpcAuthnLevel
        {
            Default = 0,
            None = 1,
            Connect = 2,
            Call = 3,
            Pkt = 4,
            PktIntegrity = 5,
            PktPrivacy = 6
        }

        private enum RpcImpLevel
        {
            Default = 0,
            Anonymous = 1,
            Identify = 2,
            Impersonate = 3,
            Delegate = 4
        }

        private enum EoAuthnCap
        {
            None = 0x0000,
            MutualAuth = 0x0001,
            StaticCloaking = 0x0020,
            DynamicCloaking = 0x0040,
            AnyAuthority = 0x0080,
            MakeFullSIC = 0x0100,
            Default = 0x0800,
            SecureRefs = 0x0002,
            AccessControl = 0x0004,
            AppID = 0x0008,
            Dynamic = 0x0010,
            RequireFullSIC = 0x0200,
            AutoImpersonate = 0x0400,
            NoCustomMarshal = 0x2000,
            DisableAAA = 0x1000
        }

        [DllImport("Ole32.dll",
            ExactSpelling = true,
            EntryPoint = "CoInitializeSecurity",
            CallingConvention = CallingConvention.StdCall,
            SetLastError = false,
            PreserveSig = false)]
        private static extern void CoInitializeSecurity(
            IntPtr pVoid,
            int cAuthSvc,
            IntPtr asAuthSvc,
            IntPtr pReserved1,
            uint dwAuthnLevel,
            uint dwImpLevel,
            IntPtr pAuthList,
            uint dwCapabilities,
            IntPtr pReserved3);

        public static void Initialize()
        {
            CoInitializeSecurity(IntPtr.Zero,
                -1,
                IntPtr.Zero,
                IntPtr.Zero,
                (uint)RpcAuthnLevel.PktPrivacy,
                (uint)RpcImpLevel.Impersonate,
                IntPtr.Zero,
                (uint)EoAuthnCap.DynamicCloaking,
                IntPtr.Zero);
        }
    }

    public partial class App : Application
    {
        public App()
        {
            NativeMethods.Initialize();
        }
    }
}

MainWindow.xaml

<Window x:Class="WPFTestVS2017.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/>

MainWindow.xaml.cs

using System.Windows;

namespace WPFTestVS2017
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
    }
}

Редактировать:

Я внес следующие изменения в App.xaml.cs:

public App()
{
    try
    {
        NativeMethods.Initialize();
    }
    catch (Exception e)
    {
        MessageBox.Show(e.ToString());
    }
}

Окно сообщения появляется при отладке в Visual Studio 2017, однако оно не отображается при запуске того же исполняемого файла вне Visual Studio.

1 Ответ

0 голосов
/ 01 февраля 2019

Вы сражаетесь с изменениями в механизме управляемой отладки в VS2017.Это не имеет ничего общего с тем, что вы уже догадались, я полагаю, довольно вероятно, что удаление опции хостинга Visual Studio связано.Слепое предположение, что это черный ящик, в который очень трудно проникнуть без помощи кого-либо из команды отладчика Microsoft.

У вас есть несколько возможных обходных путей, отсортированных по практичности:

  1. Инструменты> Параметры> Отладка> Общие, установите флажок «Использовать режим управляемой совместимости».Это заменяет новый механизм отладки на старый, последний использовавшийся в VS2010.Вы упустите некоторые недавние функции отладчика (новый формат PDB, проверка возвращаемых значений, 64-разрядное редактирование + продолжение), и это мало того, что может помешать вам отладить приложение WPF.

  2. Если нежелательно, вы можете запретить функции генерировать исключение.Измените свойство PreserveSig [DllImport] на true, измените тип возвращаемого значения с void на int.Он все равно потерпит неудачу, о чем свидетельствует отрицательное возвращаемое значение, но вы можете продолжать отлаживать оставшуюся часть кода.Возможно, вы захотите использовать возвращаемое значение, чтобы установить глобальную переменную, которую вы будете использовать для обхода хитрого COM-кода.

  3. Если нежелательно, вы можете отложить инициализацию механизма отладки до окончанияВызов CoInitializeSecurity.Добавить System.Diagnostics.Debugger.Launch();, завернутый в #if DEBUG.Теперь вы можете нажать Ctrl + F5, чтобы начать отладку, выбрать запущенный экземпляр VS в качестве желаемого отладчика, когда вы получите приглашение.Использование «Отладка»> «Присоединить к процессу» аналогично работе.

...