过去可能接受的答案有效,但现在使用未记录的/dest 参数失败:无法修改“grape_setup.exe”。该文件可能是只读的或锁定的。
幸运的是,当我在 VS 2017 和现在在 VS 2019 中尝试时,/dest 不是必需的,因此可以简单地忽略该选项。
网址设置步骤:
-
制作可执行文件的副本,因为下一个命令会更改文件:
COPY setup.exe grape_setup.exe
-
像这样替换 URL:
grape_setup.exe -url="http://foo.bar/MyApp.application?flavor=grape#"
这会更改grape_setup.exe,以便后续运行启动 ClickOnce 应用程序,就好像它是从指定的 URL 打开一样。
但是等等,最后那个#是什么?
出于某种原因,我还没有弄清楚,使用-url 会给我一个可执行文件,该可执行文件在URL 的末尾有一个额外的/MyApp.application。 # 用于分离此字符串,因此它不会被视为最后一个 URL 参数值的一部分。使用# 会将其放入fragment identifier,但替代方法是使用&junk= 或&_= 或仅使用&。
退出可执行文件
使用 -url 修改可执行文件并删除所有 Authenticode 签名。
不幸的是,它在尝试辞职时以破坏signtool.exe 的方式将其删除:
SignTool Error: SignedCode::Sign returned error: 0x800700C1
%1 is not a valid Win32 application.
This blog post 和 tool called delcert 阐明了为什么会发生这种情况。
这是delcert的输出:
ImageRemoveCertificate failed with error 0x00000057
This happens when there's a listing in IMAGE_DIRECTORY_SECURITY
in the PE's header, but the actual Authenticode signature has been stripped.
Let's fix that ...
Setting both fields to zero ...
Succeeded.
这表明-url 以非干净的方式删除了签名,delcert 可以为我们解决这个问题。
鉴于此问题,似乎有三个选项可用于获取带有嵌入式 URL 参数的签名可执行文件:
- 在发布之前取消选中“签署 ClickOnce 清单”,发布,然后使用
-url 设置 URL。最后用signtool.exe签名。
- 照常发布,使用
-url设置网址。跟进delcert 以清理损坏的签名。最后用signtool.exe签名。
- 照常发布。然后使用
delcert 删除签名。使用-url设置网址,最后用signtool.exe签名。
这三种方法都可能创建相同的可执行文件。第一个需要更改为.csproj。第二个和第三个依赖第三方软件delcert。
这是一个实际的例子:
-
将可执行文件复制为grape_setup.exe。 (在第一个例子中描述)
-
移除 Authenticode 签名:
delcert.exe grape_setup.exe
-
替换 URL 以设置我们的参数。 (在第一个例子中描述)
-
退出新创建的可执行文件:
signtool.exe sign /sha1 XYZ /t "http://..." grape_setup.exe
项目.csproj文件中/sha1的值为<ManifestCertificateThumbprint>。
/t 的值为<ManifestTimestampUrl>,但如果不需要时间戳,/t 可以省略。
让构建过程留下一个未签名的引导程序
我找到了另一种获取未签名的setup.exe 的方法,这使我不必使用delcert 之类的软件删除签名。
通过将此添加到我的.csproj 文件中,构建过程会在bin\Release\app.publish\ 下留下一个未签名的副本作为unsigned_setup.exe。
<Target Name="UnsignedBootstrapper" AfterTargets="_DeploymentGenerateBootstrapper" BeforeTargets="_DeploymentSignClickOnceDeployment">
<Copy SourceFiles="$(PublishDir)\setup.exe" DestinationFiles="$(PublishDir)\unsigned_setup.exe" />
</Target>
_DeploymentGenerateBootstrapper 目标生成引导程序并 _DeploymentSignClickOnceDeployment 对其进行签名。上述目标在两者之间运行以制作可执行文件的副本。
这在 VS 2019 中有效,但目标名称在其他版本中可能有所不同。在Options > Project and Solutions > Build and Run 下将详细程度设置为“诊断”后,我通过查看构建输出发现了它们。