2008-12-01 146 views
0

在C#中,可以使用反射来检索类似产品名称,版本等组件的相关信息:获取产品信息/ NET

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中我想要 能够检索 调用可执行文件的产品名称和版本等信息。

可能吗?

+0

真的,我不明白你的问题。 <<程序集使用非托管C++编写>> - 这是不可能的。您可以使用C++/CLI编写程序集,但它是托管的C++。 您是否想从非托管代码中识别外部.Net程序集信息? – macropas 2008-12-01 07:58:00

回答

1

走栈是没有必要找出过程中,会在您只需做一个Win32 API调用:

HMODULE hEXE = GetModuleHandle(NULL); 

按照documentation for this call

如果此参数为NULL,则GetModuleHandle返回一只手文件用于创建调用进程(.exe文件)。

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

现在既然你在.NET中,你可以使用P/Invoke签名来获得GetModuleHandle(),GetModuleFileName()。对于GetFileVersionInfo(),您可以使用System.Diagnostics.FileVersionInfo

但实际上最简单的方法是使用System.Diagnostics命名空间,您需要的所有东西都在那里。请致电System.Diagnostics.Process.GetCurrentProcess()为您正在运行的进程返回一个Process对象。然后,您可以从MainModule属性中检索ProcessModule。 ProcessModule有一个名为FileVersionInfo的属性。你想要的信息就在那里。

+0

正是我需要的。如果我可以不止一次地对此赞赏!!谢谢!!! – jpoh 2008-12-02 02:12:40

0

,你可以使用下面的代码在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 

添加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: 
0

让我们假设你的EXE/DLL的PE文件头数据后,是那个@ divo的调用返回例如公司,产品等......这些btw。从调用Win32版本信息API的衍生 - 细节了MSDN上:

http://msdn.microsoft.com/en-us/library/ms646981.aspx

你所面临的下一个挑战是枚举调用堆栈,发现来电者的模块上下文。我还没有尝试 - 但如果你检查自己的调用堆栈,我怀疑你会看到非托管调用者的框架编组到那里。怀疑它在切换到CCW之前注入的过渡帧停止。此外,由于它是COM,可以想象,调用者可以从流程外调用 - 您的调用者将是一个代理进程。

如果失败了 - 你需要调试API的放松外堆栈 - 即引入其他方面的限制:遍历堆栈

  • 潜在性能影响展开堆栈所需

    • 提升的安全权限。

    在逐个呼叫的基础上,这些中的任何一个都可能使调试器方法不切实际。

    更新

    一些研究表明有大量的错误和陷阱的,即使在调试器读取CCW过渡帧以上的堆栈。例如

    http://support.microsoft.com/kb/317221

    混合非托管/托管符号解析是很丑陋 - 在这里如何做到这一点的一些想法...... DaveBr的调试博客是相当真棒太。

    http://bytes.com/groups/net-vc/280340-stackwalk-callstack-symbol-resolve-managed-unmanaged-code-dbghelp-etc

    http://blogs.msdn.com/davbr/archive/2005/10/06/478006.aspx

    有大量关于采取编组非托管/管理客户端之间通话的步骤饲料 - 例如

    http://msdn.microsoft.com/en-us/library/ms973872.aspx