Передача параметров URL в приложение ClickOnce в любом браузере

У меня есть приложение ClickOnce, и мне нужно передать ему параметры URL. Например, пользователь может щелкнуть URL-адрес формы "http://foo.bar/MyApp.application?flavor=grape", и это запустит мое приложение, передав ему запрос "? Flavor = grape".

К сожалению, похоже, что это работает только в IE. В Firefox и Chrome пользователь должен установить надстройки для развертывания ClickOnce. Мои пользователи работают в ограничительной корпоративной среде и не могут устанавливать какие-либо надстройки или что-то еще в этом случае (ClickOnce действительно работает для них). Итак, что мне делать?

Один взломан, о котором я мог думать, регистрирует мое приложение как обработчик файла для некоторого достаточно уникального расширения файла, такого как ".bugmaster". Затем - или так моя теория пошла - я мог бы создать свой веб-сервер для файла с именем "flavor_grape.bugmaster"; пользователь щелкнет URL-адрес, указывающий на этот файл, затем выберите "Запустить" вместо "Сохранить", и это запустит мое приложение, которое затем проанализирует имя файла для параметров URL. К сожалению, такой подход тоже не работает. Он отлично работает, когда файл "flavor_grape.bugmaster" открывается из локальной файловой системы, но по какой-то причине это не работает, когда пользователь пытается открыть файл из браузера.

Есть ли у кого-нибудь другие идеи?

Ответ 1

Там есть отличный маленький трюк для ClickOnce, в котором вы можете фактически кодировать параметры непосредственно в URL-адрес, который используется setup.exe. Например, чтобы создать файл setup.exe, содержащий ваш параметр "flavor = grape", вы можете запустить из командной строки следующее:

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 для всех и связать их с вашим сайтом.

С другой стороны, если есть неограниченное количество вариантов, вы можете настроить веб-службу, которая принимает некоторые параметры, генерирует файл setup.exe с требуемыми параметрами, закодированными в нем, и выплевывает его обратно клиенту, Я использовал этот метод для генерации файла setup.exe для клиентов, подключенных к определенным серверам. В URL-адресах установки клиента содержится информация о подключении к серверу, поэтому, когда клиент установлен, он автоматически знает, к какому серверу подключиться.

Конечно, если вы не хотите использовать setup.exe, или если ваша ограничительная корпоративная среда запрещает это, все это выходит прямо из окна. Но, надеюсь, вы найдете это полезным или, по крайней мере, информативным.

Ответ 2

Принятый ответ мог бы сработать в прошлом, но использование этого недокументированного параметра /dest теперь просто не работает с: Невозможно изменить 'grape_setup.exe'. Файл может быть только для чтения или заблокирован.

К счастью, /dest не был необходим, когда я сталкивался с этим год назад в VS 2017, а теперь и в VS 2019, так что этот вариант можно просто проигнорировать.

Шаги для настройки URL:

  1. Сделайте копию исполняемого файла, потому что следующая команда изменяет этот файл:

    COPY setup.exe grape_setup.exe
    
  2. Замените URL следующим образом:

    grape_setup.exe -url="http://foo.bar/MyApp.application?flavor=grape#"
    

Это дает вам исполняемый файл, который запускает приложение ClickOnce, как если бы оно было запущено с указанного URL.

Но подождите, спросите вы; Что это # на конце?

По какой-то причине я до сих пор не понял, что использование -url дает мне исполняемый файл, который при /MyApp.application запускает файл /MyApp.application в конце URL-адреса. Это # используется для того, чтобы использовать этот мусор отдельно, чтобы он не привязывался к значению "flavour". Я использовал # поэтому он поместил его в идентификатор фрагмента, но это может быть &junk= или &_= или просто & я полагаю.

Отставка исполняемого файла

Использование -url изменяет исполняемый файл, поэтому любые сигнатуры Authenticode удаляются.

К сожалению, он удален таким образом, что нарушает signtool.exe когда пытается уйти в отставку:

SignTool Error: SignedCode::Sign returned error: 0x800700C1
        %1 is not a valid Win32 application.

Этот пост в блоге, а также инструмент под названием delcert проливают свет на то, почему это происходит.

Вот вывод delcert:

ImageRemoveCertificate failed with error 0x00000057
This happens when there a listing in IMAGE_DIRECTORY_SECURITY
in the PE header, but the actual Authenticode signature has been stripped.
Let fix that ...
Setting both fields to zero ...
Succeeded.

-url из этого, -url удаляет подпись не чистым способом, и delcert может исправить это для нас!

В свете этого есть три способа получить подписанный исполняемый файл с параметрами URL:

  • Снимите -url манифесты ClickOnce" перед публикацией, опубликуйте, а затем используйте -url для установки URL-адреса. Наконец, используйте signtool.exe для подписи.
  • Опубликуйте как обычно, затем используйте -url для установки URL. delcert с delcert чтобы убрать сломанную подпись. Наконец, используйте signtool.exe для подписи.
  • Опубликуйте как обычно. Затем используйте delcert чтобы удалить подпись. Используйте -url чтобы установить 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
    

Значение /sha1 равно <ManifestCertificateThumbprint> в файле проекта .csproj.

Значение /t также равно <ManifestTimestampUrl> но не указывайте /t если timestamp не требуется.

Процесс сборки оставляет неподписанный загрузчик

Я нашел другой способ получить неподписанный 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.