首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >stdole.dll是做什么的?

stdole.dll是做什么的?
EN

Stack Overflow用户
提问于 2008-10-02 12:34:04
回答 7查看 67.7K关注 0票数 44

我们有一个大型的C# (.net 2.0)应用程序,它使用我们自己的C++ COM组件和一个也可以通过COM访问的第三方指纹扫描器库。我们遇到了一个问题,在生产中,指纹库中的一些事件不会被激发到C#应用程序中,尽管来自我们自己的C++ COM组件的事件被激发并被正常接收。

使用MSINFO32比较工作系统和故障系统上加载的模块,我们确定这是因为STDOLE.DLL不在GAC中,因此没有加载到故障进程中。

将此文件拖入GAC会导致事件从指纹COM库中很好地返回。

那么stdole.dll做了什么呢?它的大小是16k,所以它不可能很大...它是不是某种到另一个库的链接,比如STDOLE32?为什么它的缺席会导致如此奇怪的行为呢?

我们如何分发stdole.dll?这是一个XCOPY部署应用程序,我们不使用GAC。我们是否应该将其打包为资源,并使用System.EnterpriseServices.Internal.Publish.GacInstall来确保它在GAC中?

EN

回答 7

Stack Overflow用户

发布于 2008-10-02 12:51:48

看起来stdole.dll是主要的互操作程序集。请参阅Office 2003 Primary Interop Assemblies on MSDN.

票数 23
EN

Stack Overflow用户

发布于 2016-09-22 01:55:39

这里也讨论了这个问题:Why is Visual Studio 2015 adding stdole.dll and Microsoft.AnalysisServices.AdomdClient.dll to my project?

在这种情况下,将旧项目升级到VS 2015是导致stdole.dll开始包含在该项目中的原因。

如果库引用在属性中有“嵌入互操作类型”的选项,这是首选的,之后可能就不需要stdole.dll了。只需在引用的属性中设置Embed Interop Types=true即可。

允许这样做的库包括MS Office库,如Office、Excel、Core。Crystal Reports就是这样的一个例子。

Hans Passant 强烈建议在此处设置 Embed Interop Types=falseWhat's the difference setting Embed Interop Types true and false in Visual Studio?

票数 4
EN

Stack Overflow用户

发布于 2021-06-29 01:35:17

我不认为其他任何答案实际上回答了“stdole.dll做什么”的大部分问题。这是我的理解。

摘要:

此DLL位于从托管应用程序最终指向非托管操作系统DLL的引用链的顶端,如下所示:

代码语言:javascript
复制
    .NET app -->
        stdole.dll -->
            stdole2.tlb -->
                oleaut32.dll

这条链中的链接定义得很好,但却晦涩难懂。这个答案的其余部分都走了.

详细说明:

stdole.dll本身就是一个互操作DLL。这意味着它是一个.NET程序集,其目的实际上是围绕具有COM接口的特定非托管类进行act as a wrapper。如果您使用ILSpy或dotPeek之类的工具查看stdole.dll内部,就会看到其中的内容。下面是StdPicture接口的example

代码语言:javascript
复制
using System.Runtime.InteropServices;

namespace stdole
{
  [CoClass(typeof (StdPictureClass))]
  [Guid("7BF80981-BF32-101A-8BBB-00AA00300CAB")]
  [ComImport]
  public interface StdPicture : Picture
  {
  }
}

所有这些都是一个带有属性的接口,这些属性编码了真正应该使用的COM类的详细信息。这样的DLL通常是使用tlbimp.exe或Visual Studio之类的工具自动创建的,当您将非托管COM DLL作为引用直接添加到项目中时,Visual Studio将为您执行此操作。

我们可以再深入一点。上面示例7BF80981-BF32-101A-8BBB-00AA00300CAB中的Guid通常会在Windows注册表中找到,这是运行时在托管代码中实际使用stole.StdPicture时要查看的地方。

如果您使用RegEdit搜索该GUID,您将发现:

代码语言:javascript
复制
Computer\HKEY_CLASSES_ROOT\Interface\{7BF80981-BF32-101A-8BBB-00AA00300CAB}\TypeLib

它的值为00020430-0000-0000-C000-000000000046

搜索该值,您将发现:

代码语言:javascript
复制
Computer\HKEY_CLASSES_ROOT\TypeLib\{00020430-0000-0000-C000-000000000046}

(同一DLL中的大多数其他GUID可能具有类似的条目)。

这个键有很多有趣的细节,实际上是底层实现的几个版本的细节。例如,在子项2.0\0\win32下,默认值为:

代码语言:javascript
复制
C:\WINDOWS\SysWow64\stdole2.tlb

对于版本2的32位变体,这离StdPicture的实际实现又近了一步。

TLB文件只是DLL的一个COM“头”。它本身没有可执行代码。在OLEViewDotNet或原始OleView之类的工具中打开stdole2.tlb,您可以读取类型库本身的IDL。在本例中,第一部分包含以下内容:

代码语言:javascript
复制
// typelib filename: stdole2.tlb

[
  uuid(00020430-0000-0000-C000-000000000046),
  version(2.0),
  helpstring("OLE Automation")
]
library stdole
{
    ...
}

请注意,uuid的值与我们从上面的Regedit中获得的值相同。向下滚动,最终我们会看到StdPicture条目,与上面的示例相同:

代码语言:javascript
复制
[
  uuid(0BE35204-8F91-11CE-9DE3-00AA004BB851)
]
coclass StdPicture {
    ...
};

同样,这里没有真正的代码,只有一个类定义。回到RegEdit,我们可以找到uuid

代码语言:javascript
复制
Computer\HKEY_CLASSES_ROOT\CLSID\{0BE35204-8F91-11CE-9DE3-00AA004BB851}\InprocServer32

其值为C:\Windows\System32\oleaut32.dll。现在我们知道这个DLL为32位stdole库的版本2实现了StdPicture coclass。

(虽然我认为这个文件应该在SysWow64中...?)

如果您要沿着这个链条寻找其他接口,您可能会在同一个DLL或另一个DLL中结束。

请注意,对于某些语言(如VB6),TLB通常直接嵌入到实现动态链接库中。但这不是COM所必需的,显然也不是微软在这种情况下所做的。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/162028

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档