Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从C#/.NET中的非托管执行应用程序检索产品信息_C#_.net_Com_Unmanaged - Fatal编程技术网

从C#/.NET中的非托管执行应用程序检索产品信息

从C#/.NET中的非托管执行应用程序检索产品信息,c#,.net,com,unmanaged,C#,.net,Com,Unmanaged,在C#中,可以使用反射检索与程序集相关的信息,如产品名称、版本等: string productName = Assembly.GetCallingAssembly().GetName().Name; string versionString = Assembly.GetCallingAssembly().GetName().Version.ToString(); 如果执行程序集是用非托管C++编写的,那么如何进行等效?有可能吗?假设我有一个.NET dll,它通过COM接口在非托管代码中被调

在C#中,可以使用反射检索与程序集相关的信息,如产品名称、版本等:

string productName = Assembly.GetCallingAssembly().GetName().Name;
string versionString = Assembly.GetCallingAssembly().GetName().Version.ToString();
如果执行程序集是用非托管C++编写的,那么如何进行等效?有可能吗?假设我有一个.NET dll,它通过COM接口在非托管代码中被调用

编辑:
为了让事情完全清楚,以下是我的设想:

  • 我有一个可执行文件 非托管C++
  • 我写了一个dll 在C#/.NET中
  • dll由 可通过COM接口执行
  • 在.NET dll中,我希望 能够检索信息,如 的产品名称和版本 调用可执行文件

可能吗?

您可以在VB.Net中使用以下代码来检索扩展文档属性:

Sub Main()
    Dim arrHeaders(41)

    Dim shell As New Shell32.Shell
    Dim objFolder As Shell32.Folder

    objFolder = shell.NameSpace("C:\tmp\")

    For i = 0 To 40
        arrHeaders(i) = objFolder.GetDetailsOf(objFolder.Items, i)
    Next
    For Each strFileName In objfolder.Items
        For i = 0 To 40
            Console.WriteLine(i & vbTab & arrHeaders(i) & ": " & objFolder.GetDetailsOf(strFileName, i))
        Next
    Next

End Sub
将对Microsoft Shell控件和自动化的COM引用添加到要编译的项目中

上述程序的输出将是分配给C:\tmp中所有文件的元数据列表,例如

0       Name: dpvoice.dll
1       Size: 208 KB
2       Type: Application Extension
3       Date Modified: 14.04.2008 04:41
4       Date Created: 14.04.2008 04:41
5       Date Accessed: 01.12.2008 09:56
6       Attributes: A
7       Status: Online
8       Owner: Administrators
9       Author:
10      Title:
11      Subject:
12      Category:
13      Pages:
14      Comments:
15      Copyright:
16      Artist:
17      Album Title:
18      Year:
19      Track Number:
20      Genre:
21      Duration:
22      Bit Rate:
23      Protected:
24      Camera Model:
25      Date Picture Taken:
26      Dimensions:
27      :
28      :
29      Episode Name:
30      Program Description:
31      :
32      Audio sample size:
33      Audio sample rate:
34      Channels:
35      Company: Microsoft Corporation
36      Description: Microsoft DirectPlay Voice
37      File Version: 5.3.2600.5512
38      Product Name: Microsoftr Windowsr Operating System
39      Product Version: 5.03.2600.5512
40      Keywords:

假设您正在查找@divo调用返回的EXE/DLL的PE头数据,例如公司、产品等。。。顺便说一句,这些源于调用Win32版本信息API-MSDN上的详细信息:

您面临的下一个挑战是枚举调用堆栈以发现调用方的模块上下文。我没有尝试过——但如果您检查自己的调用堆栈,我怀疑您是否会看到非托管调用方的帧被编组到其中。在切换到CCW之前,怀疑它在注入的过渡帧处停止。另外,由于它是COM,可以想象调用方可以从进程外调用—您的调用方将是一个代理进程

如果失败-您需要调试API来释放外部堆栈-这将引入其他约束:

  • 遍历堆栈所需的提升安全权限
  • 潜在性能影响展开堆栈
在逐个调用的基础上,这两种方法中的任何一种都可能使调试器方法不切实际

更新

一些研究表明,即使在调试器中,读取CCW过渡帧上方的堆栈也存在大量错误和陷阱。e、 g

混合的非托管/托管符号解析非常难看-这里有一些关于如何做到这一点的想法。。。DaveBr关于调试的博客也非常棒

关于在非托管/托管客户机之间编组调用所采取的步骤,有大量的素材,例如


不需要遍历堆栈来了解您所处的流程。只需进行一次Win32 API调用:

HMODULE hEXE = GetModuleHandle(NULL);
根据报告:

如果此参数为NULL,GetModuleHandle将返回用于创建调用进程(.exe文件)的文件的句柄

您可以使用另一个标准Win32 API将此模块句柄转换为文件名。文件名,然后可以调用以检索该文件的VS_VERSIONINFO结构。你想要的信息就在那里

现在,由于您在.NET中,您可以使用p/Invoke签名来。对于GetFileVersionInfo(),可以使用


但实际上,最简单的方法可能是坚持使用System.Diagnostics名称空间,您需要的一切都在那里。调用以返回正在运行的进程的进程对象。然后可以从属性中检索ProcessModule。ProcessModule有一个名为的属性。你想要的信息就在那里。

真的,我不明白你的问题。-这是不可能的。你可以用C++来编写程序集,但是它是一个托管C++。是否要从非托管代码中标识外部.Net程序集信息?