Разделите строку на аргументы для CLI с использованием синтаксиса DOS

Разочарование с PowerShell и Signtool: по пути к решению

Если вы когда-либо сталкивались с проблемами при использовании PowerShell для автоматизации задач, вы знаете, как это может вызывать разочарование. Недавно я провел несколько часов, пытаясь решить проблему, связанную с использованием команды signtool в Windows с помощью PowerShell. Mоя цель состояла в том, чтобы создать удобный скрипт для подписи файлов, но результаты оказались далеко не идеальными. Давайте рассмотрим, что пошло не так и как я намеревался это исправить.

Проблемы с использованием Start-Process

Первоначально я собирался использовать команду Start-Process, поскольку это распространенная практика для запуска каких-либо приложений. Однако я быстро обнаружил, что у нее есть свои недостатки. Основная проблема заключалась в том, что Start-Process выполняет команды асинхронно и имеет сложности с передачей кода состояния. Это означало, что следить за результатами выполнения было невозможно, что создавало дополнительные трудности.

Особенности интерфейса командной строки signtool

При работе с signtool оказалось, что интерфейс командной строки имеет свои особенности. Среди наиболее важных моментов:

  • Ключи и значения должны передаваться как отдельные аргументы. Если они сгруппированы в одну строку, интерпретатор будет воспринимать это как один переключатель, а не как пару ключ-значение.
  • Ключи должны начинаться с /, а не с -.
  • Пары ключ-значение не могут использовать двоеточие (:) для разделения.

Эти ограничения заставили меня пересмотреть подход к созданию аргументов.

Предоставление аргументов только при необходимости

Одной из ключевых задач при разработке моего скрипта было отправлять дополнительные аргументы для ключевых значений только в том случае, если они действительно присутствуют. Например, переменную $description следовало передавать только если она была задана. Исходя из этого, был создан небольшой сценарий, который принимает всего два аргумента: sign и все дополнительные $arguments.

Ниже приведен пример кода:

param(
  [Parameter(Mandatory=$true)][string]$file,
  [string]$description,
  [string]$expanded_description_uri
)

$arguments = "/fd sha256 /td sha256 /tr http://timestamp.digicert.com /a ${file}"
if (-not [string]::IsNullOrEmpty($description)) { $arguments = "/d `"$description`" " + $arguments }
if (-not [string]::IsNullOrEmpty($expanded_description_uri)) { $arguments = "/du `"$expanded_description_uri`" " + $arguments }
& 'C:\Program Files (x86)\Windows Kits/10/bin/10.0.26100.0/x64/signtool.exe' sign $arguments
exit $LASTEXITCODE

Разделение аргументов для корректной передачи

Далее в процессе разработки я столкнулся с необходимостью разделить аргументы правильно. Я использовал команду -Split, которая показала себя надежной:

$arguments = -Split $arguments
& 'C:\Program Files (x86)\Windows Kits/10/bin/10.0.26100.0/x64/signtool.exe' sign $arguments

Это решение позволило избежать путаницы с разделением аргументов и гарантировало, что они были переданы корректно без необходимости использования неоднозначного синтаксиса.

Заключение: освободите себя от разочарования

Эта история о моих попытках работы с signtool и PowerShell подчеркивает важность понимания тонкостей интерфейсов командной строки и синтаксиса. Важно помнить, что изучение и понимание особенностей систем, с которыми вы работаете, может значительно упростить жизнь. После всех этих трудностей я наконец достиг желаемого результата, и теперь я мог бы сосредоточиться на более продуктивных задачах. Если вы когда-либо столкнетесь с подобными проблемами, надеюсь, что этот опыт поможет вам найти эффективное решение.

Источник

Ответить

Ваш адрес email не будет опубликован. Обязательные поля помечены *