1

我使用该editbin /LARGEADDRESSAWARE命令更改了我的 .NET C# exe,以便它可以寻址大于 2 GB 的内存。这工作正常,我可以运行dumpbin命令来验证它是否已成功修改。

然后我继续创建一个包含此 exe 的 .msi 包。当我在 Windows 7 目标机器上运行这个 .msi 时,它成功安装了 exe。但是现在,如果我dumpbin在目标机器上安装的同一个 exe 上运行,则表明它不再支持大于 2 GB 的内存。

这是什么原因造成的?是在目标机器上构建.msi 还是运行.msi 的过程?

4

3 回答 3

4

Whatever is going wrong here, it surely has something to do with you doing this by hand. Let the build system do this for you. Project + Properties, Build Events tab. Paste this into the "Post-build event command line" box:

set pathsave=%path%
set path=$(devenvdir);$(devenvdir)..\..\vc\bin
editbin.exe /nologo /largeaddressaware "$(targetfilename)"
set path=%pathsave%
于 2013-08-30T01:06:53.927 回答
1

editbin 在 msbuild 构建后步骤中设置 LARGEADDRESSAWARE 标志存在几个问题。

  1. EditBin x32 不会在 VS 命令提示符之外运行,因为找不到 mspdb100.dll。你为什么要关心?好吧,如果您运行 TFS 构建工作流,则不会从 VS 命令提示符调用 msbuild。这会导致问题...
  2. 您可以通过使用bin\amd64\editbin.exe中的那个来修复这个问题,但是您只能在 x64 构建机器上构建您的 exe。
  3. 如果您在 $(TargetPath) 处修补最终文件,那么它将起作用,但如果您重建项目并且为您的任务设置了输入和输出,那么它将不会再次运行。这是一个问题,因为在重建期间,中间文件夹中的 exe 会再次复制到未修补的最终位置。
  4. 这仍然不是它。因为如果您确实为您的 exe 命名了强名称,您需要重新签名以使强名称再次有效。它将在您的开发机器上运行,因为大多数时候开发机器都禁用了强名称验证,但它无法在客户机器上运行。

最后,您的任务将如下所示:

<Target Name="AfterBuild" BeforeTargets="CopyFilesToOutputDirectory" Inputs="$(IntermediateOutputPath)$(TargetFileName)" Outputs="$(IntermediateOutputPath)largaddessaware.tmp">
   <Exec Command="xxxxxbin\amd64\EditBin.exe /LARGEADDRESSAWARE &quot;$(IntermediateOutputPath)$(TargetFileName)&quot;"/>
   <Exec Command="sn -Ra &quot;$(IntermediateOutputPath)$(TargetFileName)&quot; &quot;$(AssemblyOriginatorKeyFile)&quot;"/>
   <Touch AlwaysCreate="true" Files="$(IntermediateOutputPath)largaddessaware.tmp"/>
</Target>

我们需要在 CopyFiletoOutputDirectory 运行之前修补可执行文件,否则我们将在未修补的文件已复制到 ouptut 文件夹后修补中间文件。最终文件无法修补,因为当 exe 未更改以防止破坏增量构建时,此目标将不会运行。

这是一个简单任务(在 PE 标头中设置一位)的经典示例,该任务很难正确完成。它(几乎)从来没有像一开始看起来那么容易。

于 2013-08-30T21:24:10.527 回答
1

editbin我认为最后我发现安装程序从与我使用构建后命令更新的路径不同的路径中选择我的 exe 。我在我的 exe 的后期构建命令中添加了这一行

copy "$(targetpath)"  "$(ProjectDir)\obj\x86\release"

所以整个后期构建命令看起来像这样

set pathsave=%path%
set path=$(devenvdir);$(devenvdir)..\..\vc\bin
editbin.exe /nologo /largeaddressaware "$(targetpath)"
copy "$(targetpath)"  "$(ProjectDir)\obj\x86\release"
set path=%pathsave%

谢谢

于 2013-09-05T20:30:31.047 回答