【问题标题】:Passing URL parameters to a ClickOnce application in any browser在任何浏览器中将 URL 参数传递给 ClickOnce 应用程序
【发布时间】:2012-06-15 21:26:19
【问题描述】:

我有一个 ClickOnce 应用程序,我需要能够将 URL 参数传递给它。例如,用户可以单击“http://foo.bar/MyApp.application?flavor=grape”形式的 URL,这将启动我的应用程序,并将“?flavor=grape”查询传递给它。

不幸的是,这似乎只适用于开箱即用的 IE。在 Firefox 和 Chrome 上,用户必须安装附加组件才能使 ClickOnce 部署工作。我的用户在限制性的公司环境中工作,并且不允许安装任何附加组件或其他任何东西(不过,ClickOnce 确实适用于他们)。那么,我该怎么办?

我能想到的一个技巧是将我的应用程序注册为一些足够独特的文件扩展名的文件处理程序,例如 ".bugmaster" 。然后——或者我的理论是这样的——我可以让我的网络服务器生成一个名为“flavor_grape.bugmaster”的文件;用户将单击指向该文件的 URL,然后选择“运行”而不是“保存”,这将启动我的应用程序,然后我的应用程序将解析 URL 参数的文件名。不幸的是,这种方法也不起作用。当从本地文件系统打开“flavor_grape.bugmaster”文件时,它工作得非常好,但是,由于某种原因,当用户尝试从浏览器打开文件时,这不起作用。

还有人有其他想法吗?

【问题讨论】:

    标签: .net url deployment clickonce


    【解决方案1】:

    过去可能接受的答案有效,但现在使用未记录的/dest 参数失败:无法修改“grape_setup.exe”。该文件可能是只读的或锁定的。

    幸运的是,当我在 VS 2017 和现在在 VS 2019 中尝试时,/dest 不是必需的,因此可以简单地忽略该选项。

    网址设置步骤:

    1. 制作可执行文件的副本,因为下一个命令会更改文件:

       COPY setup.exe grape_setup.exe
      
    2. 像这样替换 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 posttool 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

    这是一个实际的例子:

    1. 将可执行文件复制为grape_setup.exe。 (在第一个例子中描述)

    2. 移除 Authenticode 签名:

      delcert.exe grape_setup.exe
      
    3. 替换 URL 以设置我们的参数。 (在第一个例子中描述)

    4. 退出新创建的可执行文件:

      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 下将详细程度设置为“诊断”后,我通过查看构建输出发现了它们。

    【讨论】:

      【解决方案2】:

      ClickOnce 有一个绝妙的小技巧,您实际上可以将参数直接编码到由 setup.exe 使用的 URL 中。例如,要创建一个包含“flavor=grape”参数的 setup.exe,您可以从命令行运行以下命令:

      copy setup.exe setup-for-grape.exe
      setup.exe -url="http://foo.bar/MyApp.application?flavor=grape" /dest=setup-for-grape.exe
      

      这使用未记录的 /dest 标志将结果输出到 setup-for-grape.exe 文件,而不是修改原始 setup.exe。完成此操作后,setup-for-grape.exe 将指向您的 URL 并且 将包含您的 flavor=grape 参数。请注意,如果您使用签名,则需要对 setup.exe 的未签名副本执行此操作,然后再对其进行签名,因为它会破坏签名。

      如果可能的参数选择数量相当有限,您可以为它们全部生成 setup.exe 并从您的网站链接到它们。

      另一方面,如果有无限数量的选择,您可以设置一个 Web 服务,该服务接受一些参数,生成一个 setup.exe,其中编码了所需的参数,然后将其返回给客户端.我已经使用这种方法为连接到特定服务器的客户端生成 setup.exe - 客户端安装 URL 中编码了服务器连接信息,因此当安装客户端时,它会自动知道要连接到哪个服务器。

      当然,如果您不想使用 setup.exe,或者如果您的限制性公司环境不允许使用它,那么所有这些都会直接消失。但希望你会发现它很有用,或者至少能提供信息。

      【讨论】:

      • 哇!你每天都在学习新事物。我一直在使用 ClickOnce,但不知何故错过了这个选项。 @Marty Dill:你以前用过这种技术吗?
      • 是的!见我的倒数第二段。我用它来生成 setup.exe,其中包含有关要连接的服务器的信息。一旦系统全部启动并运行,它就会运行得非常好。
      • 这确实是一个巧妙的技巧,但不幸的是,我确实需要无限数量的选项(嗯,我想从技术上讲它是有限的,但其中有超过 1e10 个),而且我的应用程序确实需要签署。虽然我也可以设置 Web 服务来签署应用程序。不过,这是一个有趣的想法,谢谢!
      • 是的,您绝对可以让 Web 服务进行签名。我不记得我脑海中的命令,但这很容易。
      • 我想知道/dest 标志的确切意义是什么。它似乎无论如何都需要目标文件,所以你需要前COPY。但是如果你复制了它,你可以setup-for-grape.exe -url=...改变它的url。
      猜你喜欢
      • 2010-12-17
      • 2010-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-09-05
      • 1970-01-01
      相关资源
      最近更新 更多