Получение информации о продукте из неуправляемого исполняющего приложения в C # /. NET - PullRequest
0 голосов
/ 01 декабря 2008

В 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 я хочу быть возможность извлекать информацию, как название продукта и версия вызывающий исполняемый файл.

Возможно

Ответы [ 3 ]

1 голос
/ 01 декабря 2008

Обход стека не обязателен, чтобы узнать, в каком процессе вы находитесь. Вы просто делаете один вызов Win32 API:

HMODULE hEXE = GetModuleHandle(NULL);

Согласно документации для этого звонка :

Если этот параметр имеет значение NULL, GetModuleHandle возвращает дескриптор файла, используемого для создания вызывающего процесса (файл .exe).

Вы можете превратить дескриптор этого модуля в имя файла с помощью GetModuleFileName () , другого стандартного API Win32. Имя файла в руке, затем вы можете вызвать GetFileVersionInfo () , чтобы получить структуру VS_VERSIONINFO для этого файла. Необходимая информация там.

Теперь, когда вы находитесь в .NET, вы можете использовать подписи P / Invoke для GetModuleHandle () , GetModuleFileName () . Для GetFileVersionInfo () вы можете использовать System.Diagnostics.FileVersionInfo .

Но на самом деле самый простой способ сделать это, вероятно, придерживаться пространства имен System.Diagnostics, там есть все, что вам нужно. Вызовите System.Diagnostics.Process.GetCurrentProcess () , чтобы вернуть объект Process для процесса, в котором вы работаете. Затем вы можете извлечь ProcessModule из свойства MainModule . ProcessModule имеет свойство с именем FileVersionInfo . Информация, которую вы хотите, там.

0 голосов
/ 01 декабря 2008

Предположим, вы ищете данные PE-заголовка EXE / DLL, которые возвращают вызовы @ divo, например. Компания, продукт и т. Д. Эти кстати. получены из вызова Win32 API информации о версии - подробности о MSDN:

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

Следующая сложная задача, с которой вы столкнетесь, - это перечисление стека вызовов для определения контекста модуля вашего абонента. Я не пробовал - но если вы изучите свой собственный стек вызовов, я сомневаюсь, что вы увидите кадры неуправляемого вызывающего абонента там. Подозреваю, что он останавливается на переходном кадре, введенном перед переключением в CCW. Кроме того, так как это COM, возможно, вызывающий абонент может вызывать из вне процесса - ваш вызывающий будет представлять собой процесс прокси.

Если это не удастся - вам понадобятся API отладки для размотки внешнего стека - что вводит другие ограничения:

  • повышенные разрешения безопасности, необходимые для обхода стека
  • потенциальное влияние на производительность при раскручивании стека.

На основе вызовов по вызовам любой из них может сделать подход отладчика нецелесообразным.

Обновление

Некоторые исследования показывают, что существует множество ошибок и ошибок при чтении стека выше переходного кадра CCW даже в отладчике. например

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

Смешанное Неуправляемое / Управляемое разрешение символов довольно уродливо - некоторые мысли здесь о том, как это сделать ... Блог DaveBr's об отладке также довольно удивителен.

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

0 голосов
/ 01 декабря 2008

вы можете использовать следующий код в 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-ссылку на Microsoft Shell Controls and Automation в ваш проект для компиляции.

Выводом вышеуказанной программы будет список метаданных, назначенных всем файлам в 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:
...