Получить строгое имя сборки.NET в Inno Setup
Мне нужно установить эти некоторые файлы DLL в GAC.
Я использую препроцессор для генерации [Files]
записи раздела для этих библиотек DLL. И мне нужно предоставить значение для StrongAssemblyName
параметр.
Итак вопрос
- Могу ли я автоматически получить
StrongAssemblyName
DLL из скрипта на Паскале? - Если нет, можно ли создать словарь, чтобы я мог искать в словаре, используя имя сборки в качестве ключа, а затем иметь жестко закодированные строки значений, которые будут использоваться при автоматическом построении строки
Source: path; DestDir
Я бы предпочел первое решение, если это возможно.
1 ответ
Я не думаю, что есть собственный способ получить строгое имя в Inno Setup Pascal Script.
Но вы можете использовать простую команду PowerShell для получения строгого имени.
([Reflection.Assembly]::ReflectionOnlyLoadFrom('My.dll')).FullName
Объединяя эти два вопроса:
Вы получаете код, такой как:
function GetAssemblyStrongName(FileName: string): string;
var
TmpFileName: string;
Args: string;
StrongName: AnsiString;
ResultCode: Integer;
begin
TmpFileName := ExpandConstant('{tmp}') + '\strong_name.txt';
Args :=
Format('-ExecutionPolicy Unrestricted -Command "Set-Content -Path "%s" -NoNewline ' +
'-Value ([Reflection.Assembly]::ReflectionOnlyLoadFrom(''%s'')).FullName"', [
TmpFileName, FileName]);
if (not Exec('powershell.exe', Args, '', SW_HIDE, ewWaitUntilTerminated, ResultCode)) or
(ResultCode <> 0) or
(not LoadStringFromFile(TmpFileName, StrongName)) then
begin
RaiseException(Format('Error retrieving strong name of "%s"', [FileName]));
end;
Result := StrongName;
DeleteFile(TmpFileName);
end;
Хотя на самом деле вы не можете использовать Pascal Scripting, так как вам нужно строгое имя во время компиляции, а Pascal Scripting выполняется только во время установки. В некоторых случаях вы можете использовать скриптовую константу, но она не поддерживается в StrongAssemblyName
параметр.
Итак, еще раз, вы должны использовать препроцессор.
Код Pascal Script преобразуется в препроцессор как:
#define GetAssemblyStrongName(FileName) \
Local[0] = AddBackslash(GetEnv("TEMP")) + "strong_name.txt", \
Local[1] = \
"-ExecutionPolicy Unrestricted -Command """ + \
"Set-Content -Path '" + Local[0] + "' -NoNewline -Value " + \
"([Reflection.Assembly]::ReflectionOnlyLoadFrom('" + FileName + "')).FullName" + \
"""", \
Exec("powershell.exe", Local[1], SourcePath, , SW_HIDE), \
Local[2] = FileOpen(Local[0]), \
Local[3] = FileRead(Local[2]), \
FileClose(Local[2]), \
DeleteFileNow(Local[0]), \
Local[3]
Вы можете использовать его в StrongAssemblyName
параметр как:
[Files]
Source: "My.dll"; DestDir: "{app}"; \
StrongAssemblyName: "{#GetAssemblyStrongName('My.dll')}"
Который предварительно обрабатывается до чего-то вроде:
[Files]
Source: "My.dll"; DestDir: "{app}"; \
StrongAssemblyName: "My, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2271ec4a3c56d0bf"
Хотя, когда вы генерируете [Files]
раздел полностью препроцессором, ваш текущий код из вашего комментария теперь будет работать, так как синтаксис, который вы использовали, фактически вызывает GetAssemblyStrongName
макрос препроцессора, а не GetAssemblyStrongName
Функция Pascal Script.
Обратите внимание, что в приведенном выше макросе используются строки в стиле C, поэтому он должен быть вне стиля Pascal pragma
директивы:
; here
#pragma parseroption -p-
; not here
#pragma parseroption -p+
; or here