问题标签 [registration-free-com]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
456 浏览

c++ - Reg-Free 进程外 COM 服务器事件

我们正在尝试将进程内 COM 对象更改为进程外 COM 对象。新进程只是将 Dispatch 传递给以前使用的 COM 对象,因此我们可以选择返回到进程内对象。这工作正常,但我们遇到有关事件的问题。进程外服务器拦截先前使用的 COM 对象的事件,并将这些事件传递给自己的事件接口,该接口也在工作。但问题是,当进程外服务器未在 Windows 注册表中注册时,客户端无法使用 DispEventAdvise 连接到此事件接口。

服务器 IDL 如下所示:

我们将 control_i.c、control_p.c 和 dlldata.c 添加到客户端和服务器。两者都执行以下步骤来注册代理/存根。

这适用于使用 CoCreateInstance 创建的控件,但不适用于事件。DispEventAdvise 不断返回 CONNECT_E_CANNOTCONNECT 导致接收器上 DIID__IControlEvents 的 QueryInterface 返回 E_NOINTERFACE。

我们真的需要在不在注册表中注册控件的情况下让它工作。我们还尝试使用清单文件和单独的代理/存根 DLL 注册它,但没有成功。


0 投票
2 回答
2212 浏览

visual-studio - Visual Studio 导致在调试时忽略嵌入式程序集清单

我的 .NET 客户端应用程序依赖于另一个程序集。这种依赖关系在一个app.manifest文件中声明:

应用程序清单

然后将项目配置为使用我们的app.manifest文件。您在Project -> Application -> Resourcesapp.manifest下指定使用自定义:

在此处输入图像描述

这一切都有效

我必须确保将我的其他程序集放在同一个文件夹中^1。例如:

Contoso.Grobber.manifest

所以我的文件夹中有:

  • 示例应用程序.exe
  • Contoso.Grobber.Manifest
  • Grobberify.dll

一切正常。我的应用程序运行,一切正常。

我可以证明我的嵌入式清单受到尊重,因为如果我将嵌入式清单更改为需要名为Contoso.Grobber asdfasfaraasdf的东西:

如果现在运行我的应用程序,Fusion 加载器将意识到没有名为asdfasfaraasdf的程序集,并在加载时抛出错误:

在此处输入图像描述

应用程序无法启动,因为它的并排配置不正确。请查看应用程序事件日志或使用命令行 sxstrace.exe 工具了解更多详细信息。

如果我将我的依赖程序集放回正确的asdfasfaraasdf --> Contso.Grobber,那么一切正常。

调试时除外

没有特别的原因,如果我在调试器中,那么融合加载程序看不到我的程序集清单,它是依赖程序集。

我可以通过在我的程序集清单中声明我依赖于一个不存在的程序集来证明这一点(例如 name="asdfasdfasf")

该应用程序应该无法启动 -但它会启动!不管我做什么:

  • 使用假程序集名称
  • 删除我的依赖程序集的清单
  • 删除.dll我的依赖程序集

该应用程序不会启动失败。这意味着 Visual Studio 正在运行的我的可执行文件的任何版本:它不包含我嵌入app.manifest的 .

这是一个问题,因为它坏了

您可能认为让应用程序运行是一件好事——我不希望它失败。这是错误的,原因有两个:

  • 如果所需的程序集不存在,我希望它无法启动
  • 依赖程序集包含所需的融合信息

我正在加载的程序集是一个 COM dll。我的.manifest文件包含急需的 COMclsid和文件名信息。当 Visual Studio 不支持我的应用程序清单时,Fusion 加载程序将看不到我的免注册 COM 对象:

如果没有此程序集 comClass 信息,我的 .NET 应用程序在调试时无法创建 COM 对象:

在此处输入图像描述

仅在调试时发生

带有 32 位应用程序的 Windows 7 64 位上的 Visual Studio Community 2013 失败,并且登录用户未配置壁纸仅在调试应用程序时发生。如果我直接运行SampleApplication.exe,则嵌入程序集清单将受到尊重。

这可能与 Visual Studio 不调试的事实有关

示例应用程序.exe

Visual Studio 实际上调试了一个名为:

SampleApplication.vshost.exe

或不。我知道什么?

我如何使它工作?

我知道没有解决办法。地球上对免注册 COM有任何经验的人数仅限于:

可以肯定地说,没有人真正阅读过上面的“研究工作”的整个部分。我也很想知道哪些用户在那里抓住了复活节彩蛋,以及谁会抱怨过多的研究工作。

实际上,我知道没有解决方案。虽然我可以记录这是一个问题的事实,但我并没有暗示任何人都可以解决它。这使得整个 45 分钟的问题成为我发泄无法解决的问题的一种方式。

奖金阅读

0 投票
1 回答
646 浏览

c# - DLL位于单独文件夹时免注册COM

这个问题之前已经在 SO 上被问过,例如这里这里。这种情况是,人们想在他们的应用程序中使用 COM 组件,而不必在机器上注册 COM 组件。这是通过添加两个清单文件来完成的,一个到客户端,一个到服务器,操作系统的并行功能负责其余部分。现在,当所有 Dll 都在同一个文件夹中时,这可以正常工作。

在我的特定场景中,我试图让旧版 .net 2.0 dll 访问 4.0 dll。我们不想更改 2.0 dll,通过上述方法,我能够做到这一点。但是,如果 4.0 dll 位于可执行文件(2.0 dll)的子文件夹中。并行执行开始时找不到 4.0 dll。我目前正在调用 win32 API 并创建一个新的 ActivationContext 传递清单文件。我使用 ProcMon 并看到 dll 正在可执行目录中查找,而不是在清单中指定的路径中查找。正如上面的链接也证明,.net 似乎只知道清单中的 ClrClass 并忽略了为私有程序集查找提供的 AssemblyLocation ,这是非常不幸的!

无论如何,上述链接中的解决方法是 GAC 和 AssemblyResolve。如果可能的话,我不想通过 GAC,而且 AssemblyResolve 对我不起作用,因为我必须在无法加载 4.0 dll 的 2.0 dll 中订阅它。

是否有任何类型的黑客让应用程序认为它暂时位于其他地方以便找到 dll?

我也知道使用 service(web, windows) 来启用 2.0 应用程序调用 4.0 应用程序。除了上述三种之外,任何其他可能性都会被理解。

0 投票
0 回答
503 浏览

c# - 使用免费的 Microsoft Office DLL 注册?

我正在开发一个需要能够连接到 MS Access 数据库并使用存储在那里的一些数据库对象的 C# 应用程序。

由于后来可能需要对 Access 相关代码进行一些小改动的人主要熟悉 VBA 和 DAO,因此我们决定使用 ACEDAO.dll(通过 Microsoft.Office.Interop.Access.Dao PIA),为了使语法尽可能熟悉。

参考提到的 PIA,我可以轻松地在 Visual Studio 2015 中使用必要的 Access 特定类型,并且应用程序编译得非常好。但是,在开始调试过程时,我很快遇到了异常:

虽然我安装了 Office 2013,但似乎引用的 DLL (ACEDAO.DLL) 未注册。我可以通过简单地从 Microsoft 下载和安装 Access Runtime 来解决这个问题,之后注册相应的 .dll 并且应用程序运行正常。

问题是,安装 Access Runtime 需要管理员权限,这对于客户端 PC 来说不是一个现实的选择。必须运行该应用程序的所有 PC 都安装了与我的开发人员机器相同的 Office 版本,并且 ACEDAO.dll 在程序文件中,但未注册...是否可以在无需注册的情况下使用该库?

引用 Office 安装文件夹中的 ACEDAO.dll 允许我将“隔离”属性设置为 true。虽然这在构建时给了我很多警告(问题隔离 COM 参考 'Microsoft.Office.Interop.Access.Dao' ...),但它编译并复制了二进制文件夹中的 dll 并创建了一个清单,但它仍然不会在没有注册库的情况下无法工作(来自 mscorlib.dll 的异常 0x8007013D,没有可用的消息文本)...

关于是否以及如何在没有在目标机器上注册的情况下使用 ACEDAO 库的任何想法?

0 投票
0 回答
1254 浏览

c# - 在没有代码库/GAC 的情况下将免注册 COM 互操作与 C# .NET DLL 一起使用?

我有一个通过 COM Interop 公开的 C# .NET DLL,为此我生成了一个清单文件。DLL 正在通过 Excel VBAProject 使用CreateActCtxCreateObject创建我的对象。

一切正常,但是……我需要致电regasm MyProject.dll /codebase或向 GAC 注册。否则我得到ActiveX component can't create objecterror in dll错误。

是否可以使用 .NET DLL 而无需注册 DLL?我以前可以使用基于 VB6 的 DLL 和清单文件来执行此操作。

0 投票
2 回答
612 浏览

c# - .NET Framework (v 4.0) COM 注册免费从 Win32 C++ 应用程序调用

我需要使用 C# 在 .Net Framework 中创建一个免注册的 COM 对象。

我遵循了MSDN 演练。我必须努力解决它,或者它对我来说不够清楚,或者它不正确,但这是一篇旧帖子,我在 Windows 10 上使用 Visual Studio 2015,所以可能有些地方发生了变化。

以下是我为使其工作而采取的步骤:

  1. 编译COM C# dll SideBySide.dll(Target Framework 2.0),当然我没有regasm注册过。

  2. 我不使用教程中描述的方法,它似乎对我不起作用。我创建SideBySide.Manifestmt.exe,这里是命令:

    mt -outputresource:"<path SidebySide.dll>" -manifest "<SideBySide.manifest>"

  3. 我手动修改了生成的清单以删除所有无用的标签,并添加强制性标签。这是修改后的清单:

  4. 我已经SideBySide.dll用这个命令添加了清单:

    mt -outputresource:"<Path SidebySide.dll>" -manifest "SideBySide.manifest"

  5. 我已经从SideBySide.dll using tlbexp` 导出了 TLB。

  6. 我在 C++ 客户端的配置中设置了No。Properties -> Manifest tool -> Embed Manifest

  7. 我已经编译client.exe,然后我对client.exe.manifest文件应用了更改。这是修改后的清单:

一切运行良好,似乎我可以从本机 C++ 应用程序使用 .Net Framework COM 接口。

但是,当我尝试SideBySide.dll使用 .Net Framework 4.0 或更高版本进行编译时,会出现问题CreateInstance

发生此错误:

0x8013101b :此程序集由比当前加载的运行时更新的运行时构建,无法加载。

当然,我已经尝试执行上面列出的所有步骤,我还尝试在 DLL 的清单中指定运行时版本,但它没有用。

我也读过这篇文章。问题是一样的,但我认为该解决方案不适合我,因为我需要从本机客户端调用 C# COM 对象。

是否有一些解决方法可以应用,还是我需要另一种方法来解决我的问题?

0 投票
2 回答
395 浏览

com - 通过准隔离COM消费EXE服务器

我已经能够使用清单,尤其是 MSBuild 任务 GenerateApplicationManifest,以便我们的主应用程序使用独立 COM。我可以创建在我需要的 DLL 中实现的所有 COM 对象,而无需在我的客户端计算机上注册 DLL。但是,我很贪心...

我们的应用程序套件通常还有一些通过 COM 调用的单独应用程序。对于这些,据说不能对EXE隔离COM做EXE。严格来说,这是真的,但我已经完成了 90% 的工作,并且在其他论坛上,我看到其他人提供线索以完成剩下的工作。

对于我的 EXE 服务器,我在清单中有一个带有 EXE 服务器名称的条目和一个子条目,这样当 ATL 服务器调用LoadRegTypeLib()时,调用就会成功。这样可行。

当然,棘手的部分是您不能在客户端应用程序清单中放置 EXE 服务器的条目并期望CoCreateInstance()成功(通过启动服务器 EXE 并执行 COM 所做的所有其他事情。)

我可以伪造很多,因为我知道要启动什么 EXE 服务器。我可以调用CreateProcess(),然后调用WaitForInputidle()客户端应用程序,让我的服务器为客户端应用程序中的 CoCreateInstance() 做好准备。

如果我打电话CoCreateInstance()并询问IDispatch客户端应用程序中的接口,则调用成功,我可以调用Invoke()并且一切正常。

现在到了贪婪的部分......

IDispatch 工作一切都很好,但我希望能够通过我从 IDispatch 派生的双接口进行调用。我想这样做是因为我有很多以这种方式编写的代码,并且语法更简单,并且已经存在异常处理。

但是,当我QueryInterface()在我的接口上调用双接口时IDispatch,我得到一个 E_NOINTERFACE 返回。我在服务器 EXE 中的 ATL 服务器对象中设置了断点,并且可以确认在服务器端,它找到了接口并返回 S_OK。因此,似乎接口无法以某种方式编组回客户端。

所以,问题是,我怎样才能让QueryInterface()我的自定义/双界面成功?我尝试了在客户端清单(和服务器清单)中使用<comInterfaceProxyStub><comInterfaceExternalProxyStub>的各种组合来尝试编组接口,但我仍然E_NOINTERFACE在客户端中看到返回。

几年前,我在另一个论坛上看到了 Hans Passant 的评论,说可能需要一个单独的代理/存根 DLL 来编组接口,但没有太多细节。

甚至有可能在免注册的情况下解决这个问题吗?是否有必要创建代理/存根库?如果是这样,我的客户端应用程序(和/或服务器应用程序和/或代理/存根 DLL)中的清单条目会是什么样子?

0 投票
1 回答
186 浏览

com - 如何处理 regfree 的 COM 事件?

我正在尝试处理从 C# 服务器到 C++ 客户端的 COM 事件。我可以使用服务器 regfree,但我的活动不再有效。

以前,通过注册,事件是通过IDispEventImplATL 在客户端中处理的。

我无法找到任何直接解决此问题的文章,但我确实看到了一个IConnectionPoint本质上不需要注册的建议。

我还看到了一些IDispEventSimpleImpl可能适用于 regfree 的建议。

0 投票
1 回答
684 浏览

typelib - 有没有办法通过遍历.NET 中的 TLB 文件来查看 COM 条目?

我正在将应用程序转换为使用免注册 COM。有一些通常会调用 regsvr32 的第 3 方 COM dll。我测试了我可以通过制作并排清单从这些 3rd 方 dll 创建对象。

我使用 Windows 内置的 OLE/COM 查看器来获取此信息。但是,我想制作一个可以手动为我执行此操作的程序,因为这些 3rd 方库有很多我需要放入清单中的类。

有谁知道以编程方式遍历类型库的方法?

0 投票
0 回答
140 浏览

com - 免注册 COM 不能很好地处理单线程对象。封送期间丢弃的激活上下文

我正在通过 JNI 将基于 COM/CLI 的库集成到基于 Java 的应用程序中(是的,这有点乱)。在大多数情况下它都在工作,但是当谈到激活上下文如何与单线程 COM 对象交互时,我遇到了一些障碍。我的情况可以用下面的代码片段来概括。

库和应用程序的部署迫使我使用免注册 COM。此外,由于主应用程序是用 Java 编写的,因此我无法真正将清单资源附加到 exe 文件或类似文件中。因此,我需要使用 COM 中的激活上下文机制来允许库查找其 COM 类。此外,库本身是单线程的,因此需要 STA 才能运行。但是,我的应用程序将从各种线程调用库。

据我了解,如果要创建的对象是单线程的,那么第一次从 MTA 线程调用 CoCreateInstance 时,COM 将启动一个新的“默认 STA 线程”。然后在默认 STA 中创建实际对象,然后 CoCreateInstance 的返回值将是一个代理对象,它将方法调用来回编组到默认 STA。这一切都很好,这就是我希望它的工作方式。

当我的代码不是第一个导致默认 STA 线程启动的代码时,就会出现我的问题。似乎即使对象创建被封送到默认 STA,当前激活上下文也不是。默认 STA 卡在创建时处于活动状态的激活上下文中。这对我来说意味着如果我不是第一个导致默认 STA 被初始化的人,我对 CoCreateInstance 的调用将失败,因为默认 STA 不知道我的激活上下文。这是一个大型企业应用程序,我不能确定我的代码会第一个调用 CoCreateInstance,即使我可以,这对我来说似乎也是一个脆弱的解决方案。

因此,我需要以下之一:

  1. 一种将激活上下文编组到默认 STA 的方法。

  2. 一种使用正确激活上下文启动新 STA 的方法,我的对象将在其中存在,并且 CoCreateInstance 和方法调用被来回编组到此 STA 而不是默认 STA。

  3. 重构我的集成以确保对有问题的库的所有调用都来自我可以控制的单个 STA,以避免编组步骤。这是我的备用计划,但我觉得必须有更简单的方法。