gpt4 book ai didi

c# - Activator.CreateInstance() 在 VSIDE 内部工作,但不在外部工作

转载 作者:太空狗 更新时间:2023-10-29 21:10:22 26 4
gpt4 key购买 nike

我有一堆 COM 对象,它们都实现了相同的接口(interface),并且需要创建一个在运行时从选项列表中选择的对象。因为我知道每个实现 COM 服务器的 CLSID,所以这应该很容易。但是,对于 COM 库的某个子集,我只能在 VS2010 IDE 中运行时才能完成这项工作。

这是我用来测试的整个程序:

using System;

namespace ComTest
{
class Program
{
static void Main(string[] args)
{
var clsid = "{E8978DA6-047F-4E3D-9C78-CDBE46041603}";
var type = Type.GetTypeFromCLSID(new Guid(clsid));
var obj = Activator.CreateInstance(type, true);
Console.WriteLine("Obj is {0}", obj);
}
}
}

只要我通过 VS2010 运行,我就可以为目前为止我尝试过的每个 COM CLSID 工作。无论是否附加调试器,无论是否附加托管进程,我都会从 CreateInstance 返回一个 System.__ComObject

当我从控制台窗口编译并运行这段代码时,对于某些 CLSID 值,我得到:

Unhandled Exception: System.Runtime.InteropServices.COMException: Creating an instance of the COM component with CLSID {E8978DA6-047F-4E3D-9C78-CDBE46041603} from the IClassFactory failed due to the following error: 80004005.
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean noCheck, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor, Boolean& bNeedSecurityCheck)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean skipCheckThis, Boolean fillCache)
at System.RuntimeType.CreateInstanceDefaultCtor(Boolean publicOnly, Boolean skipVisibilityChecks, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic)
at ComTest.Program.Main(String[] args) in

这只发生在特定的 CLSID 上——例如,“{c1243ca0-bf96-11cd-b579-08002b30bfeb}”(内置文本 IFilter)有效,但“{E8978DA6-047F-4E3D-9C78-CDBE46041603} "(Acrobat Reader X 的 IFilter)没有。我无法弄清楚的是,通过 IDE 运行在 COM Interop 调用是否成功时会有什么不同。有什么想法吗?

编辑:

我没有以管理员身份运行 VS2010,但我已经尝试通过提升的 Powershell 控制台运行输出二进制文件,但它仍然不起作用。

编辑 2:

到目前为止,我使用过的唯一重现此“错误”的 COM 服务器是 Acrobat Reader X 的 AroRdIf.dll(以前的版本工作正常)。我不再担心让 Acrobat 的特定 IFilter 工作了,但我非常担心我的代码在我的 IDE 中运行,但不在它之外。另外,Windows SDK FILTDUMP 工具加载此 COM 服务器没有问题,所以我知道这是可能的,我只是不知道如何

最佳答案

所以我花了一些时间对此进行了测试,并且能够完全按照您的描述重现该问题。我重新创建了您的确切控制台应用程序,我看到了相同的行为,但我认为我至少可以添加一些新信息。

起初我和你的想法一样,这是 visual studio 让它工作的东西,但事实并非如此。如果将其构建到控制台可执行文件中,然后从资源管理器启动它,则无需 visual studio 参与即可正常工作。我还添加了 Debugger.Launch() 到开头,这样我就可以在从命令提示符运行时附加到它,即使 VS 完全附加和调试,我也会收到错误。我的结果都表明不是 VS 让它工作,它实际上是从破坏它的命令提示符运行它。

我尝试了各种方法来使命令提示符启动和 Windows 资源管理器启动之间的环境相同,但我每次都得到相同的结果;在资源管理器中完美运行,在命令行中死机。

使用反射器进行挖掘,设置通过了所有测试和所有内容。这是对以下内容的实际调用:

RuntimeTypeHandle.CreateInstance(this, publicOnly, noCheck, ref canBeCached, ref ctor, ref bNeedSecurityCheck);

在被炸毁的 RuntimeType 类中,此时没有更多的托管代码可供挖掘。在这一点上,我的猜测是它必须是完全包含在 Adob​​e COM 服务器中的东西,当从命令提示符运行时它会杀死它。

也许更了解 Windows 内部的人可以谈谈从命令行执行与从资源管理器执行之间的区别?

关于c# - Activator.CreateInstance(<guid>) 在 VSIDE 内部工作,但不在外部工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7289620/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com