【问题标题】:Retrieve strong name of .NET assembly in Inno Setup在 Inno Setup 中检索 .NET 程序集的强名称
【发布时间】:2017-09-01 09:09:21
【问题描述】:

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

我使用预处理器为这些 DLL 生成 [Files] 部分条目。我需要为StrongAssemblyName 参数提供一个值。

所以问题

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

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

【问题讨论】:

    标签: .net inno-setup .net-assembly pascalscript strongname


    【解决方案1】:

    我不认为,在 Inno Setup Pascal 脚本中检索强名称的本地方法。

    但是,您可以使用简单的 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 脚本,因为您需要在编译时使用强名称,而 Pascal 脚本仅在安装时执行。在某些情况下,您可以使用scripted constant,但StrongAssemblyName parameter 不支持它。

    同样,您必须使用preprocessor

    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"
    

    尽管您generate the [Files] section completely by a preprocessor,您当前的评论代码现在可以工作,因为您使用的语法实际上调用GetAssemblyStrongName 预处理器宏而不是GetAssemblyStrongName Pascal 脚本函数。

    请注意,上面的宏使用 C 风格的字符串,所以它必须 Pascal 风格的pragma 指令之外:

    ; here
    
    #pragma parseroption -p-
    
    ; not here
    
    #pragma parseroption -p+
    
    ; or here
    

    【讨论】:

      猜你喜欢
      • 2011-11-16
      • 2015-11-06
      • 2015-10-19
      • 1970-01-01
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2022-10-22
      相关资源
      最近更新 更多