问题描述
我需要将这些 DLL 文件安装到 GAC.
I need to install these some DLL files to the GAC.
我使用预处理器为这些 DLL 生成 [Files]
部分条目.我需要为 StrongAssemblyName
参数提供一个值.
I use preprocessor to generate [Files]
section entries for these DLLs. And I need to provide a value for the StrongAssemblyName
parameter.
那么问题
- 我能否从 Pascal 脚本中自动检索 DLL 的
StrongAssemblyName
? - 如果没有,可以创建一个字典,以便我可以使用程序集名称作为键在字典中查找,然后使用硬编码的值字符串在自动构建行时使用
来源:路径;目标目录
如果可能,我更喜欢第一个解决方案.
I would prefer the first solution, if possible.
推荐答案
我不认为,在 Inno Setup Pascal Script 中有一种本地方式来检索强名称.
I do not think, there's a native way to retrieve a strong name in Inno Setup Pascal Script.
但是,您可以使用简单的 PowerShell 命令来检索强名称.
But, you can use a simple PowerShell command to retrieve the strong name.
([Reflection.Assembly]::ReflectionOnlyLoadFrom('My.dll')).FullName
结合这两个问题:
你会得到一个类似的代码:
you get a code like:
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
参数.
Though actually, you cannot use Pascal Scripting, as you need the strong name on compile-time, and the Pascal Scripting is executed on install-time only. In some cases, you can use a scripted constant, but it's not supported in the StrongAssemblyName
parameter.
同样,您必须使用预处理器.
Pascal Script 代码转换为预处理器,如:
The Pascal Script code translates to the preprocessor like:
#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
参数中使用它,例如:
You can use it in the StrongAssemblyName
parameter like:
[Files]
Source: "My.dll"; DestDir: "{app}";
StrongAssemblyName: "{#GetAssemblyStrongName('My.dll')}"
被预处理成类似的东西:
Which gets preprocessed to something like:
[Files]
Source: "My.dll"; DestDir: "{app}";
StrongAssemblyName: "My, Version=1.0.0.0, Culture=neutral, PublicKeyToken=2271ec4a3c56d0bf"
虽然,当您完全由预处理器生成[Files]
部分时,您的您评论中的当前代码现在可以工作,因为您使用的语法实际上调用了 GetAssemblyStrongName
预处理器宏,而不是 GetAssemblyStrongName
Pascal 脚本函数.
Though, as you generate the [Files]
section completely by a preprocessor, your current code from your comment will now work, as the syntax, that you have used, actually calls GetAssemblyStrongName
preprocessor macro and not GetAssemblyStrongName
Pascal Script function.
请注意,上面的宏使用 C 风格的字符串,所以它必须在Pascal风格的pragma
指令之外:
Note that the macro above uses C-style strings, so it has to be outside the Pascal-style pragma
directives:
; here
#pragma parseroption -p-
; not here
#pragma parseroption -p+
; or here
这篇关于在 Inno Setup 中检索 .NET 程序集的强名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!