在 Inno Setup 中检索 .NET 程序集的强名称

2023-12-10

我需要将这些 DLL 文件安装到 GAC 中。

我使用预处理器来生成[Files]这些 DLL 的节条目。我需要提供一个值StrongAssemblyName范围。

所以问题

  1. 可以自动检索吗StrongAssemblyName来自 Pascal 脚本的 DLL?
  2. 如果没有,可以创建一个字典,以便我可以使用程序集名称作为键在字典中查找,然后使用硬编码的值字符串,在自动构建行时使用这些字符串Source: path; DestDir

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


我认为,在 Inno Setup Pascal Script 中没有一种本地方法可以检索强名称。

但是,您可以使用简单的 PowerShell 命令来检索强名称。

([Reflection.Assembly]::ReflectionOnlyLoadFrom('My.dll')).FullName

结合这两个问题:

  • 我如何才能看到我的程序集的强名称?
  • 如何在 Inno Setup 中获取 Exec'ed 程序的输出?

你会得到如下代码:

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 脚本代码转换为预处理器,如下所示:

#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帕斯卡脚本函数。

请注意,上面的宏使用 C 风格的字符串,因此它必须是outside帕斯卡风格pragma指令:

; here

#pragma parseroption -p-

; not here

#pragma parseroption -p+

; or here
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Inno Setup 中检索 .NET 程序集的强名称 的相关文章

随机推荐