Archivi tag: csharp

Piccole automazioni con Powershell

Molti si chiedono perché esiste Powershell e a che pro bisognerebbe incominciare a usarlo. Me lo sono chiesto anch’io quando un ex collega ha iniziato a introdurlo in azienda preferendolo ad altri linguaggi più o meno di scripting.
Il primo risultato che mi ha restituito Google alla domanda “Why Powershell”: Why Powershell?

Ebbene, anche a non aver bisogno di mandare razzi sulla Luna è uno strumento che è giusto conoscere, specialmente se si lavora con tecnologie Microsoft ma non necessariamente. Un gran bel punto a suo favore è inoltre la facilità con cui si può sviluppare e debuggare uno script utilizzando Visual Studio Code, indipendentemente che ci si trovi su Windows, macOS o Linux. Tra l’altro quando si ha bisogno di automatizzare un qualche processo si finisce per usare quasi sempre le stesse istruzioni combinate in modo diverso, quindi appena se ne hanno alcuni a portata di mano diventa tutto un copia-e-incolla.

Qui sotto un semplice esempio di script Powershell che:

  • Compila un progetto .NET
  • Prende soltanto file dll e exe generati e li comprime in un archivio
  • Legge una stringa dal file .csproj (xml) per utilizzarla come nome del file zip
  • Prende in ingresso un parametro come argomento dello script (usandolo eventualmente come nome del file zip)
  • Utilizza un metodo del .NET Framework (System.String.IsNullOrWhiteSpace)

Dubito che qualcuno abbia bisogno di fare le stesse cose e in quest’ordine, ma anche preso a pezzi può comunque tornare utile (a me senza dubbio).

$workingDir = "./"
$projectName = "Dotnet.Project.Test"
$projectDir = "./src/$projectName/"
$csProjectFile = "$($projectDir)$($projectName).csproj"
$buildDir = "$($projectDir)bin/Release"

# args[0]: version
$interactive = $args.Length -eq 0 # if interactive can prompt questions

if ($interactive -eq $true) {
    $versionFromFile = (Select-Xml -Path $csProjectFile -XPath '/Project/PropertyGroup/Version' | Select-Object).Node.InnerText
    $versionToUse = Read-Host -Prompt "Current version is $versionFromFile, write anything if you don't want to use this one"
    if ([string]::IsNullOrWhiteSpace($versionToUse)){
        $versionToUse = $versionFromFile
    }
} else {
    $versionToUse = $args[0]
}

$zipFileName = "$versionToUse.zip"
$zipFile = "$workingDir/$zipFileName"

if (Test-Path $zipFile) {
    if ($interactive -eq $true) {
        $ShouldDeleteZip = Read-Host -Prompt "File $zipFileName already exists. Would you like to delete it now? [y/N]"
        if ($ShouldDeleteZip -eq "y") {
            Remove-Item $zipFile
        } else {
            Read-Host -Prompt "Impossible to continue without removing $zipFileName file, press a key to exit"
            Break
        }
    } else {
        Write-Host "Existing $zipFileName file, deleting it..."
        Remove-Item $zipFile
    }
}

Write-Host "Building $projectName..."

Start-Process -WorkingDirectory $workingDir -Wait -NoNewWindow -FilePath "dotnet" -ArgumentList "build ""$($csProjectFile)"" -c Release"

Write-Host "Compressing archive $zipFileName..."

Get-ChildItem -Path $buildDir |
    Where-Object { $_.Extension -eq '.dll' -Or $_.Extension -eq '.exe' -Or $_.Extension -eq '.config' } |
    Compress-Archive -DestinationPath $zipFile -Update

if (Test-Path $zipFile) {
    Write-Host "File $zipFileName created"
} else {
    Write-Host "An unknown error occurred while compressing the file"
}

Read-Host -Prompt "Press a key to exit..."