Activator.CreateInstance(< guid>)在VSIDE内部工作,但不在外部工作 [英] Activator.CreateInstance(<guid>) works inside VSIDE but not externally

查看:119
本文介绍了Activator.CreateInstance(< guid>)在VSIDE内部工作,但不在外部工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是我正在使用的整个程序用于测试:

 使用系统; 

命名空间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是{0},obj);
}
}
}

我可以为此工作到目前为止,只要我在VS2010中运行,我都尝试过的每个COM CLSID。无论是否连接调试器,以及是否附加托管过程,我都从 CreateInstance System .__ ComObject >。



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

 未处理的异常:System.Runtime.InteropServices.COMException:由于IClassFactory无法创建具有CLSID {E8978DA6-047F-4E3D-9C78-CDBE46041603}的COM组件实例,因此失败错误以下:80004005. System.RuntimeTypeHandle.CreateInstance(RuntimeType类型,布尔publicOnly,布尔noCheck,布尔& canBeCached,RuntimeMethodHandleInternal& ctor,布尔&bNeedSecurityCheck)中的
,位于System.RuntimeType.CreateInstanceDefaultCtor处的
,布尔skipCheckThis,布尔fillCache)(布尔publicOnly,布尔skipVisibilityChecks,布尔skipCheckThis,布尔fillCache)$ System.Activator.CreateInstance上的b $ b(类型,布尔型非公共)$ Com $ .com.Program.Main(String [] args)中的



这仅在特定的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类中,此时没有更多的托管代码可挖掘。在这一点上,我的猜测是它必须完全包含在Adobe COM Server中,并在从命令提示符运行时将其杀死。



也许有人更了解Windows的精髓,可以说说从命令行执行与浏览器执行之间的区别?


I have a bunch of COM objects which all implement the same interface, and need to create one of them as chosen at runtime from a list of options. Since I know the CLSID for each of the implementing COM servers, this should be easy. However, for a certain subset of COM libraries, I can only make this work if I'm running inside of the VS2010 IDE.

Here is the entire program I'm using to test with:

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);
        }
    }
}

I can make this work for every COM CLSID I've tried so far, as long as I run through VS2010. With or without the debugger attached, and with or without the hosting process attached, I get a System.__ComObject back from CreateInstance.

When I compile and run this code from a console window, for certain CLSID values, I instead get:

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 

This only happens with particular CLSIDs -- for example, "{c1243ca0-bf96-11cd-b579-08002b30bfeb}" (the built-in text IFilter) works, but "{E8978DA6-047F-4E3D-9C78-CDBE46041603}" (Acrobat Reader X's IFilter) doesn't. What I can't figure out is how being run via the IDE makes any different on wether a COM Interop call will succeed. Any ideas?

EDIT:

I'm not running VS2010 as an Administrator, but I have tried running the output binary through an elevated Powershell console and it still doesn't work.

EDIT 2:

Thus far the only COM server I've used that reproduces this "bug" is Acrobat Reader X's AroRdIf.dll (prior versions work fine). I'm not worried about getting Acrobat's specific IFilter working anymore, but I am very concerned that I have code that runs in my IDE but not outside of it. And, as an aside, the Windows SDK FILTDUMP tool has no problem loading this COM server, so I know it's possible, I just don't know how.

解决方案

So I spent some time testing this out, and I was able to reproduce the issue exactly as you describe. I recreated your exact console app and I see the same behavior, but I think I can at least add some new information.

At first I thought the same as you, that it was something with visual studio making it work, but that's not actually the case. If you build this into a console executable, and then launch it from explorer, it works fine with no visual studio involvement. Also I added Debugger.Launch() to the beginning so I could attach to it when run from the command prompt, and I get the error even with VS fully attached and debugging. My results all indicate that it's not VS that's making it work, it's actually running it from the command prompt that is breaking it.

I tried all kinds of stuff to make the environment the same between command prompt launching and windows explorer launching, but I get the same thing every time; works perfect from explorer and dies from command line.

Digging in with reflector, the setup is passing all of its tests and everything. It's the actual call to:

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

In the RuntimeType class which is bombing out, and there's no more managed code to dig into at that point. At this point my guess is that it has to be something entirely contained in the Adobe COM Server that is killing it off when run from the command prompt.

Maybe someone who knows more about the guts of windows can speak to the differences between executing from the command line vs. explorer?

这篇关于Activator.CreateInstance(< guid>)在VSIDE内部工作,但不在外部工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆