标签: com

Get-WMIObject \ Get-CimInstance 实际上是做什么的?

我正在开发一个新的 WMI 实例提供程序,但遇到了一些麻烦。我能够使用regsvr32.exe. 该regsvr32应用程序调用我的实现DllRegisterServer并创建以下注册表项和值:

HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}                : (default)      = "WMI Provider"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\InprocServer32 : (default)      = "C:\MyWmiProvider.dll"
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\InprocServer32 : ThreadingModel = Neutral
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\CLSID\{00000001-0000-0000-0000-00000000000F}\Version        : (default)      = 1.0.0
Run Code Online (Sandbox Code Playgroud)

(哪里{00000001-0000-0000-0000-00000000000F}只是一个测试类 ID(CLSID))

我也能够成功地添加在我的定义我的WMI类定义中号anaged Ø bject ˚F使用ORMAT(MOF)文件mofcomp.exe。我可以通过运行以下命令来验证我的定义是否存在于 WMI 存储库中:

Get-CimClass -Namespace "root/MyNamespace" | Where-Object CimClassName -like "MyClass_*"
Run Code Online (Sandbox Code Playgroud)

这是我的 MOF 文件的示例:

#pragma namespace("\\\\.\\root\\MyNamespace")
#pragma autorecover

instance of __Win32Provider as $P
{
    Name = "MyWmiProvider";
    ClsId = "{00000001-0000-0000-0000-00000000000F}";
};

instance of __InstanceProviderRegistration
{
    Provider = …
Run Code Online (Sandbox Code Playgroud)

com powershell wmi visual-c++ get-wmiobject

17
推荐指数
1
解决办法
850
查看次数

如何检查COM组件(EXE/DLL文件)是否已注册(使用.NET)?

如何使用.NET检查COM组件(EXE/DLL文件)是否已注册?

.net c# com

16
推荐指数
2
解决办法
3万
查看次数

创建自己的HRESULT?

我已经有一个项目使用了很多COM和HRESULTS.我想知道是否有可能定义你自己的HRESULT,并且能够将FormatMessage()用于我们自己的HRESULT?

我四处乱窜,无法找到任何东西.有任何想法吗?

编辑

基本上我想定义一组我自己的HRESULT,而不是只返回E_FAIL.或者其他通用的.像E_FAIL一样好.但是,我想说,我想指出,例如地理处理子系统崩溃或文件是无效的光栅图像.该应用程序已经通过它使用com.

c++ com hresult

16
推荐指数
1
解决办法
3969
查看次数

如何在本机.NET类中包装COM对象?

我在.NET(C#)中使用了广泛的现有COM API(可能是Outlook,但它不是).我通过在Visual Studio中添加"COM引用"来完成此操作,因此所有"魔法"都是在幕后完成的(即,我不必手动运行tlbimp).

虽然现在可以从.NET"轻松"使用COM API,但它不是非常友好的.NET.例如,没有泛型,事件很奇怪,奇怪,如IPicture等.所以,我想创建一个使用现有COM API实现的本机.NET API.

一个简单的第一次传球可能是

namespace Company.Product {
   class ComObject {
       public readonly global::Product.ComObject Handle; // the "native" COM object
       public ComObject(global::Product.ComObject handle) {
          if (handle == null) throw new ArgumentNullException("handle");
          Handle = handle;
       }

       // EDIT: suggestions from nobugz
       public override int GetHashCode() {
          return Handle.GetHashCode();
       }
       public override bool Equals(object obj) {
          return Handle.Equals(obj);
       }
   }
}
Run Code Online (Sandbox Code Playgroud)

这种方法的一个直接问题是,您可以轻松地为同一个底层"本机COM"对象结束多个ComObject实例.例如,在进行枚举时:

IEnumerable<Company.Product.Item> Items {
   get {
      foreach (global::Item item in Handle.Items)
         yield …
Run Code Online (Sandbox Code Playgroud)

.net c# com interop com-interop

16
推荐指数
2
解决办法
3125
查看次数

Visual Studio 2010 64位COM互操作问题

我正在尝试将VC6 COM DLL添加到我们的VS2010RC C#解决方案中.使用VC6工具编译DLL以创建x86版本,并使用VC7跨平台工具编译以生成VC7 DLL.

只要消耗C#项目的平台设置为x86,组件的x86版本就可以正常工作.DLL的x64或x86版本是否实际注册无关紧要.它适用于两者.如果平台设置为"任何CPU",我会收到一个BadImageFormatException负载Interop.<name>.dll.

至于x64版本,我甚至无法构建项目.我收到tlbimp错误:

TlbImp:错误TI0000:必须指定与输入类型库兼容的单个有效机器类型.

有没有人见过这个问题?

编辑:

我已经做了很多深入研究这个问题,并认为这可能是一个Visual Studio错误.我有一个干净的解决方案.我引入了我的COM程序集,选择了与语言无关的"任何CPU".生成的Interop DLL的过程体系结构是x86而不是MSIL.

可能必须手工制作Interop才能使其工作.

如果有人有其他建议,请告诉我.

com interop visual-c++-6 visual-studio-2010

16
推荐指数
1
解决办法
2万
查看次数

通过COM包装器从托管代码调用COM可见托管组件

我有一个第三方组件,让我们说FIPreviewHandler来处理预览,它实现了IPreviewHandler.FIPreviewHandler实现为托管组件,并通过互操作使用IPreviewHandler接口和相关接口.FIPreviewHandler使用regasm.exe作为COM注册.

我有一个客户端应用程序也管理.我想在我的应用程序中创建一个FIPreviewHandler实例作为COM组件.

我有一个interop程序集,定义IPreviewHandler和相关的接口.

当我使用Activator.CreateInstance()创建一个FIPreviewHandler实例时,GetTypeByCLSID()返回的类型使用FIPreviewHandler的正确CLSID,它返回一个托管实例,因为它有实际的程序集可用,并跳过COM .当我尝试QI /将此实例转换为任何接口,例如IPreviewHandler时,它返回null,因为它作为托管对象加载,尽管FIPreviewHandler实现的IPreviewHandler接口与我在interop中的接口相同,但它在一个不同的命名空间/程序集中,因此为null.如果要返回一个COM实例/ RCW(System .__ ComObject),它将不会占用命名空间,并且可以正常转换,并返回一个有效的实例.

FIPreviewHandler是一个32位组件,在64位Win7机器上,如果我将我的客户端应用程序编译为"任何CPU",Activator.CreateInstance()将返回一个COM实例/ RCW(System .__ ComObject),因为它会查找64位实现FIPreviewHandler,因此返回一个代理.在这种情况下,我的应用程序工作正常.但是当我为x86编译它时,它获得32位实现,并返回实际托管类的托管实例,而不是COM实例,因此失败.

我不能使用FIPreviewHandler程序集中定义的接口,因为我必须为IPreviewHandler编写通用客户端,我的应用程序将与任何实现IPreviewHandler的组件一起使用,这对于基于C++的客户端访问FIPreviewHandler作为COM对象非常有用,但是失败了对于托管客户端.

我希望我有意义,我真的很感激任何帮助.

c# com proxy interop marshalling

16
推荐指数
1
解决办法
2289
查看次数

WMPLib:player.mediaCollection.getAll().count始终为0

我正在尝试编写从用户的Windows Media Player库中读取每个项目的代码.此代码适用于大多数用户,但对于某些用户,getAll()当他们的Windows Media Player库中明显包含数百或数千个项目时,将返回空列表.

var player = new WindowsMediaPlayer();
var collection = player.mediaCollection;
var list = collection.getAll();
int total = list.count;
Run Code Online (Sandbox Code Playgroud)

WMPLib通过添加对wmp.dll的COM引用来引用命名空间.我的应用程序随附Interop.WMPLib.dll.如何配置某些用户的计算机,使其在其库中运行带有许多歌曲的Windows Media Player,但WMPLib无法正常运行?此外,在所有情况下可靠地读取用户的Windows Media Player库有哪些变通方法?

.net c# com wmp windows-media-player

16
推荐指数
1
解决办法
2623
查看次数

正确的释放COM对象的方法?

有时当我结束应用程序并尝试释放一些COM对象时,我会在调试器中收到警告:

RaceOnRCWCleanUp 被发现了

如果我编写一个使用COM对象的类,我是否需要实现IDisposable并调用Marshal.FinalReleaseComObject它们IDisposable.Dispose才能正确释放它们?

如果Dispose没有手动调用,我还需要在终结器中释放它们还是GC会自动释放它们?现在我打电话Dispose(false)给终结者,但我想知道这是否正确.

我使用的COM对象也有一个类侦听的事件处理程序.显然,事件是在另一个线程上引发的,所以如果在处理类时触发它,如何正确处理呢?

.net c# com

16
推荐指数
3
解决办法
2万
查看次数

COM在非Windows世界?

希望这个问题不会太模糊.通过COM规范和Don Box的Essential COM书阅读,有很多关于"COM解决的问题"的讨论 - 而且它们听起来都很重要,相关且最新.

那么COM地址在其他系统(linux,unix,OSX,android)上处理的问题怎么样呢?我想的是:

  • 跨编译器和编译器版本的二进制兼容性
  • 二进制组件重用
  • 编译一个应用程序,使其具有运行时依赖性,而不是加载时间依赖性(以便即使缺少依赖项也会运行)
  • 从库以外的语言访问库功能
  • 合理的低开销远程过程调用加载到不同进程的地址空间中的组件
  • 等等(我确定这个清单还在继续)

我基本上只是想了解为什么例如Linux上的CORBA不是像COM这样的东西在Windows上(如果这是有道理的).Linux上的软件开发是否可以订阅与COM提出的基于组件的模型不同的理念?

最后,COM是C/C++的东西吗?有几次我遇到过人们的评论,他们说COM被.NET淘汰了,但没有真正解释他们的意思.

c++ windows com binary-compatibility

16
推荐指数
2
解决办法
903
查看次数

清单中需要哪些标签才能免费注册COM?

TL; DR是否所有生成的注册表项都regsvr32需要出现在SxS reg-free-COM清单中,反之亦然?


我正在尝试获得免注册的COM用于第三方组件.

关于主题,我发现有提到的几个要素,即可以放入一个清单:

从文档中,我们可以将以下标记添加到清单中以描述COM组件:

  • assemblyIdentity- 据我所知,这真的只是描述了"抽象集会 "
  • comClass - 描述COM类(IID接口).看来,这总是需要的.
  • typelib - 什么时候?
  • comInterfaceExternalProxyStub - 什么时候?
  • comInterfaceProxyStub - 什么时候?

从其他文档HKEY_LOCAL_MACHINE\SOFTWARE\Classes我们可以看到COM注册表项有几个类别:

使用regsvr42来提取我试图注册的dll会产生一个只包含comClass条目,没有typelib或ProxyStub条目的清单.(我交叉检查写的密钥,有问题的DLL pdm.dll,MS的Process Debug Manager只写那些密钥,也就是说,注册表中没有明显的类型库或代理存根信息.)

如果注册表只包含与此相关的信息,comClass则表示此信息在SxS清单中是足够的,或者清单中是否需要其他信息?


另外,我注意到注册表包含a VersionIndependentProgId和a ProgId,其末尾附加了版本号.清单只有一个ProgId条目,文档说明:

progid:与COM组件关联的与版本相关的编程标识符.ProgID的格式是 <vendor>.<component>.<version>.

但文档也说明了这一点

comClass元素可以有<progid>...</progid>子元素,其中列出的版本有关的ProgID.

并且他们说 progid属性应该是版本独立的属性.

那么,放在这里的是什么?当客户端没有请求特定版本时,它是否重要?

c++ com manifest side-by-side regfreecom

15
推荐指数
1
解决办法
2279
查看次数