我正在尝试运行一个在启动时调用CoInitializeSecurity
的应用程序。这在Visual Studio 2013中有效,但在Visual Studio 2017中不适用-我很好奇为什么会这样。
在Visual Studio 2017中启动时调用CoInitializeSecurity时,我得到一个错误代码为COMException
的RPC_E_TOO_LATE (0x80010119)
,该错误代码表示已对CoInitialize
进行了调用,这在Visual Studio 2013中不会发生。
在启用Visual Studio托管进程或在调用CoInitializeSecurity
之前加载使用COM的程序集的情况下,我在Visual Studio 2013中已经看到了此行为。
加载的程序集在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 \ WindowsBase.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 \ assembly \ 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'。
远程调试器使我感到怀疑,因为它使我想起了Visual Studio托管过程。另一行不同之处是System.Core.dll
,它没有出现在VS2013的已加载程序集中。
码:
应用程式
<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外部运行相同的可执行文件时则不会出现。
最佳答案
您正在与VS2017中的托管调试引擎中的更改作斗争。它与您的猜测无关,我认为Visual Studio Hosting Process选项的删除很可能与之相关。盲目猜测,这是一个黑匣子,如果没有Microsoft调试器团队中的任何人的帮助,很难穿透。
您有几种可能的解决方法,按实用性排序:
在工具>选项>调试>常规中,选中“使用托管的兼容模式”复选框。这将新的调试引擎替换为上一次在VS2010中使用的旧调试引擎。您会错过一些最新的调试器功能(新的PDB格式,返回值检查,64位Edit + Continue),这些几乎不会阻止您调试WPF应用程序。
如果不需要,可以阻止该函数引发异常。将[DllImport]的PreserveSig属性更改为true,将返回类型从void更改为int。它仍然会失败,由负的返回值指示,但是您可以继续调试其余代码。也许您想使用返回值来设置一个全局变量,以用于绕过棘手的COM代码。
如果不需要,可以将初始化调试引擎的时间推迟到CoInitializeSecurity调用之后。附加System.Diagnostics.Debugger.Launch();
,并用#if DEBUG
包裹。现在,您可以按Ctrl + F5开始调试,在出现提示时,将VS的运行实例选择为所需的调试器。使用调试>附加到进程是一个类似的解决方法。
关于c# - CoInitializeSecurity在Visual Studio 2017中引发RPC_E_TOO_LATE,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/54437684/