stdole.dll 有什么作用?

发布于 2024-07-06 17:47:25 字数 538 浏览 8 评论 0 原文

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

使用 MSINFO32 将工作系统上加载的模块与故障系统上加载的模块进行比较,我们确定这是由于 STDOLE.DLL 不在 GAC 中,因此未加载到故障进程中造成的。

将此文件拖到 GAC 中会导致事件从指纹 COM 库正常返回。

那么stdole.dll 是做什么的呢? 它的大小为 16k,所以不会太大...它是否是到另一个库(如 STDOLE32)的某种链接? 为什么它的缺失会导致如此奇怪的行为?

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

We have a large C# (.net 2.0) app which uses our own C++ COM component and a 3rd party fingerprint scanner library also accessed via COM. We ran into an issue where in production some events from the fingerprint library do not get fired into the C# app, although events from our own C++ COM component fired and were received just fine.

Using MSINFO32 to compare the loaded modules on a working system to those on a failing system we determined that this was caused by STDOLE.DLL not being in the GAC and hence not loaded into the faulty process.

Dragging this file into the GAC caused events to come back fine from the fingerprint COM library.

So what does stdole.dll do? It's 16k in size so it can't be much... is it some sort of link to another library like STDOLE32? How come its absence causes such odd behavior?

How do we distribute stdole.dll? This is an XCOPY deploy app and we don't use the GAC. Should we package it as a resource and use the System.EnterpriseServices.Internal.Publish.GacInstall to ensure it's in the GAC?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

撩发小公举 2024-07-13 17:47:26

在我们的项目中,IDispatch 使用了 stdole.dll。 我们将其更改为对象并删除 IDispatch,然后从引用中删除 stdole。

In our project IDispatch couses using stdole.dll. We've change it to object and remove IDispatch, then remove stdole from references.

孤独患者 2024-07-13 17:47:25

看来 stdole.dll 是一个主要互操作程序集。 请参阅 MSDN 上的 Office 2003 主互操作程序集

It seems that stdole.dll is a primary interop assembly. See Office 2003 Primary Interop Assemblies on MSDN.

我是有多爱你 2024-07-13 17:47:25

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

摘要:

该 DLL 位于从托管应用程序最终引导至非托管操作系统 DLL 的引用链的顶部附近,如下所示:

    .NET app -->
        stdole.dll -->
            stdole2.tlb -->
                oleaut32.dll

该链中的链接定义明确但模糊。 这个答案的其余部分沿着链走...


详细解释:

stdole.dll 本身是一个互操作 DLL。 这意味着它是一个 .NET 程序集,其目的本质上是 充当具有 COM 接口的特定非托管类的包装器。 如果您使用 ILSpy 或 dotPeek 等工具查看 stdole.dll 内部,您可以看到那里有什么。 这是 StdPicture 的示例 接口:

using System.Runtime.InteropServices;

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

这一切都是一个接口,其属性对确实应该使用的 COM 类的详细信息进行编码。 像这样的 DLL 通常是使用


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

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

Computer\HKEY_CLASSES_ROOT\Interface\{7BF80981-BF32-101A-8BBB-00AA00300CAB}\TypeLib

其值为 00020430-0000-0000-C000-000000000046

搜索该值,您会发现:(

Computer\HKEY_CLASSES_ROOT\TypeLib\{00020430-0000-0000-C000-000000000046}

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

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

C:\WINDOWS\SysWow64\stdole2.tlb

版本 2 的 32 位变体。这距离 StdPicture 实际实现的位置更近了一步。


TLB 文件只是 DLL 的一种 COM“标头”。 它本身没有可执行代码。 在 OLEViewDotNet 或原始 stdole2.tlb "https://learn.microsoft.com/en-us/windows/win32/com/ole-com-object-viewer" rel="noreferrer">OleView,可以读取typelib本身的IDL 。 在本例中,第一部分具有以下内容:

// typelib filename: stdole2.tlb

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

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

[
  uuid(0BE35204-8F91-11CE-9DE3-00AA004BB851)
]
coclass StdPicture {
    ...
};

这里再次没有真正的代码,只有一个类定义。 回到RegEdit我们可以发现uuid

Computer\HKEY_CLASSES_ROOT\CLSID\{0BE35204-8F91-11CE-9DE3-00AA004BB851}\InprocServer32

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

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

如果您要遵循此链来获取其他接口,您可能最终会得到相同的 DLL 或另一个。

请注意,对于某些语言(如 VB6),TLB 通常直接嵌入到实现 DLL 中。 但这对于 COM 来说不是必需的,而且显然 Microsoft 在本例中也不是这样做的。

I don't think any of the other answers actually answered most of the question "what does stdole.dll do". Here's my understanding.

Summary:

This DLL is near the top of a chain of references leading from your managed application ultimately to unmanaged operating system DLLs which looks like this:

    .NET app -->
        stdole.dll -->
            stdole2.tlb -->
                oleaut32.dll

The links in this chain are well defined but obscure. The rest of this answer walks the chain...


Detailed explanation:

stdole.dll itself is an interop DLL. That means that it is a .NET assembly whose purpose is to essentially act as a wrapper around specific unmanaged classes which have COM interfaces. If you look inside stdole.dll with a tool like ILSpy or dotPeek you can see what's there. Here's an example for the StdPicture interface:

using System.Runtime.InteropServices;

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

All this is is an interface with attributes that encode details of the COM classes that really should be used. DLLs like this are generally created automatically with a tool like tlbimp.exe or Visual Studio will do this for you when you add an unmanaged COM DLL directly to your project as a reference.


We can dig a little deeper. A Guid in the example above 7BF80981-BF32-101A-8BBB-00AA00300CAB is generally going to be found in the Windows registry, that's where the runtime is going to look when stole.StdPicture is actually used from managed code.

If you search for that GUID using RegEdit, you'll find:

Computer\HKEY_CLASSES_ROOT\Interface\{7BF80981-BF32-101A-8BBB-00AA00300CAB}\TypeLib

which has the value 00020430-0000-0000-C000-000000000046.

Searching for that value, you'll find:

Computer\HKEY_CLASSES_ROOT\TypeLib\{00020430-0000-0000-C000-000000000046}

(Most of the other GUIDs from the same DLL would probably have a similar entry).

This key has a lot of interesting details, in fact details for several versions of the underlying implementation. For instance under subkey 2.0\0\win32 the default value is:

C:\WINDOWS\SysWow64\stdole2.tlb

for the 32-bit variant of version 2. That's one step closer to where StdPicture actually is implemented.


A TLB file is just a COM "header" of sorts for a DLL. It doesn't have executable code in itself. Opening stdole2.tlb in a tool like OLEViewDotNet or the original OleView, you can read the IDL of the typelib itself. In this case, the first part has the following:

// typelib filename: stdole2.tlb

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

Note the uuid has the same value we got from Regedit above. Scrolling down eventually we come to the StdPicture entry, the same example as above:

[
  uuid(0BE35204-8F91-11CE-9DE3-00AA004BB851)
]
coclass StdPicture {
    ...
};

Yet again there's no real code here, just a class definition. Back to RegEdit we can find that uuid:

Computer\HKEY_CLASSES_ROOT\CLSID\{0BE35204-8F91-11CE-9DE3-00AA004BB851}\InprocServer32

whose value is C:\Windows\System32\oleaut32.dll. Now we know that this DLL implements the StdPicture coclass for version 2 of the 32-bit stdole library.

(Though I would have thought this file should be in SysWow64...?)

If you were to follow this chain for some other interface, you might end up at the same DLL or another.

Note that for some languages (like VB6) it is typical for the TLB to be embedded right in the implementing DLL directly. But this is not required for COM and obviously not how Microsoft did it in this case.

っ〆星空下的拥抱 2024-07-13 17:47:25

此处也讨论了此问题:为什么 Visual Studio 2015 将 stdole.dll 和 Microsoft.AnalysisServices.AdomdClient.dll 添加到我的项目中?< /a>

在本例中,将旧项目升级到 VS 2015 是导致 stdole.dll 开始包含在项目中的原因。

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

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

Hans Passant 强烈反对设置Embed Interop Types=false 此处:在 Visual Studio 中设置嵌入互操作类型 true 和 false 有什么区别?

This issue is also discussed over here: Why is Visual Studio 2015 adding stdole.dll and Microsoft.AnalysisServices.AdomdClient.dll to my project?

Upgrading an older project to VS 2015 is what caused stdole.dll to start getting included in the project in this case.

If the library referencing has the option to "Embed Interop Types" in the properies, this is preferred and the stdole.dll may not be needed after that. Just set Embed Interop Types=true in the properties of the reference.

Libraries that allow this include the MS Office libraries such as Office, Excel, Core. An example of one that does not is Crystal Reports.

Hans Passant strongly discourages setting Embed Interop Types=false here: What's the difference setting Embed Interop Types true and false in Visual Studio?

愁以何悠 2024-07-13 17:47:25

我有同样的问题。 我刚刚从应用程序中删除了引用并重新编译。 运行所有通过的测试。 然后在没有dll的情况下重新部署,一切正常。

我不知道这个项目最初是如何引用的。 这是一个遗留应用程序,所以一定是很久以前的事了。

西蒙

I had the same problem. I just deleted the reference from the application and recompiled. Ran all the tests which passed. Then redeployed without the dll and it all worked.

I dont know how a reference to this got in the project in the first place. It is a legacy app so must have been a long time ago.

Simon

苍暮颜 2024-07-13 17:47:25

就我而言,它是对 Office Word Interop 的旧的未使用引用...但删除它还不够:发布配置文件仍然有复制 stdole.dll 的行!

<File Include="bin/stdole.dll"> ...

删除该行(使用“在文件中查找”找到)并从远程服务器上的 bin 文件夹中删除 stdole.dll 解决了我的问题。

希望这对其他人有帮助。

In my case, it was an old unused reference to Office Word Interop ... but removing that was not sufficient: The publish profile still had line to copy stdole.dll !

<File Include="bin/stdole.dll"> ...

Deleting that line (found using 'Find in Files') and deleting the stdole.dll from the bin folder on the remote server fixed my problem.

Hope this helps someone else.

离旧人 2024-07-13 17:47:25

我还必须为 stdole 添加对我的项目的引用。 尽管我没有任何对它的引用(它是一个简单的图像应用程序),但我们的 2 位用户收到了它丢失的错误。 可能他们只运行 .net 2.0,而这是 3.5 应用程序。 我已经明白为什么了。

我还进入项目属性选项卡进行发布,并选择应用程序文件,然后包含要部署的 stdole。 希望这会起作用。

I had to also add a reference to my project for stdole. Even though I don't have any references to it (it's a simple image app), 2 of our users were getting errors that it was missing. It could be that they were only running .net 2.0 when this is a 3.5 app. I have figured out why.

I also went in to publish on the project properties tab, and selected Application Files, then included the stdole to be deployed. Hopefully that will work.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文