制作 C++/MFC 应用程序以从其他应用程序中提取 AssemblyInfo?

Posted

技术标签:

【中文标题】制作 C++/MFC 应用程序以从其他应用程序中提取 AssemblyInfo?【英文标题】:Making a C++/MFC application to extract AssemblyInfo from other applications? 【发布时间】:2011-04-19 06:03:01 【问题描述】:

我正在尝试制作一个 C++/MFC 应用程序(所谓的“更新应用程序”),它可以从用 C#/.NET 3.5 编写的其他应用程序中提取 AssemblyVersion 信息。 所以我可以根据我能得到的版本信息来更新我的C#程序。

我很确定这是可能的,但我不知道哪种方式是最好的方式。

我想知道一些可以在网上搜索的技术或关键字。

如果有直接的解释也将不胜感激。

【问题讨论】:

可以用c++ cli还是一定要mfc MFC 对我来说会更好。使用 CLI 更容易吗? 【参考方案1】:

以下是我们在原生 C++ 应用程序中执行类似操作的大致方法。

使用/clr 编译。您可以在项目范围内或仅在选定的 C++ 文件上执行此操作,但据我所知,有选择地执行此操作很复杂,因此我们只是在项目范围内执行此操作。在适当的地方也可以#include <vcclr.h>

您需要了解应用程序域。这里的主要内容是,一旦将程序集加载到域中,就无法卸载程序集,除非卸载整个域。由于您想加载一个程序集,查询其版本,然后放开它,您可能需要创建一个临时域并加载到其中。

在我们的系统中,我们有一个名为 ModelLoader 的托管 C++ 类,用于加载对象模型、查询其版本信息并丢弃它们 - 就像您想要做的那样。此类是托管/非托管封送处理中的关键元素。

ModelLoader 中的代码必须在临时域中执行,因为我们希望它在那里加载目标程序集,然后卸载域但是,主应用程序已经在主域中运行,因此它需要能够将方法调用编组到临时域中的 ModelLoader。所以 ModelLoader 继承了 System::MarshalByRefObject,它允许 .NET 运行时完成所有的封送处理。

所以基本步骤是这样的:

    加载包含 ModelLoader 代码的程序集。在我们的系统中,它内置在我们的主要非托管 .EXE 中,因此我们只需使用 Reflection::Assembly::GetExecutingAssembly() 来获取它的句柄。如果您的 ModelLoader 等效项位于单独的程序集中,那么您将不得不以某种方式加载它。但由于您可能不需要卸载此程序集,您可以将其加载到主域中。

    创建一个临时域。

    在临时域中创建 ModelLoader 类的实例(显然它在您的系统中会有不同的名称)。

    将该新实例的句柄封送回您的主域。

    使用主域中的封送句柄在临时域中执行代码。

    卸载临时域。

所以,在代码中:

AppDomain ^domain = AppDomain::CreateDomain(L"temp domain");
Assembly ^assembly = Assembly::GetExecutingAssembly();
ObjectHandle ^handle = domain->CreateInstanceFrom(
                         assembly->Location,L"ModeLoader");
Object ^o = handle->Unwrap();
ModelLoader ^loader = dynamic_cast<ModelLoader^>(o);
loader->GetAssemblyVersion(...);
AppDomain::Unload(domain);

为了省去一些麻烦,所涉及的命名空间是:

System::AppDomain
System::Reflection::Assembly
System::Runtime::Remoting::ObjectHandle
System::Object

在您的 ModelLoader 中,您需要加载目标程序集并查询其版本信息。与所有其他东西相比,这很简单:

void ModelLoader::GetAssemblyVersion(const wchar_t *filename, AssemblyName ^name)

    Assembly ^assembly = Assembly::Load(gcnew String(filename));
    name = assembly->GetName();

(这个函数是我刚刚做的,可能不太对。)

另一件需要注意的是装配分辨率。这就是程序集加载器将程序集名称解析为 DLL 文件的方式。这本身就是一个相当大的领域,所以我现在不会再谈论它了。 (而且无论如何我都不是专家。)要开始,只需确保您要加载的所有程序集都在您的主应用程序目录中,我认为您或多或少会好起来的。然后,当您有基本的加载工作时,您可以担心更复杂的分辨率。

【讨论】:

以上是关于制作 C++/MFC 应用程序以从其他应用程序中提取 AssemblyInfo?的主要内容,如果未能解决你的问题,请参考以下文章

MFC 向导外观

如何从 mfc 应用程序调用 IE 或任何其他浏览器?

自定义 Avalon 控件以从其他线程性能问题中渲染

如何启动 c++ mfc 应用程序

VS2013生成Release版本MFC程序在其他机器上运行

如何转换 JavaScript 对象以从 C++ 访问其数据?