SignCli/SignCli.psm1

using namespace System
using namespace System.Collections.Generic

function Format-SignCliArgumentList {
    param (
        [Parameter(Mandatory)]
        [string]$SignCliPath,

        [Parameter(Mandatory)]
        [string]$TrustedSigningEndpoint,

        [Parameter(Mandatory)]
        [string]$TrustedSigningAccount,

        [Parameter(Mandatory)]
        [string]$TrustedSigningCertificateProfile,

        [Parameter()]
        [AllowEmptyString()]
        [string]$ClickOnceApplicationName,

        [Parameter()]
        [AllowEmptyString()]
        [string]$ClickOncePublisherName,

        [Parameter(Mandatory)]
        [List[string]]$FileList,

        [Parameter(Mandatory)]
        [string]$FileDigest,

        [Parameter()]
        [AllowEmptyString()]
        [string]$TimestampRfc3161,

        [Parameter()]
        [AllowEmptyString()]
        [string]$TimestampDigest,

        [Parameter()]
        [AllowEmptyString()]
        [string]$Description,

        [Parameter()]
        [AllowEmptyString()]
        [string]$DescriptionUrl
    )

    $result = [List[string]]::new()
    $result.Add("`"$SignCliPath`"")

    $result.Add("code")
    $result.Add("trusted-signing")

    $result.Add("-v")
    $result.Add("debug")

    $result.Add("-tse")
    $result.Add("`"$TrustedSigningEndpoint`"")

    $result.Add("-tsa")
    $result.Add("`"$TrustedSigningAccount`"")

    $result.Add("-tscp")
    $result.Add("`"$TrustedSigningCertificateProfile`"")

    if ($ClickOnceApplicationName) {
        $result.Add("-an")
        $result.Add("`"$ClickOnceApplicationName`"")
    }
    
    if ($ClickOncePublisherName) {
        $result.Add("-pn")
        $result.Add("`"$ClickOncePublisherName`"")
    }

    $result.Add("-fd")
    $result.Add($FileDigest)

    if ($TimestampRfc3161) {
        $result.Add("-t")
        $result.Add($TimestampRfc3161)
    }

    if ($TimestampDigest) {
        $result.Add("-td")
        $result.Add($TimestampDigest)
    }

    if ($Description) {
        $result.Add("-d")
        $result.Add("`"$Description`"")
    }

    if ($DescriptionUrl) {
        $result.Add("-u")
        $result.Add("`"$DescriptionUrl`"")
    }

    $result.AddRange($FileList)

    return $result
}

function Invoke-SignCli {
    param (
        [Parameter(Mandatory)]
        [string]$SignCliPath,

        [Parameter(Mandatory)]
        [List[string]]$SignCliArguments,

        [Parameter(Mandatory)]
        [int]$Timeout
    )

    Write-Information -MessageData "`tExecuting sign.dll: dotnet $SignCliArguments" -InformationAction Continue

    $startProcessParams = @{
        FilePath = "dotnet"
        ArgumentList = $SignCliArguments
        NoNewWindow = $true
        PassThru = $true
    }
    $process = Start-Process @startProcessParams

    try {
        Wait-Process -InputObject $process -Timeout $Timeout
    } catch [TimeoutException] {
        $timeoutError = "The Trusted Signing service could not finish the request within the"
        $timeoutError += " allotted time of $Timeout seconds. This may happen if you are signing"
        $timeoutError += " a large number of files. You can try to increase the value of the"
        $timeoutError += " 'Timeout' parameter which is 300 seconds by default."
        throw $timeoutError
    }

    return $process.ExitCode
}