本文介绍了在 Inno Setup 中检索 .NET 程序集的强名称的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将这些 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.

那么问题

  1. 我能否从 Pascal 脚本中自动检索 DLL 的 StrongAssemblyName?
  2. 如果没有,可以创建一个字典,以便我可以使用程序集名称作为键在字典中查找,然后使用硬编码的值字符串在自动构建行时使用来源:路径;目标目录

如果可能,我更喜欢第一个解决方案.

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 程序集的强名称的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-25 01:51