mirror of
https://github.com/gerardog/gsudo.git
synced 2025-01-07 03:06:40 +08:00
Feature.NetCore: Migration to dotnet 7.0 (#157)
* feat(net-core): Migration to Net 7.0 + NativeAOT - Convert project file to SDK style - Replaced BinaryFormatter with System.Text.Json source generator - feat(net-core): Multitarget net7.0 and net4.6 - feat(build): GitHub Actions build - feat(net-core): Updated .msi installer to install x86 or x64 version upon processor platform. - docs: New blog entry for .NET 7 migration - chore: Fixed Link to Security Considerations in the help - chore(net-core): Use newer NamedPipeServerStreamAcl from NET 6.0 - fix(cache): Fix `cache on` finishing before the cache is available. Fixes #144 - feat(build): Automated Chocolatey releases - feat(net core): +semver: feature
This commit is contained in:
parent
b7865bde46
commit
2be1901dad
2
.github/CODEOWNERS
vendored
Normal file
2
.github/CODEOWNERS
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
/.github/ @gerardog
|
||||
/build/ @gerardog
|
173
.github/workflows/build.yml
vendored
Normal file
173
.github/workflows/build.yml
vendored
Normal file
@ -0,0 +1,173 @@
|
||||
name: Build, Test & Release
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- Feature.NetCore
|
||||
- master
|
||||
|
||||
jobs:
|
||||
test:
|
||||
name: Test
|
||||
runs-on: windows-latest
|
||||
permissions:
|
||||
id-token: write
|
||||
contents: read
|
||||
checks: write
|
||||
steps:
|
||||
- uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
include-prerelease: true
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Run Tests
|
||||
run: ./build/02-test.ps1
|
||||
- name: Test Report DotNet
|
||||
uses: dorny/test-reporter@v1
|
||||
if: success() || failure() # run this step even if previous step failed
|
||||
with:
|
||||
name: TestsResults (dotnet)
|
||||
path: "**/TestResults*.trx"
|
||||
reporter: dotnet-trx
|
||||
fail-on-error: false
|
||||
- name: Test Report PowerShell v5
|
||||
uses: zyborg/pester-tests-report@v1.5.0 # https://github.com/zyborg/pester-tests-report#inputs
|
||||
if: success() || failure() # run this step even if previous step failed
|
||||
with:
|
||||
test_results_path: ./testResults_PS5.xml
|
||||
report_name: TestResults PowerShell v5.x
|
||||
report_title: PowerShell v5 Tests
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Test Report PowerShell v7
|
||||
uses: zyborg/pester-tests-report@v1.5.0 # https://github.com/zyborg/pester-tests-report#inputs
|
||||
if: success() || failure() # run this step even if previous step failed
|
||||
with:
|
||||
test_results_path: ./testResults_PS7.xml
|
||||
report_name: TestResults PowerShell Core (v7.x)
|
||||
report_title: PowerShell v7 Tests
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
# - uses: OrbitalOwen/desktop-screenshot-action@0.1
|
||||
# if: always()
|
||||
# with:
|
||||
# file-name: 'desktop.jpg'
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/setup-dotnet@v2
|
||||
with:
|
||||
dotnet-version: '7.0.x'
|
||||
include-prerelease: true
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- name: Install dependencies
|
||||
run: choco install GitVersion.Portable ilmerge --confirm --no-progress
|
||||
- name: Update project version
|
||||
run: gitversion /l console /output buildserver /updateAssemblyInfo /verbosity minimal
|
||||
- name: Get project version
|
||||
id: getversion
|
||||
run: |
|
||||
echo "::set-output name=version::$(gitversion /showvariable LegacySemVer)"
|
||||
echo "::set-output name=version_MajorMinorPatch::$(gitversion /showvariable MajorMinorPatch)"
|
||||
- name: Build
|
||||
run: ./build/01-build.ps1
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Binaries
|
||||
path: ./artifacts
|
||||
outputs:
|
||||
version: ${{ steps.getversion.outputs.version }}
|
||||
version_MajorMinorPatch: ${{ steps.getversion.outputs.version_MajorMinorPatch }}
|
||||
|
||||
release:
|
||||
name: Sign & Release to GitHub
|
||||
#if: github.ref == 'refs/heads/master' && github.repository == 'gerardog/gsudo'
|
||||
if: github.repository == 'gerardog/gsudo'
|
||||
runs-on: windows-latest
|
||||
needs: [build, test]
|
||||
#needs: build
|
||||
environment:
|
||||
name: release-github
|
||||
env:
|
||||
cert_path: "C:\\secret\\cert.pfx"
|
||||
cert_key: ${{ secrets.P_F_X_Key }}
|
||||
version: ${{ needs.build.outputs.version }}
|
||||
version_MajorMinorPatch: ${{ needs.build.outputs.version_MajorMinorPatch }}
|
||||
permissions:
|
||||
contents: write
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: Binaries
|
||||
path: ./artifacts
|
||||
- name: Decode certificate
|
||||
# First encode and upload as environment secret using: [convert]::ToBase64String((Get-Content .\code_signing.pfx -AsByteStream))
|
||||
run: |
|
||||
$pfx_cert_byte = [System.Convert]::FromBase64String("${{ secrets.p_f_x }}")
|
||||
$_ = mkdir (split-path -parent $env:cert_path) -ErrorAction Ignore
|
||||
[IO.File]::WriteAllBytes("$env:cert_path", $pfx_cert_byte)
|
||||
- name: Code Sign
|
||||
run: ./build/03-sign.ps1
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Binaries
|
||||
path: ./artifacts
|
||||
- name: Package for GitHub Release
|
||||
run: ./build/04-release-GitHub.ps1
|
||||
- name: Remove the pfx
|
||||
run: Remove-Item -path $env:cert_path
|
||||
- name: Upload installer artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Installer
|
||||
path: ./artifacts/gsudoSetup.msi
|
||||
- name: Create Release
|
||||
uses: ncipollo/release-action@v1.10.0
|
||||
with:
|
||||
artifacts: "artifacts/*.*"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
draft: true
|
||||
generateReleaseNotes: true
|
||||
name: gsudo v${{env.version}}
|
||||
tag: v${{env.version}}
|
||||
commit: ${{env.GITHUB_SHA}}
|
||||
|
||||
chocolatey:
|
||||
name: Pack & Release to Chocolatey
|
||||
#if: github.ref == 'refs/heads/master' && github.repository == 'gerardog/gsudo'
|
||||
if: github.repository == 'gerardog/gsudo'
|
||||
runs-on: windows-latest
|
||||
#needs: [build, test]
|
||||
needs: [build, release]
|
||||
environment:
|
||||
name: release-chocolatey
|
||||
env:
|
||||
version: ${{ needs.build.outputs.version }}
|
||||
version_MajorMinorPatch: ${{ needs.build.outputs.version_MajorMinorPatch }}
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: Binaries
|
||||
path: ./artifacts
|
||||
- name: Import Chocolatey Api Key
|
||||
run: choco apikey --key ${{ secrets.CHOCOLATEY_APIKEY }} --source https://push.chocolatey.org/
|
||||
- name: Build Package for Chocolatey & Upload
|
||||
run: ./build/05-release-Chocolatey.ps1
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: Binaries
|
||||
path: ./artifacts
|
@ -1,4 +1,4 @@
|
||||
name: Deploy to GitHub Pages
|
||||
name: Build Documentation Website
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -10,7 +10,7 @@ on:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
name: Deploy to GitHub Pages
|
||||
name: Deploy Docs to GitHub Pages
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -23,6 +23,8 @@ bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
artifacts/
|
||||
TestResult*
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
|
61
appveyor.yml
61
appveyor.yml
@ -1,23 +1,48 @@
|
||||
image: Visual Studio 2019
|
||||
image: Visual Studio 2022
|
||||
clone_folder: c:\git\gsudo
|
||||
platform: Any CPU
|
||||
configuration: Release
|
||||
|
||||
install:
|
||||
- choco install gitversion.portable -pre -y
|
||||
- ps: Install-Module Pester -Force -SkipPublisherCheck -Scope CurrentUser
|
||||
cache:
|
||||
- src\gsudo\packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified
|
||||
- '%LocalAppData%\NuGet\Cache' # NuGet < v3
|
||||
- '%LocalAppData%\NuGet\v3-cache' # NuGet v3
|
||||
|
||||
init:
|
||||
- git config --global core.autocrlf true
|
||||
- powershell -noprofile -command "Install-Module PSReadLine -Force -SkipPublisherCheck -AllowPrerelease"
|
||||
|
||||
install:
|
||||
- choco install dotnet-7.0-sdk --pre
|
||||
- choco install gitversion.portable -y
|
||||
- ps: Install-Module Pester -Force -SkipPublisherCheck -Scope CurrentUser
|
||||
|
||||
before_build:
|
||||
- nuget restore src\gsudo.sln
|
||||
- ps: gitversion /l console /output buildserver /updateAssemblyInfo
|
||||
- ps: gitversion /l console /output buildserver /updateAssemblyInfo /verbosity minimal
|
||||
|
||||
build_script:
|
||||
- dotnet restore src\gsudo.sln
|
||||
- dotnet build src\gsudo.sln -c Release
|
||||
# net 7.0 x64 build with NativeAOT
|
||||
- dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net7.0 -r win-x64 --sc -p:PublishAot=true -p:TrimmerDefaultAction=link -p:IlcOptimizationPreference=Size
|
||||
# net 7.0 x86 does not support NativeAOT
|
||||
- dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net7.0 -r win-x86 --sc -p:PublishReadyToRun=true -p:PublishSingleFile=true
|
||||
# net framework 4.6 AnyCpu
|
||||
- dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net46 -p:Platform=x64
|
||||
|
||||
after_build:
|
||||
- 7z a gsudo.%CONFIGURATION%.%APPVEYOR_BUILD_VERSION%.Unsigned.zip %APPVEYOR_BUILD_FOLDER%\src\gsudo\bin\*.* %APPVEYOR_BUILD_FOLDER%\src\gsudo.extras\gsudoModule.* %APPVEYOR_BUILD_FOLDER%\src\gsudo.extras\Invoke-gsudo.ps1
|
||||
- appveyor PushArtifact gsudo.%CONFIGURATION%.%APPVEYOR_BUILD_VERSION%.Unsigned.zip
|
||||
- 7z a gsudo.net70.x64.Unsigned.v%APPVEYOR_BUILD_VERSION%.zip .\src\gsudo\bin\net7.0\win-x64\publish\*.* .\src\gsudo.Wrappers\gsudoModule.* .\src\gsudo.Wrappers\Invoke-gsudo.ps1
|
||||
- appveyor PushArtifact gsudo.net70.x64.Unsigned.v%APPVEYOR_BUILD_VERSION%.zip
|
||||
|
||||
- 7z a gsudo.net70.x86.Unsigned.v%APPVEYOR_BUILD_VERSION%.zip .\src\gsudo\bin\net7.0\win-x86\publish\*.* .\src\gsudo.Wrappers\gsudoModule.* .\src\gsudo.Wrappers\Invoke-gsudo.ps1
|
||||
- appveyor PushArtifact gsudo.net70.x86.Unsigned.v%APPVEYOR_BUILD_VERSION%.zip
|
||||
|
||||
- 7z a gsudo.net46.AnyCpu.Unsigned.v%APPVEYOR_BUILD_VERSION%.zip .\src\gsudo\bin\net46\publish\*.* .\src\gsudo.Wrappers\gsudoModule.* .\src\gsudo.Wrappers\Invoke-gsudo.ps1
|
||||
- appveyor PushArtifact gsudo.net46.AnyCpu.Unsigned.v%APPVEYOR_BUILD_VERSION%.zip
|
||||
|
||||
test_script:
|
||||
- ps: $Env:Path+=";$($Env:APPVEYOR_BUILD_FOLDER)/src/gsudo/bin;";
|
||||
- vstest.console /logger:Appveyor %APPVEYOR_BUILD_FOLDER%\src\gsudo.Tests\bin\%CONFIGURATION%\gsudo.Tests.dll
|
||||
- ps: $Env:Path+=";$($Env:APPVEYOR_BUILD_FOLDER)/src/gsudo/bin/net7.0/win-x64/publish;";
|
||||
- vstest.console /logger:Appveyor %APPVEYOR_BUILD_FOLDER%\src\gsudo.Tests\bin\%CONFIGURATION%\net7.0\gsudo.Tests.dll
|
||||
- powershell -c Invoke-Pester -EnableExit -OutputFile Powershell5Tests.xml -OutputFormat NUnitXml
|
||||
- pwsh -c Invoke-Pester -EnableExit -OutputFile PowershellCoreTests.xml -OutputFormat NUnitXml
|
||||
- ps: |
|
||||
@ -25,18 +50,4 @@ test_script:
|
||||
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path "PowershellCoreTests.xml"))
|
||||
|
||||
on_finish:
|
||||
- ps: if($env:APPVEYOR_RDP_ENABLED -eq 'TRUE') { $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) }
|
||||
|
||||
clone_folder: c:\git\gsudo
|
||||
platform: Any CPU
|
||||
configuration: Release
|
||||
|
||||
build:
|
||||
parallel: true
|
||||
project: src\gsudo.sln
|
||||
verbosity: minimal
|
||||
|
||||
cache:
|
||||
- src\packages -> **\packages.config # preserve "packages" directory in the root of build folder but will reset it if packages.config is modified
|
||||
- '%LocalAppData%\NuGet\Cache' # NuGet < v3
|
||||
- '%LocalAppData%\NuGet\v3-cache' # NuGet v3
|
||||
- ps: if($env:APPVEYOR_RDP_ENABLED -eq 'TRUE') { $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) }
|
6
build/00-prerequisites.ps1
Normal file
6
build/00-prerequisites.ps1
Normal file
@ -0,0 +1,6 @@
|
||||
choco install ilmerge
|
||||
choco install GitVersion.Portable
|
||||
choco install wixtoolset
|
||||
choco install hub
|
||||
choco install dotnet-7.0-sdk --pre
|
||||
|
19
build/01-build.ps1
Normal file
19
build/01-build.ps1
Normal file
@ -0,0 +1,19 @@
|
||||
pushd $PSScriptRoot\..
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -o .\artifacts\net46-AnyCpu\unmerged -f net46 -p:Platform=AnyCpu -v minimal -p:WarningLevel=0 || $(exit $LASTEXITCODE)
|
||||
#dotnet publish .\src\gsudo\gsudo.csproj -c Release -o .\artifacts\net70-arm64 -f net7.0 -r win-arm64 --sc -p:PublishReadyToRun=true -p:PublishSingleFile=true -v minimal -p:WarningLevel=0 || $(exit $LASTEXITCODE)
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -o .\artifacts\x86 -f net7.0 -r win-x86 --sc -p:PublishReadyToRun=true -p:PublishSingleFile=true -v minimal -p:WarningLevel=0 || $(exit $LASTEXITCODE)
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -o .\artifacts\x64 -f net7.0 -r win-x64 --sc -p:PublishAot=true -p:IlcOptimizationPreference=Size || $(exit $LASTEXITCODE)
|
||||
|
||||
ilmerge .\artifacts\net46-AnyCpu\unmerged\gsudo.exe .\artifacts\net46-AnyCpu\unmerged\*.dll /out:.\artifacts\net46-AnyCpu\gsudo.exe /target:exe /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /ndebug /wildcards || $(exit $LASTEXITCODE)
|
||||
|
||||
if ($?) {
|
||||
rm artifacts\net46-AnyCpu\unmerged -Recurse
|
||||
echo "ilmerge -> artifacts\net46-AnyCpu\"
|
||||
}
|
||||
|
||||
cp .\src\gsudo.Wrappers\* .\artifacts\net46-AnyCpu
|
||||
#cp .\src\gsudo.Wrappers\* .\artifacts\net70-arm64
|
||||
cp .\src\gsudo.Wrappers\* .\artifacts\x86
|
||||
cp .\src\gsudo.Wrappers\* .\artifacts\x64
|
||||
|
||||
popd
|
46
build/02-test.ps1
Normal file
46
build/02-test.ps1
Normal file
@ -0,0 +1,46 @@
|
||||
function Test-IsAdmin {
|
||||
return (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
if (! (Test-IsAdmin)) {
|
||||
throw "Must be admin to run tests"
|
||||
}
|
||||
|
||||
$failure=$false
|
||||
|
||||
pushd $PSScriptRoot\..
|
||||
|
||||
dotnet test .\src\gsudo.sln --logger "trx;LogFileName=$((gi .).FullName)\TestResults.trx" --logger:"console;verbosity=normal" -v quiet -p:WarningLevel=0
|
||||
if (! $?) { $failure = $true }
|
||||
|
||||
$env:path=(Get-Item .\src\gsudo\bin\net7.0\).FullName+";"+$env:path
|
||||
|
||||
gsudo -k > $null
|
||||
|
||||
$script = {
|
||||
Install-Module Pester -Force -SkipPublisherCheck
|
||||
Import-Module Pester
|
||||
|
||||
$configuration = New-PesterConfiguration;
|
||||
$configuration.Run.Path = "src"
|
||||
$configuration.TestResult.Enabled = $true
|
||||
$configuration.TestResult.OutputPath = "TestResults_PS$($PSVersionTable.PSVersion.Major).xml"
|
||||
$configuration.TestResult.OutputFormat = "NUnitXml"
|
||||
# $configuration.Should.ErrorAction = 'Continue'
|
||||
# $configuration.CodeCoverage.Enabled = $true
|
||||
|
||||
Invoke-Pester -Configuration $configuration
|
||||
}
|
||||
|
||||
|
||||
Write-Verbose -verbose "Running PowerShell Tests on Windows PowerShell (v5.x)"
|
||||
powershell $script
|
||||
if (! $?) { $failure = $true }
|
||||
|
||||
Write-Verbose -verbose "Running PowerShell Tests on Pwsh Core (v7.x)"
|
||||
pwsh $script
|
||||
if (! $?) { $failure = $true }
|
||||
|
||||
.\src\gsudo\bin\net7.0\gsudo.exe -k
|
||||
|
||||
if ($failure) { exit 1 }
|
55
build/03-sign.ps1
Normal file
55
build/03-sign.ps1
Normal file
@ -0,0 +1,55 @@
|
||||
pushd $PSScriptRoot\..
|
||||
|
||||
# Find SignTool.exe
|
||||
if ($env:SignToolExe) {
|
||||
# From env var.
|
||||
} elseif (get-command signtool.exe -ErrorAction Ignore) {
|
||||
# From path.
|
||||
$env:SignToolExe = (gcm signtool.exe).Path
|
||||
} elseif ($i = get-item "C:\Program Files (x86)\Windows Kits\10\bin\10.0.19041.0\x64\signtool.exe" -ErrorAction Ignore) {
|
||||
$env:SignToolExe = $i.Fullname
|
||||
} elseif ($i = get-item "C:\Program Files (x86)\Microsoft SDKs\ClickOnce\SignTool\signtool.exe" -ErrorAction Ignore) {
|
||||
$env:SignToolExe = $i.Fullname
|
||||
} else {
|
||||
Write-Output "SignTool Locations:"
|
||||
(Get-ChildItem -Path ${env:ProgramFiles(x86)} -Filter signtool.exe -Recurse -ErrorAction SilentlyContinue -Force).FullName
|
||||
popd
|
||||
throw "Unable to find SignTool.exe. Set env:SignToolExe to it's location."
|
||||
}
|
||||
|
||||
if (!$env:cert_path) { throw 'Missing $env:cert_path variable'}
|
||||
if (!$env:cert_key) { throw 'Missing $env:cert_key variable'}
|
||||
|
||||
if (!(gi "$env:cert_path")) { throw 'Missing $env:cert_path file'}
|
||||
|
||||
"Using Signtool.exe from: $env:SignToolExe"
|
||||
"Using Certificate from: $env:cert_path"
|
||||
|
||||
$files = @(
|
||||
"artifacts\x64\*.exe",
|
||||
"artifacts\x64\*.p*1"
|
||||
"artifacts\x86\*.exe",
|
||||
"artifacts\x86\*.p*1",
|
||||
#"artifacts\arm64\*.exe",
|
||||
#"artifacts\arm64\*.p*1",
|
||||
"artifacts\net46-AnyCpu\*.exe",
|
||||
"artifacts\net46-AnyCpu\*.p*1"
|
||||
) -join " "
|
||||
|
||||
# Accept $args override.
|
||||
if ($args)
|
||||
{
|
||||
$files = $args -join " "
|
||||
}
|
||||
|
||||
$cmd = "& ""$env:SignToolExe"" sign /f ""$env:cert_path"" /p $env:cert_key /fd SHA256 /t http://timestamp.digicert.com $files"
|
||||
|
||||
echo "`nInvoking SignTool.exe:`n"
|
||||
iex $cmd
|
||||
|
||||
if (! $?) {
|
||||
popd
|
||||
exit 1
|
||||
}
|
||||
|
||||
popd
|
33
build/04-release-GitHub.ps1
Normal file
33
build/04-release-GitHub.ps1
Normal file
@ -0,0 +1,33 @@
|
||||
pushd $PSScriptRoot\..
|
||||
|
||||
if ($env:version) {
|
||||
"- Getting version from env:version"
|
||||
$version = $env:version
|
||||
$version_MajorMinorPatch=$env:version_MajorMinorPatch
|
||||
} else {
|
||||
"- Getting version using GitVersion"
|
||||
$version = $(gitversion /showvariable LegacySemVer)
|
||||
$version_MajorMinorPatch=$(gitversion /showvariable MajorMinorPatch)
|
||||
}
|
||||
"- Using version number v$version / v$version_MajorMinorPatch"
|
||||
|
||||
Get-ChildItem .\artifacts\ -File | Remove-Item
|
||||
|
||||
"- Packaging v$version"
|
||||
Compress-Archive -Path ./artifacts/x86,./artifacts/x64,./artifacts/net46-AnyCpu -DestinationPath "artifacts/gsudo.v$($version).zip" -force -CompressionLevel Optimal
|
||||
(Get-FileHash artifacts\gsudo.v$($version).zip).hash > artifacts\gsudo.v$($version).zip.sha256
|
||||
|
||||
$msbuild = &"${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" -latest -prerelease -products * -requires Microsoft.Component.MSBuild -find MSBuild\**\Bin\MSBuild.exe
|
||||
|
||||
$outdir = "$PSScriptRoot\..\artifacts"
|
||||
|
||||
"- Building Installer"
|
||||
(gc src\gsudo.Installer\Constants.Template.wxi) -replace '#VERSION#', "$version" | Out-File -encoding UTF8 src\gsudo.Installer\Constants.wxi
|
||||
& $msbuild /t:Rebuild /p:Configuration=Release src\gsudo.Installer.sln /v:Minimal /p:OutputPath=$outdir || (popd && exit 1)
|
||||
rm .\artifacts\gsudoSetup.wixpdb
|
||||
|
||||
"- Code Signing Installer"
|
||||
& $PSScriptRoot\03-sign.ps1 artifacts\gsudoSetup.msi || (popd && exit 1)
|
||||
(Get-FileHash artifacts\gsudoSetup.msi).hash > artifacts\gsudoSetup.msi.sha256
|
||||
|
||||
popd
|
63
build/05-release-Chocolatey.ps1
Normal file
63
build/05-release-Chocolatey.ps1
Normal file
@ -0,0 +1,63 @@
|
||||
function Test-IsAdmin {
|
||||
return (New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
}
|
||||
|
||||
if (! (Test-IsAdmin)) {
|
||||
throw "Must be admin to properly test generated package"
|
||||
}
|
||||
|
||||
Get-Item .\artifacts\x64\gsudo.exe > $null || $(throw "Missing binaries/artifacts")
|
||||
|
||||
pushd $PSScriptRoot\..
|
||||
|
||||
if ($env:version) {
|
||||
"- Getting version from env:version"
|
||||
$version = $env:version
|
||||
$version_MajorMinorPatch=$env:version_MajorMinorPatch
|
||||
} else {
|
||||
"- Getting version using GitVersion"
|
||||
$version = $(gitversion /showvariable LegacySemVer)
|
||||
$version_MajorMinorPatch=$(gitversion /showvariable MajorMinorPatch)
|
||||
}
|
||||
"- Using version number v$version / v$version_MajorMinorPatch"
|
||||
|
||||
"- Cleaning Choco template folder"
|
||||
git clean .\Build\Chocolatey\gsudo -xf
|
||||
|
||||
"- Adding Artifacts"
|
||||
cp artifacts\x?? .\Build\Chocolatey\gsudo\tools -Recurse -Force -Exclude *.pdb
|
||||
Get-ChildItem .\build\Chocolatey\gsudo\tools\ -Recurse -Filter *.exe | % { ni "$($_.FullName).ignore" } > $null
|
||||
|
||||
# Generate gsudo.nuspec
|
||||
(Get-Content Build\Chocolatey\gsudo.nuspec.template) -replace '#VERSION#', "$version" | Out-File -encoding UTF8 .\Build\Chocolatey\gsudo\gsudo.nuspec
|
||||
# Generate Tools\VERIFICATION.txt
|
||||
Get-Content .\Build\Chocolatey\verification.txt.template | Out-File -encoding UTF8 .\Build\Chocolatey\gsudo\Tools\VERIFICATION.txt
|
||||
|
||||
"- Calculating Hashes "
|
||||
|
||||
@"
|
||||
---
|
||||
Version Hashes for v$version
|
||||
|
||||
"@ >> .\Build\Chocolatey\gsudo\Tools\VERIFICATION.txt
|
||||
Get-FileHash .\Build\Chocolatey\gsudo\Tools\*\*.* | Out-String -Width 200 | %{$_.Replace("$((gi Build\Chocolatey\gsudo).FullName)\", "",'OrdinalIgnoreCase')} >> .\Build\Chocolatey\gsudo\Tools\VERIFICATION.txt
|
||||
Get-childitem *.bak -Recurse | Remove-Item
|
||||
|
||||
"- Packing v$version to chocolatey"
|
||||
mkdir Artifacts\Chocolatey -Force > $null
|
||||
& choco pack .\Build\Chocolatey\gsudo\gsudo.nuspec -outdir="$((get-item Artifacts\Chocolatey).FullName)" || $(throw "Choco pack failed.")
|
||||
|
||||
"- Testing package"
|
||||
if (choco list -lo | Where-object { $_.StartsWith("gsudo") }) {
|
||||
choco upgrade gsudo --failonstderr -s Artifacts\Chocolatey -f -pre --confirm || $(throw "Choco upgrade failed.")
|
||||
} else {
|
||||
choco install gsudo --failonstderr -s Artifacts\Chocolatey -f -pre --confirm || $(throw "Choco install failed.")
|
||||
}
|
||||
|
||||
if($(choco apikey).Count -lt 2) { throw "Missing Chocolatey ApiKey. Use: choco apikey -k <your key here> -s https://push.chocolatey.org/" }
|
||||
|
||||
"`n- Uploading v$version to chocolatey"
|
||||
choco push artifacts\Chocolatey\gsudo.$($version).nupkg || $(throw "Choco push failed.")
|
||||
|
||||
"- Success"
|
||||
popd
|
1
build/06-release-Scoop.ps1
Normal file
1
build/06-release-Scoop.ps1
Normal file
@ -0,0 +1 @@
|
||||
|
@ -11,7 +11,7 @@ gitversion /showvariable MajorMinorPatch > "%temp%\version.tmp"
|
||||
SET /P MajorMinorPatch= < "%temp%\version.tmp"
|
||||
|
||||
set REPO_ROOT_FOLDER=%cd%
|
||||
set BIN_FOLDER=%cd%\src\gsudo\bin
|
||||
set BIN_FOLDER=%cd%\src\gsudo\bin\
|
||||
set OUTPUT_FOLDER=%REPO_ROOT_FOLDER%\Build\Releases\%version%
|
||||
|
||||
popd
|
||||
@ -27,29 +27,45 @@ echo Building with version number v%version%
|
||||
:: Cleanup
|
||||
del %BIN_FOLDER%\*.* /q
|
||||
rd %BIN_FOLDER%\package /q /s 2>nul
|
||||
|
||||
mkdir %BIN_FOLDER%\package 2> nul
|
||||
mkdir %BIN_FOLDER%\package\x64 2> nul
|
||||
mkdir %BIN_FOLDER%\package\x86 2> nul
|
||||
mkdir %BIN_FOLDER%\package\net46-AnyCpu 2> nul
|
||||
|
||||
IF EXIST %OUTPUT_FOLDER% RD %OUTPUT_FOLDER% /q /s
|
||||
mkdir %OUTPUT_FOLDER% 2> nul
|
||||
mkdir %OUTPUT_FOLDER%\bin 2> nul
|
||||
|
||||
:: Build
|
||||
%msbuild% /t:restore /p:RestorePackagesConfig=true %REPO_ROOT_FOLDER%\src\gsudo.sln /v:Minimal
|
||||
%msbuild% /t:Rebuild /p:Configuration=Release %REPO_ROOT_FOLDER%\src\gsudo.sln /p:Version=%version% /v:Minimal /p:WarningLevel=0
|
||||
echo Build net7.0 win-x64
|
||||
cmd /c rd .\src\gsudo\obj /s /q
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net7.0 -r win-x64 --sc -p:PublishAot=true -p:IlcOptimizationPreference=Size -v minimal -p:WarningLevel=0
|
||||
|
||||
echo Build net7.0 win-x86
|
||||
cmd /c rd .\src\gsudo\obj /s /q
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net7.0 -r win-x86 --sc -p:PublishReadyToRun=true -p:PublishSingleFile=true
|
||||
|
||||
echo Build net46 AnyCpu
|
||||
cmd /c rd .\src\gsudo\obj /s /q
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net46 -p:Platform=AnyCpu
|
||||
|
||||
if errorlevel 1 goto badend
|
||||
echo Build Succeded.
|
||||
|
||||
echo Running ILMerge
|
||||
pushd %BIN_FOLDER%
|
||||
|
||||
ilmerge gsudo.exe System.Security.Claims.dll System.Security.Principal.Windows.dll /out:%BIN_FOLDER%\package\gsudo.exe /target:exe /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /ndebug
|
||||
echo Running ILMerge for net46
|
||||
pushd %BIN_FOLDER%\net46\publish
|
||||
|
||||
ilmerge gsudo.exe System.Security.Claims.dll System.Security.Principal.Windows.dll /out:%BIN_FOLDER%\package\net46-AnyCpu\gsudo.exe /target:exe /targetplatform:v4,"C:\Windows\Microsoft.NET\Framework\v4.0.30319" /ndebug
|
||||
if errorlevel 1 echo ILMerge Failed - Try: choco install ilmerge & pause & popd & goto badend
|
||||
|
||||
popd
|
||||
copy %REPO_ROOT_FOLDER%\src\gsudo.extras\gsudo %BIN_FOLDER%\package\
|
||||
copy %REPO_ROOT_FOLDER%\src\gsudo.extras\gsudoModule.ps?1 %BIN_FOLDER%\package\
|
||||
copy %REPO_ROOT_FOLDER%\src\gsudo.extras\invoke-gsudo.ps1 %BIN_FOLDER%\package\
|
||||
|
||||
copy %REPO_ROOT_FOLDER%\src\gsudo.Wrappers\*.* %BIN_FOLDER%\package\x64
|
||||
copy %REPO_ROOT_FOLDER%\src\gsudo.Wrappers\*.* %BIN_FOLDER%\package\x86
|
||||
copy %REPO_ROOT_FOLDER%\src\gsudo.Wrappers\*.* %BIN_FOLDER%\package\net46-AnyCpu
|
||||
|
||||
copy %BIN_FOLDER%\net7.0\win-x64\publish\gsudo.exe %BIN_FOLDER%\package\x64
|
||||
copy %BIN_FOLDER%\net7.0\win-x86\publish\gsudo.exe %BIN_FOLDER%\package\x86
|
||||
|
||||
:: Code Sign
|
||||
if 'skipsign'=='%1' goto skipsign
|
||||
@ -57,7 +73,9 @@ if 'skipsign'=='%1' goto skipsign
|
||||
echo Signing exe.
|
||||
pushd %BIN_FOLDER%
|
||||
|
||||
%SignToolPath%signtool.exe sign /n "Open Source Developer, Gerardo Grignoli" /fd SHA256 /tr "http://time.certum.pl" %BIN_FOLDER%\package\gsudo.exe %BIN_FOLDER%\package\gsudoModule.psm1 %BIN_FOLDER%\package\gsudoModule.psd1 %BIN_FOLDER%\package\invoke-gsudo.ps1
|
||||
::%SignToolPath%signtool.exe sign /n "Open Source Developer, Gerardo Grignoli" /fd SHA256 /tr "http://time.certum.pl" package\x64\*.* package\x86\*.* package\net46-AnyCpu\*.*
|
||||
%SignToolPath%signtool.exe sign /f C:\git\code_signing.pfx /p 1234 /fd SHA256 /t http://timestamp.digicert.com package\x64\*.exe package\x64\*.p* package\x86\*.exe package\x86\*.p* package\net46-AnyCpu\*.exe package\net46-AnyCpu\*.p*
|
||||
|
||||
if errorlevel 1 echo Sign Failed & pause & popd & goto badend
|
||||
echo Sign successfull
|
||||
|
||||
@ -68,10 +86,12 @@ echo Building Installer
|
||||
|
||||
%msbuild% /t:Restore,Rebuild /p:Configuration=Release %REPO_ROOT_FOLDER%\src\gsudo.Installer.sln /v:Minimal
|
||||
if errorlevel 1 echo Buid Failed & pause & popd & goto badend
|
||||
|
||||
echo Signing Installer
|
||||
|
||||
if 'skipsign'=='%1' goto skipbuild
|
||||
%SignToolPath%signtool.exe sign /n "Open Source Developer, Gerardo Grignoli" /fd SHA256 /tr "http://time.certum.pl" %REPO_ROOT_FOLDER%\src\gsudo.Installer\bin\Release\gsudomsi.msi
|
||||
::%SignToolPath%signtool.exe sign /n "Open Source Developer, Gerardo Grignoli" /fd SHA256 /t http://timestamp.digicert.com %REPO_ROOT_FOLDER%\src\gsudo.Installer\bin\Release\gsudomsi.msi
|
||||
%SignToolPath%signtool.exe sign /f C:\git\code_signing.pfx /p 1234 /fd SHA256 /t http://timestamp.digicert.com %REPO_ROOT_FOLDER%\src\gsudo.Installer\bin\Release\gsudomsi.msi
|
||||
|
||||
:skipbuild
|
||||
|
||||
@ -87,14 +107,17 @@ pushd %REPO_ROOT_FOLDER%\Build
|
||||
|
||||
:: Create GitHub release ZIP + ZIP hash
|
||||
Set PSModulePath=
|
||||
7z a "%OUTPUT_FOLDER%\gsudo.v%version%.zip" %OUTPUT_FOLDER%\bin\*
|
||||
7z a "%OUTPUT_FOLDER%\gsudo.v%version%.zip" %BIN_FOLDER%\package\x86
|
||||
7z a "%OUTPUT_FOLDER%\gsudo.v%version%.zip" %BIN_FOLDER%\package\x64
|
||||
7z a "%OUTPUT_FOLDER%\gsudo.v%version%.zip" %BIN_FOLDER%\package\net46-AnyCpu
|
||||
|
||||
powershell -NoProfile -Command ECHO (Get-FileHash %OUTPUT_FOLDER%\gsudo.v%version%.zip).hash > %OUTPUT_FOLDER%\gsudo.v%version%.zip.sha256
|
||||
powershell -NoProfile -Command ECHO (Get-FileHash %OUTPUT_FOLDER%\gsudoSetup.msi).hash > %OUTPUT_FOLDER%\gsudoSetup.msi.sha256
|
||||
|
||||
:: Chocolatey
|
||||
git clean %REPO_ROOT_FOLDER%\Build\Chocolatey\gsudo\Bin -xf
|
||||
md %REPO_ROOT_FOLDER%\Build\Chocolatey\gsudo\Bin 2> nul
|
||||
copy %OUTPUT_FOLDER%\bin\*.* %REPO_ROOT_FOLDER%\Build\Chocolatey\gsudo\Bin\
|
||||
copy %BIN_FOLDER%\package\net46-AnyCpu\*.* %REPO_ROOT_FOLDER%\Build\Chocolatey\gsudo\Bin\
|
||||
copy %REPO_ROOT_FOLDER%\Build\Chocolatey\verification.txt.template %REPO_ROOT_FOLDER%\Build\Chocolatey\gsudo\Tools\VERIFICATION.txt
|
||||
|
||||
popd & pushd %REPO_ROOT_FOLDER%\Build\Chocolatey\gsudo
|
||||
|
@ -22,16 +22,16 @@
|
||||
<!-- == SOFTWARE SPECIFIC SECTION == -->
|
||||
<!-- This section is about the software itself -->
|
||||
<title>gsudo - a sudo for windows</title>
|
||||
<authors>Gerardo Grignoli</authors>
|
||||
<authors>Gerardo Grignoli & GitHub contributors</authors>
|
||||
<!-- projectUrl is required for the community feed -->
|
||||
<projectUrl>http://github.com/gerardog/gsudo</projectUrl>
|
||||
<!--<iconUrl>http://cdn.rawgit.com/gerardog/master/icons/gsudo.png</iconUrl>-->
|
||||
<copyright>2019 Gerardo Grignoli</copyright>
|
||||
<copyright>2022 Gerardo Grignoli</copyright>
|
||||
<!-- If there is a license Url available, it is is required for the community feed -->
|
||||
<licenseUrl>https://opensource.org/licenses/MIT</licenseUrl>
|
||||
<requireLicenseAcceptance>false</requireLicenseAcceptance>
|
||||
<projectSourceUrl>http://github.com/gerardog/gsudo</projectSourceUrl>
|
||||
<docsUrl>https://github.com/gerardog/gsudo/blob/master/README.md</docsUrl>
|
||||
<docsUrl>https://gerardog.github.io/gsudo/</docsUrl>
|
||||
<!--<mailingListUrl></mailingListUrl>-->
|
||||
<bugTrackerUrl>https://github.com/gerardog/gsudo/issues</bugTrackerUrl>
|
||||
<tags>sudo for windows run elevated user command runas powershell wsl</tags>
|
@ -8,31 +8,22 @@ Import-Module (Join-Path (Split-Path -parent $MyInvocation.MyCommand.Definition)
|
||||
$ErrorActionPreference = 'Continue'
|
||||
$ToolsLocation = Get-ToolsLocation
|
||||
|
||||
$bin = "$env:ChocolateyInstall\lib\gsudo\bin\"
|
||||
|
||||
############ Clean-up previous versions
|
||||
if (Test-Path "$bin\sudo.exe")
|
||||
{
|
||||
Remove-Item "$bin\sudo.exe"
|
||||
if ([Environment]::Is64BitOperatingSystem -eq $true) {
|
||||
$bin = "$env:ChocolateyInstall\lib\gsudo\tools\x64"
|
||||
} else {
|
||||
$bin = "$env:ChocolateyInstall\lib\gsudo\tools\x86"
|
||||
}
|
||||
|
||||
# Remove from User Path on previous versions ( <= 0.7.1 )
|
||||
Uninstall-ChocolateyPath $bin 'User'
|
||||
|
||||
# Remove from Path on previous versions ( <= 1.0.2 )
|
||||
Uninstall-ChocolateyPath $bin 'Machine'
|
||||
|
||||
if ([System.Environment]::CurrentDirectory -like "$ToolsLocation*") {
|
||||
Write-Output -Verbose "Changing directory to $ToolsLocation to ensure successfull install/upgrade."
|
||||
Set-Location $ToolsLocation
|
||||
}
|
||||
############
|
||||
|
||||
$TargetDir = ("$ToolsLocation\gsudo\v" + ((Get-Item "$bin\gsudo.exe").VersionInfo.ProductVersion -split "\+" )[0])
|
||||
$SymLinkDir = "$ToolsLocation\gsudo\Current"
|
||||
|
||||
# Add to System Path
|
||||
mkdir $TargetDir -ErrorAction Ignore
|
||||
mkdir $TargetDir -ErrorAction Ignore > $null
|
||||
copy "$bin\*" $TargetDir -Exclude *.ignore -Force
|
||||
Install-ChocolateyPath -PathToInstall $SymLinkDir -PathType 'Machine'
|
||||
|
||||
@ -49,7 +40,7 @@ cmd /c mklink /d "$SymLinkDir" "$TargetDir\"
|
||||
# gsudo powershell module banner.
|
||||
"";
|
||||
|
||||
Write-Output "gsudo successfully installed. Please restart your consoles to use gsudo."
|
||||
Write-Output "gsudo successfully installed. Please restart your consoles to use gsudo.`n"
|
||||
|
||||
if (Get-Module gsudoModule) {
|
||||
"Please restart PowerShell to update PowerShell gsudo Module."
|
||||
|
@ -1,4 +1,5 @@
|
||||
choco install ilmerge
|
||||
choco install GitVersion.Portable
|
||||
choco install wixtoolset
|
||||
choco install hub
|
||||
choco install hub
|
||||
choco install dotnet-7.0-sdk --pre
|
@ -1,10 +0,0 @@
|
||||
---
|
||||
slug: welcome
|
||||
title: Welcome
|
||||
authors: [gerardog]
|
||||
tags: []
|
||||
---
|
||||
|
||||
Welcome.
|
||||
|
||||
This site is still a work in progress.
|
63
docs/blog/2022-08-21-dotnet7/index.md
Normal file
63
docs/blog/2022-08-21-dotnet7/index.md
Normal file
@ -0,0 +1,63 @@
|
||||
---
|
||||
slug: gsudo-dotnet-7
|
||||
title: Migrating gsudo to .NET 7
|
||||
authors: [gerardog]
|
||||
tags: []
|
||||
---
|
||||
|
||||
|
||||
The first gsudo versions were made in 2019, around the release of .NET Core 3. I tried to figure out how .NET Core's redistribution model worked, but it didn't worked for me. One should either redistribute the full runtime, or ask the user to manually download and install it. There was another option: to build a self-cointained app (with runtime embedded) but that increased the output size by more than 80mb!
|
||||
|
||||
The alternative was to target .NET Framework v4.6. This version is bundled with every Windows 10/11. When targeting it, gsudo build output size was around 100kb. The app on v4.6 loaded faster, so targeting v4.6 seemed logical. It was small, fast, and the installation didn't required any big runtime redistribution or additional steps.
|
||||
|
||||
Recently, things have changed a little with [.NET 7 Preview 3 announcement](https://devblogs.microsoft.com/dotnet/announcing-dotnet-7-preview-3/#faster-lighter-apps-with-native-aot) and NativeAOT: "Publishing your app as native AOT produces an app that is self-contained and that has been ahead-of-time (AOT) compiled to native code. Native AOT apps start up very quickly and use less memory. Users of the application can run it on a machine that doesn't have the .NET runtime installed."
|
||||
|
||||
I'm almost sold! Let's try it out... *(sounds of frenetic typing)*... Ok, that was [18 files changed](https://github.com/gerardog/gsudo/compare/971ea97c...7c0c1b71). Now I have a multi-target project that can compile for v4.6 or v7. Not bad.
|
||||
|
||||
But not everyone's cup of tea: NativeAOT builds for each specific platform, so instead of having one AnyCPU build, now I have two (x64 and x86). But also, NativeAOT is only supported on x64. The closest for x86 is a self-contained build with Ready2Run.
|
||||
|
||||
Let's do some test the performance. So first let´s build for each platform:
|
||||
|
||||
``` powershell
|
||||
# Build .NET Framework v4.6
|
||||
msbuild /t:Restore /p:RestorePackagesConfig=true src\gsudo.sln /v:Minimal /p:TargetFrameworkVersion=v4.6
|
||||
msbuild /t:Rebuild /p:Configuration=Release src\gsudo\gsudo.csproj /v:Minimal /p:WarningLevel=0 /p:TargetFrameworkVersion=v4.6
|
||||
# Build .NET 7.0 x64 build with NativeAOT
|
||||
dotnet clean .\src\gsudo\gsudo.csproj -f net7.0 | Out-null
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net7.0 -r win-x64 --sc -p:PublishAot=true -p:IlcOptimizationPreference=Size -v minimal -p:WarningLevel=0
|
||||
# Build .NET 7.0 x86 build with Ready2Run
|
||||
dotnet clean .\src\gsudo\gsudo.csproj -f net7.0 -r win-x86 | Out-null
|
||||
dotnet publish .\src\gsudo\gsudo.csproj -c Release -f net7.0 -r win-x86 --sc -p:PublishReadyToRun=true -p:PublishSingleFile=true -v minimal -p:WarningLevel=0
|
||||
```
|
||||
|
||||
Now let´s meassure 100 elevations using a preexisting credentials cache. I am using `gsudo -d` to force an elevation using `cmd.exe`, which loads much faster and predictable than `Powershell`. Then I repeated the tests with each different build.
|
||||
|
||||
``` powershell
|
||||
$gsudo="C:\git\gsudo\src\gsudo\bin\net46\gsudo.exe"
|
||||
& $gsudo cache on | out-null # start a cache session.
|
||||
& $gsudo -d dir | out-null # test the cache session.
|
||||
Measure-Command { 1..100 | % { & $gsudo -d dir} } | select -Property TotalSeconds | Format-List
|
||||
& $gsudo -k | out-null # close cache.
|
||||
```
|
||||
|
||||
The first results were absurd. I found out Windows Defender takes extra time to verify unsigned apps in the cloud. So I disabled Defender and started over.
|
||||
|
||||
| | v1.3.0 (Net 4.6 + ilmerge + CodeSigned) | Latest (Net 4.6 unsigned) | Net 7.0 x64 NativeAOT (unsigned) | Net 7.0 x86 Ready2Run (unsigned) |
|
||||
| ------------------------------- | --------------------------------------- | ------------------------- | -------------------------------- | -------------------------------- |
|
||||
| Size | 180.5 KB | 208.5 KB | 6.17 MB | 16.89 MB |
|
||||
| Time to elevate 100 times (sum) | 12.75 s | 12.62 s | 7.83 s | 10.94 s |
|
||||
| Performance improvement | (baseline) | 1.04% | 38.62% | 14.18% |
|
||||
|
||||
Wow! An improvement of 38.62% is significant enough to ignore the fact that the file size has increased 6 MB, or almost 30 times.
|
||||
|
||||
## Should gsudo target .NET 7.0?
|
||||
|
||||
The problem is that the installer should provide for all platforms, and so far I´ve only focused on x64. What options do I have?
|
||||
|
||||
- I could fall back to Net 4.6 (targeting AnyCPU) for the remaining platforms. The down-side would be different prerequisites for each scenario. But the installer would only grow 6mb.
|
||||
- Or include x86 Net 7.0 Read2Run version. It´s faster, but takes 16mb. The setup including both would take 23 MB (actually 10mb when compressed)!
|
||||
|
||||
## Current situation
|
||||
|
||||
Right now my code-signing certificate is expired. Once I´ve got a new certificate, I will be making a test release. I will update this post then.
|
||||
|
@ -1,5 +1,5 @@
|
||||
gerardog:
|
||||
name: Gerardo Grignoli
|
||||
title: Maintainer of gsudo
|
||||
# title: gsudo Creator
|
||||
url: https://github.com/gerardog
|
||||
image_url: https://avatars.githubusercontent.com/u/3901474?s=96&v=4
|
||||
|
@ -14,10 +14,10 @@
|
||||
"write-heading-ids": "docusaurus write-heading-ids docs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^2.0.0-beta.21",
|
||||
"@docusaurus/plugin-google-gtag": "^2.0.0-beta.21",
|
||||
"@docusaurus/plugin-sitemap": "^2.0.0-beta.21",
|
||||
"@docusaurus/preset-classic": "^2.0.0-beta.21",
|
||||
"@docusaurus/core": "^2.0.1",
|
||||
"@docusaurus/plugin-google-gtag": "^2.0.1",
|
||||
"@docusaurus/plugin-sitemap": "^2.0.1",
|
||||
"@docusaurus/preset-classic": "^2.0.1",
|
||||
"@mdx-js/react": "^1.6.22",
|
||||
"clsx": "^1.1.1",
|
||||
"prism-react-renderer": "^1.3.1",
|
||||
|
2
src/.gitattributes
vendored
Normal file
2
src/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
gsudo.extras\*.ps1 text eol=crlf
|
||||
gsudo.extras\* text eol=lf
|
@ -1,53 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{FD3B76FD-E682-4C65-A936-84B9B2C6FB19}</ProjectGuid>
|
||||
<TargetFramework>net46</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<RootNamespace>KeyPressTester</RootNamespace>
|
||||
<AssemblyName>KeyPressTester</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Configurations>Debug;Release;Debug-Net46</Configurations>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Xml" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
@ -2,14 +2,14 @@
|
||||
|
||||
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
|
||||
|
||||
<Product Id="*" Name="gsudo v!(bind.FileVersion.GSudoExe)" Language="1033" Version="!(bind.FileVersion.GSudoExe)"
|
||||
<Product Id="*" Name="gsudo v$(env.version)" Language="1033" Version="$(env.version_MajorMinorPatch)"
|
||||
UpgradeCode="567b5616-d362-484e-b6ff-7c1875cf0aee" Manufacturer="gerardog">
|
||||
|
||||
<Package InstallerVersion="200"
|
||||
Compressed="yes"
|
||||
InstallScope="perMachine"
|
||||
Manufacturer="Silvenga"
|
||||
Description="Provides packaging for the gsudo utility by @gerardog." />
|
||||
Manufacturer="Gerardo Grignoli"
|
||||
Description="gsudo is a sudo-equivalent for windows" />
|
||||
|
||||
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
|
||||
<MediaTemplate EmbedCab="yes" />
|
||||
@ -19,6 +19,21 @@
|
||||
</Feature>
|
||||
|
||||
<UIRef Id="WixUI_InstallDir" />
|
||||
|
||||
<!-- Skip license dialog -->
|
||||
<UI>
|
||||
<Publish Dialog="WelcomeDlg"
|
||||
Control="Next"
|
||||
Event="NewDialog"
|
||||
Value="InstallDirDlg"
|
||||
Order="2">1</Publish>
|
||||
<Publish Dialog="InstallDirDlg"
|
||||
Control="Back"
|
||||
Event="NewDialog"
|
||||
Value="WelcomeDlg"
|
||||
Order="2">1</Publish>
|
||||
</UI>
|
||||
|
||||
<WixVariable Id="WixUILicenseRtf" Value="..\..\vendor\LICENSE.rtf" />
|
||||
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
|
||||
|
||||
@ -33,6 +48,7 @@
|
||||
<ComponentGroup Id="GSudo">
|
||||
<ComponentRef Id="GSudoPath" />
|
||||
<ComponentRef Id="GSudoExe" />
|
||||
<ComponentRef Id="GSudoExeX86" />
|
||||
<ComponentRef Id="GSudoBash" />
|
||||
<ComponentRef Id="GSudoPowerShell" />
|
||||
</ComponentGroup>
|
||||
@ -49,18 +65,28 @@
|
||||
Value="[INSTALLFOLDER]" />
|
||||
</Component>
|
||||
|
||||
<Component Id="GSudoExe" Guid="22f27e91-98ef-4edb-8f6b-9ed48501185c">
|
||||
<File Id="GSudoExe" KeyPath="yes" Name="gsudo.exe" Source="..\gsudo\bin\package\gsudo.exe" />
|
||||
<Component Id="GSudoExe" Guid="bec137e1-06e2-4efb-aea9-30306cc01c87">
|
||||
<Condition>
|
||||
<![CDATA[VersionNT64]]>
|
||||
</Condition>
|
||||
<File Id="GSudoExe" KeyPath="yes" Name="gsudo.exe" Source="..\..\artifacts\x64\gsudo.exe"/>
|
||||
</Component>
|
||||
|
||||
<Component Id="GSudoExeX86" Guid="bec137e1-06e2-4efb-aea9-30306cc01c86">
|
||||
<Condition>
|
||||
<![CDATA[NOT(VersionNT64)]]>
|
||||
</Condition>
|
||||
<File Id="GSudoExeX86" KeyPath="yes" Name="gsudo.exe" Source="..\..\artifacts\x86\gsudo.exe" />
|
||||
</Component>
|
||||
|
||||
<Component Id="GSudoBash" Guid="3d6047df-a14c-484d-9ded-77761d03197a">
|
||||
<File Id="GSudoBash" KeyPath="yes" Name="gsudo" Source="..\gsudo\bin\package\gsudo" />
|
||||
<File Id="GSudoBash" KeyPath="yes" Name="gsudo" Source="..\..\artifacts\x64\gsudo" />
|
||||
</Component>
|
||||
|
||||
<Component Id="GSudoPowerShell" Guid="99d35b52-4b20-42d3-afad-11a98cab2fd3">
|
||||
<File Id="GSudoModuleDef" KeyPath="no" Name="gsudoModule.psd1" Source="..\gsudo\bin\package\gsudoModule.psd1" />
|
||||
<File Id="GSudoModule" KeyPath="yes" Name="gsudoModule.psm1" Source="..\gsudo\bin\package\gsudoModule.psm1" />
|
||||
<File Id="InvokeGSudo" KeyPath="no" Name="invoke-gsudo.ps1" Source="..\gsudo\bin\package\invoke-gsudo.ps1" />
|
||||
<File Id="GSudoModuleDef" KeyPath="no" Name="gsudoModule.psd1" Source="..\..\artifacts\x64\gsudoModule.psd1" />
|
||||
<File Id="GSudoModule" KeyPath="yes" Name="gsudoModule.psm1" Source="..\..\artifacts\x64\gsudoModule.psm1" />
|
||||
<File Id="InvokeGSudo" KeyPath="no" Name="invoke-gsudo.ps1" Source="..\..\artifacts\x64\invoke-gsudo.ps1" />
|
||||
</Component>
|
||||
|
||||
</Directory>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<ProductVersion>3.10</ProductVersion>
|
||||
<ProjectGuid>34aaa3cf-95e5-41ea-8a00-c5f713bf664e</ProjectGuid>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<OutputName>gsudomsi</OutputName>
|
||||
<OutputName>gsudoSetup</OutputName>
|
||||
<OutputType>Package</OutputType>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
|
||||
|
@ -185,7 +185,7 @@ namespace gsudo.Tests
|
||||
Verb = "RunAs"
|
||||
}
|
||||
)?.WaitForExit();
|
||||
Thread.Sleep(500);
|
||||
Thread.Sleep(2000);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,78 +1,15 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" />
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{B91748FC-950F-46AB-A037-7118BEA81FF7}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>gsudo.Tests</RootNamespace>
|
||||
<AssemblyName>gsudo.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<ProjectTypeGuids>{3AC096D0-A1C2-E12C-1390-A8335801FDAB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">15.0</VisualStudioVersion>
|
||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
||||
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
|
||||
<IsCodedUITest>False</IsCodedUITest>
|
||||
<TestProjectType>UnitTest</TestProjectType>
|
||||
<NuGetPackageImportStamp>
|
||||
</NuGetPackageImportStamp>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<Configurations>Debug;Release</Configurations>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
|
||||
<HintPath>..\packages\MSTest.TestFramework.1.3.2\lib\net45\Microsoft.VisualStudio.TestPlatform.TestFramework.Extensions.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<ProjectReference Include="..\gsudo\gsudo.csproj" AdditionalProperties="TargetFramework=net7.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="ArgumentParsingTests.cs" />
|
||||
<Compile Include="AssertExtensions.cs" />
|
||||
<Compile Include="PowerShellTests.cs" />
|
||||
<Compile Include="TestProcess.cs" />
|
||||
<Compile Include="CmdTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.*" />
|
||||
<PackageReference Include="MSTest.TestAdapter" Version="1.3.2" />
|
||||
<PackageReference Include="MSTest.TestFramework" Version="1.3.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\gsudo\gsudo.csproj">
|
||||
<Project>{9eebda90-12de-4780-b8b1-8bf86dfe71b3}</Project>
|
||||
<Name>gsudo</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets" Condition="Exists('$(VSToolsPath)\TeamTest\Microsoft.TestTools.targets')" />
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.props'))" />
|
||||
<Error Condition="!Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets'))" />
|
||||
</Target>
|
||||
<Import Project="..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets" Condition="Exists('..\packages\MSTest.TestAdapter.1.3.2\build\net45\MSTest.TestAdapter.targets')" />
|
||||
</Project>
|
@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="MSTest.TestAdapter" version="1.3.2" targetFramework="net46" />
|
||||
<package id="MSTest.TestFramework" version="1.3.2" targetFramework="net46" />
|
||||
</packages>
|
@ -1,4 +1,8 @@
|
||||
Describe "PS Invoke-Gsudo (v$($PSVersionTable.PSVersion.ToString()))" {
|
||||
BeforeAll {
|
||||
$env:Path += ";" + (Get-Item (Join-Path $PSScriptRoot "..\gsudo.Wrappers")).FullName
|
||||
}
|
||||
|
||||
BeforeEach {
|
||||
$global:ErrorActionPreference=$ErrorActionPreference='Continue';
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
Describe "PS Gsudo (v$($PSVersionTable.PSVersion.ToString()))" {
|
||||
BeforeAll {
|
||||
$Path = (Get-Item (Join-Path $PSScriptRoot "gsudoModule.psm1")).FullName
|
||||
$env:Path += ";" + (Get-Item (Join-Path $PSScriptRoot "..\gsudo.Wrappers")).FullName
|
||||
$Path = (Get-Item (Join-Path $PSScriptRoot "..\gsudo.Wrappers\gsudoModule.psm1")).FullName
|
||||
$Path | Should -not -BeNullOrEmpty
|
||||
Import-Module $Path
|
||||
}
|
2
src/gsudo.extras/.gitattributes
vendored
2
src/gsudo.extras/.gitattributes
vendored
@ -1,2 +0,0 @@
|
||||
*.ps1 text eol=crlf
|
||||
* text eol=lf
|
@ -1,13 +1,13 @@
|
||||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 16
|
||||
VisualStudioVersion = 16.0.29215.179
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.1.32421.90
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "gsudo", "gsudo\gsudo.csproj", "{9EEBDA90-12DE-4780-B8B1-8BF86DFE71B3}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "gsudo.Tests", "gsudo.Tests\gsudo.Tests.csproj", "{B91748FC-950F-46AB-A037-7118BEA81FF7}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "gsudo.Tests", "gsudo.Tests\gsudo.Tests.csproj", "{B91748FC-950F-46AB-A037-7118BEA81FF7}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KeyPressTester", "KeyPressTester\KeyPressTester.csproj", "{FD3B76FD-E682-4C65-A936-84B9B2C6FB19}"
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "KeyPressTester", "KeyPressTester\KeyPressTester.csproj", "{FD3B76FD-E682-4C65-A936-84B9B2C6FB19}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
|
@ -66,8 +66,9 @@ namespace gsudo.Commands
|
||||
commandToRun.AddRange(new[]
|
||||
{"cache", "on", "--pid", AllowedPid.ToString()});
|
||||
|
||||
InputArguments.Wait = true;
|
||||
InputArguments.Direct = true;
|
||||
return await new RunCommand() {CommandToRun = commandToRun}
|
||||
return await new RunCommand() {CommandToRun = commandToRun, }
|
||||
.Execute().ConfigureAwait(false);
|
||||
}
|
||||
else
|
||||
@ -84,6 +85,10 @@ namespace gsudo.Commands
|
||||
|
||||
Logger.Instance.Log("Cache is a security risk. Use `gsudo cache off` (or `-k`) to go back to safety.",
|
||||
LogLevel.Warning);
|
||||
|
||||
// wait until the cache service becomes available (2 seconds max)
|
||||
for (int i=0; i<40 && !NamedPipeClient.IsServiceAvailable(AllowedPid); i++)
|
||||
await Task.Delay(50).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -35,9 +35,7 @@ namespace gsudo.Commands
|
||||
Console.WriteLine("gsudo config\t\t\t\tShow current config settings & values.");
|
||||
Console.WriteLine("gsudo config {key} [--global] [value] \tRead or write a user setting");
|
||||
Console.WriteLine("gsudo config {key} [--global] --reset \tReset config to default value");
|
||||
|
||||
Console.WriteLine("gsudo status\t\t\t\tShow status about current user, security, integrity level or other gsudo relevant data.");
|
||||
// Console.WriteLine("gsudo confighelp \tGet additional help about config settings.");
|
||||
Console.WriteLine();
|
||||
Console.WriteLine("General options:");
|
||||
Console.WriteLine(" -n | --new Starts the command in a new console (and returns immediately).");
|
||||
@ -49,11 +47,6 @@ namespace gsudo.Commands
|
||||
Console.WriteLine(" --loadProfile When elevating PowerShell commands, do load profiles.");
|
||||
Console.WriteLine(" --copyns Connect network drives to the elevated user. Warning: Verbose, interactive asks for credentials");
|
||||
Console.WriteLine();
|
||||
/*
|
||||
Console.WriteLine("Credentials Cache options:");
|
||||
Console.WriteLine($" If no cache option is specified, your credentials will be cached for {Settings.CacheDuration.Value.TotalSeconds} seconds.");
|
||||
Console.WriteLine();
|
||||
*/
|
||||
Console.WriteLine("Other options:");
|
||||
Console.WriteLine(" --loglevel {val} Set minimum log level to display: All, Debug, Info, Warning, Error, None");
|
||||
Console.WriteLine(" --debug Enable debug mode.");
|
||||
@ -61,7 +54,7 @@ namespace gsudo.Commands
|
||||
Console.WriteLine(" --vt (deprecated) Set console mode to piped VT100 ConPty/PseudoConsole (experimental).");
|
||||
Console.WriteLine(" --attached (deprecated) Set console mode to attached.");
|
||||
Console.WriteLine(" --copyev (deprecated) Copy environment variables to the elevated process. (not needed on default console mode)");
|
||||
Console.Write("\nLearn more about security considerations of using gsudo at: https://bit.ly/gsudoSecurity\n");
|
||||
Console.Write("\nLearn more about security considerations of using gsudo at: https://gerardog.github.io/gsudo/docs/security\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -349,8 +349,12 @@ namespace gsudo.Commands
|
||||
nameof(gsudo));
|
||||
|
||||
var dirSec = new DirectorySecurity();
|
||||
dirSec.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, AccessControlType.Allow));
|
||||
Directory.CreateDirectory(tempFolder, dirSec);
|
||||
dirSec.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), FileSystemRights.FullControl, AccessControlType.Allow));
|
||||
#if NETFRAMEWORK
|
||||
Directory.CreateDirectory(tempFolder, dirSec);
|
||||
#else
|
||||
dirSec.CreateDirectory(tempFolder);
|
||||
#endif
|
||||
|
||||
string tempBatName = Path.Combine(
|
||||
tempFolder,
|
||||
@ -360,7 +364,9 @@ namespace gsudo.Commands
|
||||
|
||||
System.Security.AccessControl.FileSecurity fSecurity = new System.Security.AccessControl.FileSecurity();
|
||||
fSecurity.AddAccessRule(new System.Security.AccessControl.FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null), System.Security.AccessControl.FileSystemRights.FullControl, System.Security.AccessControl.AccessControlType.Allow));
|
||||
File.SetAccessControl(tempBatName, fSecurity);
|
||||
|
||||
new FileInfo(tempBatName).SetAccessControl(fSecurity);
|
||||
|
||||
|
||||
return new string[] {
|
||||
Environment.GetEnvironmentVariable("COMSPEC"),
|
||||
|
@ -5,6 +5,9 @@ using System.IO;
|
||||
using gsudo.Rpc;
|
||||
using gsudo.ProcessHosts;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
#if NETCOREAPP
|
||||
using System.Text.Json;
|
||||
#endif
|
||||
|
||||
namespace gsudo.Commands
|
||||
{
|
||||
@ -123,9 +126,11 @@ namespace gsudo.Commands
|
||||
|
||||
Logger.Instance.Log($"ElevationRequest length {dataSizeInt}", LogLevel.Debug);
|
||||
|
||||
return (ElevationRequest) new BinaryFormatter()
|
||||
.Deserialize(new MemoryStream(inBuffer));
|
||||
|
||||
#if NETFRAMEWORK
|
||||
return (ElevationRequest)new BinaryFormatter().Deserialize(new MemoryStream(inBuffer));
|
||||
#else
|
||||
return JsonSerializer.Deserialize(inBuffer, ElevationRequestJsonContext.Default.ElevationRequest);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -3,6 +3,9 @@ using System.Globalization;
|
||||
using System.Security.AccessControl;
|
||||
using System.Security.Principal;
|
||||
using System.Threading;
|
||||
#if NETFRAMEWORK
|
||||
using EventWaitHandleAcl = System.Threading.EventWaitHandle;
|
||||
#endif
|
||||
|
||||
namespace gsudo
|
||||
{
|
||||
@ -46,20 +49,28 @@ namespace gsudo
|
||||
EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
|
||||
AccessControlType.Allow));
|
||||
|
||||
if (!EventWaitHandle.TryOpenExisting(
|
||||
if (!EventWaitHandleAcl.TryOpenExisting(
|
||||
GLOBAL_WAIT_HANDLE_NAME,
|
||||
EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
|
||||
out var eventWaitHandle))
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
eventWaitHandle = new EventWaitHandle(false, EventResetMode.ManualReset, GLOBAL_WAIT_HANDLE_NAME, out var created, security);
|
||||
#else
|
||||
eventWaitHandle = EventWaitHandleAcl.Create(false, EventResetMode.ManualReset, GLOBAL_WAIT_HANDLE_NAME, out var created, security);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!EventWaitHandle.TryOpenExisting(
|
||||
if (!EventWaitHandleAcl.TryOpenExisting(
|
||||
GLOBAL_WAIT_HANDLE_NAME + pid.ToString(CultureInfo.InvariantCulture),
|
||||
EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify,
|
||||
out var eventWaitHandleSpecific))
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
eventWaitHandleSpecific = new EventWaitHandle(false, EventResetMode.ManualReset, GLOBAL_WAIT_HANDLE_NAME + pid.ToString(CultureInfo.InvariantCulture), out var created, security);
|
||||
#else
|
||||
eventWaitHandleSpecific = EventWaitHandleAcl.Create(false, EventResetMode.ManualReset, GLOBAL_WAIT_HANDLE_NAME + pid.ToString(CultureInfo.InvariantCulture), out var created, security);
|
||||
#endif
|
||||
}
|
||||
|
||||
var credentialsResetThread = new Thread(() =>
|
||||
@ -83,7 +94,7 @@ namespace gsudo
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var eventWaitHandle = EventWaitHandle.OpenExisting(
|
||||
using (var eventWaitHandle = EventWaitHandleAcl.OpenExisting(
|
||||
GLOBAL_WAIT_HANDLE_NAME + (pid?.ToString(CultureInfo.InvariantCulture) ?? ""),
|
||||
EventWaitHandleRights.Synchronize | EventWaitHandleRights.Modify))
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ namespace gsudo
|
||||
}
|
||||
}
|
||||
|
||||
#if NETFRAMEWORK
|
||||
class MySerializationBinder : SerializationBinder
|
||||
{
|
||||
/// <summary>
|
||||
@ -68,4 +69,10 @@ namespace gsudo
|
||||
typeName = serializedType.FullName;
|
||||
}
|
||||
}
|
||||
#else
|
||||
[System.Text.Json.Serialization.JsonSerializable(typeof(ElevationRequest))]
|
||||
internal partial class ElevationRequestJsonContext : System.Text.Json.Serialization.JsonSerializerContext
|
||||
{
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -15,10 +15,13 @@ namespace gsudo.Helpers
|
||||
{
|
||||
private static int? _cacheGetCurrentIntegrityLevelCache;
|
||||
private static bool? _cacheIsAdmin;
|
||||
private static string _cacheOwnExeName;
|
||||
|
||||
public static string GetOwnExeName()
|
||||
{
|
||||
return SymbolicLinkSupport.ResolveSymbolicLink(System.Reflection.Assembly.GetEntryAssembly().Location);
|
||||
if (_cacheOwnExeName != null)
|
||||
return _cacheOwnExeName;
|
||||
return _cacheOwnExeName = SymbolicLinkSupport.ResolveSymbolicLink(System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
|
||||
}
|
||||
|
||||
public static string GetExeName(this Process process)
|
||||
|
@ -17,6 +17,7 @@ namespace gsudo.Helpers
|
||||
/// </summary>
|
||||
public static void EnableAssemblyLoadFix()
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
string exeName = ProcessHelper.GetOwnExeName();
|
||||
string exeNamePath = Path.GetDirectoryName(exeName);
|
||||
|
||||
@ -35,6 +36,7 @@ namespace gsudo.Helpers
|
||||
if (File.Exists(target))
|
||||
return Assembly.LoadFrom(target);
|
||||
return null;
|
||||
#endif
|
||||
}
|
||||
|
||||
public static string ResolveSymbolicLink(string symLinkFullPath)
|
||||
@ -44,7 +46,7 @@ namespace gsudo.Helpers
|
||||
.Replace("\\\\?\\", "")
|
||||
;
|
||||
}
|
||||
public static string GetFinalPathName(string path)
|
||||
private static string GetFinalPathName(string path)
|
||||
{
|
||||
var h = Native.FileApi.CreateFile(path,
|
||||
Native.FileApi.FILE_READ_EA,
|
||||
@ -77,3 +79,4 @@ namespace gsudo.Helpers
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -164,7 +164,7 @@ namespace gsudo.Native
|
||||
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szExeFile;
|
||||
};
|
||||
|
||||
[SuppressUnmanagedCodeSecurity, HostProtection(SecurityAction.LinkDemand, MayLeakOnAbort = true)]
|
||||
[SuppressUnmanagedCodeSecurity]
|
||||
internal sealed class SafeSnapshotHandle : SafeHandleMinusOneIsInvalid
|
||||
{
|
||||
internal SafeSnapshotHandle() : base(true)
|
||||
|
@ -2,6 +2,9 @@
|
||||
using System.IO;
|
||||
using System.IO.Pipes;
|
||||
using System.Runtime.Serialization.Formatters.Binary;
|
||||
#if NETCOREAPP
|
||||
using System.Text.Json;
|
||||
#endif
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
@ -58,6 +61,7 @@ namespace gsudo.Rpc
|
||||
|
||||
public async Task WriteElevationRequest(ElevationRequest elevationRequest)
|
||||
{
|
||||
#if NETFRAMEWORK
|
||||
// Using Binary instead of Newtonsoft.JSON to reduce load times.
|
||||
var ms = new System.IO.MemoryStream();
|
||||
new BinaryFormatter()
|
||||
@ -71,6 +75,13 @@ namespace gsudo.Rpc
|
||||
await ControlStream.WriteAsync(lengthArray, 0, sizeof(int)).ConfigureAwait(false);
|
||||
await ControlStream.WriteAsync(ms.ToArray(), 0, (int)ms.Length).ConfigureAwait(false);
|
||||
await ControlStream.FlushAsync().ConfigureAwait(false);
|
||||
#else
|
||||
byte[] utf8Json = JsonSerializer.SerializeToUtf8Bytes(elevationRequest, ElevationRequestJsonContext.Default.ElevationRequest);
|
||||
|
||||
await ControlStream.WriteAsync(BitConverter.GetBytes(utf8Json.Length), 0, sizeof(int)).ConfigureAwait(false);
|
||||
await ControlStream.WriteAsync(utf8Json, 0, utf8Json.Length).ConfigureAwait(false);
|
||||
await ControlStream.FlushAsync().ConfigureAwait(false);
|
||||
#endif
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
|
@ -72,20 +72,21 @@ namespace gsudo.Rpc
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsServiceAvailable()
|
||||
public static bool IsServiceAvailable(int? pid = null, string sid = null)
|
||||
{
|
||||
string pipeName = null;
|
||||
var callerProcessId = Process.GetCurrentProcess().Id;
|
||||
string user = System.Security.Principal.WindowsIdentity.GetCurrent().User.Value;
|
||||
|
||||
while (callerProcessId > 0)
|
||||
pid = pid ?? ProcessHelper.GetParentProcessId(Process.GetCurrentProcess().Id);
|
||||
sid = sid ?? System.Security.Principal.WindowsIdentity.GetCurrent().User.Value;
|
||||
|
||||
while (pid.Value > 0)
|
||||
{
|
||||
callerProcessId = ProcessHelper.GetParentProcessId(callerProcessId);
|
||||
pipeName = NamedPipeNameFactory.GetPipeName(user, callerProcessId);
|
||||
pipeName = NamedPipeNameFactory.GetPipeName(sid, pid.Value);
|
||||
// Does the pipe exists?
|
||||
if (NamedPipeUtils.ExistsNamedPipe(pipeName))
|
||||
break;
|
||||
|
||||
pid = ProcessHelper.GetParentProcessId(pid.Value);
|
||||
pipeName = null;
|
||||
// try grandfather.
|
||||
}
|
||||
|
@ -80,11 +80,19 @@ namespace gsudo.Rpc
|
||||
|
||||
do
|
||||
{
|
||||
using (NamedPipeServerStream dataPipe = new NamedPipeServerStream(pipeName, PipeDirection.InOut, MAX_SERVER_INSTANCES,
|
||||
PipeTransmissionMode.Message, PipeOptions.Asynchronous, Settings.BufferSize, Settings.BufferSize, ps))
|
||||
#if NETFRAMEWORK
|
||||
using (NamedPipeServerStream dataPipe = new NamedPipeServerStream(
|
||||
#else
|
||||
using (var dataPipe = System.IO.Pipes.NamedPipeServerStreamAcl.Create(
|
||||
#endif
|
||||
pipeName, PipeDirection.InOut, MAX_SERVER_INSTANCES, PipeTransmissionMode.Message, PipeOptions.Asynchronous, Settings.BufferSize, Settings.BufferSize, ps))
|
||||
{
|
||||
using (NamedPipeServerStream controlPipe = new NamedPipeServerStream(pipeName + "_control", PipeDirection.InOut, MAX_SERVER_INSTANCES,
|
||||
PipeTransmissionMode.Message, PipeOptions.Asynchronous, Settings.BufferSize, Settings.BufferSize, ps))
|
||||
#if NETFRAMEWORK
|
||||
using (var controlPipe = new NamedPipeServerStream(
|
||||
#else
|
||||
using (var controlPipe = System.IO.Pipes.NamedPipeServerStreamAcl.Create(
|
||||
#endif
|
||||
pipeName + "_control", PipeDirection.InOut, MAX_SERVER_INSTANCES, PipeTransmissionMode.Message, PipeOptions.Asynchronous, Settings.BufferSize, Settings.BufferSize, ps))
|
||||
{
|
||||
Logger.Instance.Log("NamedPipeServer listening.", LogLevel.Debug);
|
||||
Task.WaitAll(
|
||||
|
@ -296,7 +296,9 @@ namespace gsudo.Tokens
|
||||
|
||||
public TokenProvider Impersonate(Action ActionImpersonated)
|
||||
{
|
||||
using (var ctx = System.Security.Principal.WindowsIdentity.Impersonate(GetToken().DangerousGetHandle()))
|
||||
System.Security.Principal.WindowsIdentity.RunImpersonated(new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(GetToken().DangerousGetHandle()), ActionImpersonated);
|
||||
|
||||
/* using (var ctx = System.Security.Principal.WindowsIdentity.Impersonate(GetToken().DangerousGetHandle()))
|
||||
{
|
||||
try
|
||||
{
|
||||
@ -308,24 +310,17 @@ namespace gsudo.Tokens
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
return this;
|
||||
}
|
||||
|
||||
public T Impersonate<T>(Func<T> ActionImpersonated)
|
||||
|
||||
{
|
||||
using (var ctx = System.Security.Principal.WindowsIdentity.Impersonate(GetToken().DangerousGetHandle()))
|
||||
{
|
||||
try
|
||||
{
|
||||
return ActionImpersonated();
|
||||
}
|
||||
finally
|
||||
{
|
||||
ctx.Undo();
|
||||
}
|
||||
}
|
||||
}
|
||||
T res = default;
|
||||
System.Security.Principal.WindowsIdentity.RunImpersonated(new Microsoft.Win32.SafeHandles.SafeAccessTokenHandle(GetToken().DangerousGetHandle()), () => { res = ActionImpersonated(); });
|
||||
return res;
|
||||
}
|
||||
|
||||
public TokenProvider EnablePrivileges(bool throwOnFailure, params Privilege[] priviledgesList)
|
||||
{
|
||||
|
@ -1,15 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net46</TargetFramework>
|
||||
<TargetFrameworks>net7.0;net46</TargetFrameworks>
|
||||
<SignAssembly>false</SignAssembly>
|
||||
<AssemblyOriginatorKeyFile>StrongName.snk</AssemblyOriginatorKeyFile>
|
||||
<Authors>Gerardo Grignoli</Authors>
|
||||
<Description>gsudo is a sudo for Windows, allows to run commands with elevated permissions in the current console.</Description>
|
||||
<DelaySign>false</DelaySign>
|
||||
<OutputPath>bin\</OutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||
<AppendTargetFrameworkToOutputPath>true</AppendTargetFrameworkToOutputPath>
|
||||
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
|
||||
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
|
||||
<Version>1.0.0-prerelease</Version>
|
||||
@ -24,21 +23,24 @@
|
||||
<PathMap>$(MSBuildProjectDirectory)=C:\</PathMap>
|
||||
<AssemblyVersion>1.0.0.0</AssemblyVersion>
|
||||
<FileVersion>1.0.0.0</FileVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<NoWarn>1701;1702;CA1303;CA1707;CA1028;CA1001;CA1031;CA1416</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(TargetFramework)'=='net7.0'">
|
||||
<AutoGenerateBindingRedirects>False</AutoGenerateBindingRedirects>
|
||||
<PublishTrimmed>true</PublishTrimmed>
|
||||
<InvariantGlobalization>true</InvariantGlobalization>
|
||||
<IlcOptimizationPreference>Size</IlcOptimizationPreference>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>DEBUG</DefineConstants>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<NoWarn>1701;1702;CA1303;CA1707;CA1028;CA1001;CA1031</NoWarn>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Remove="bin\**" />
|
||||
<EmbeddedResource Remove="bin\**" />
|
||||
<None Remove="bin\**" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="GitVersion.MsBuild" Version="5.6.11">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
@ -48,13 +50,17 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Security.Principal.Windows" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net7.0'">
|
||||
<PackageReference Include="System.Security.Principal.Windows" Version="5.0.0" />
|
||||
<PackageReference Include="System.Threading.AccessControl" Version="6.0.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Condition="'$(TargetFramework)'=='net46'">
|
||||
<PackageReference Include="System.Security.Principal.Windows" Version="4.6.0" />
|
||||
</ItemGroup>
|
||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||
<Exec Command="echo Killing running gsudo commands.
gsudo -k 2>nul
%25windir%25\sysnative\tskill gsudo
exit 0" />
|
||||
</Target>
|
||||
|
||||
<Target Name="PostBuildMacros">
|
||||
<GetAssemblyIdentity AssemblyFiles="$(TargetPath)">
|
||||
<Output TaskParameter="Assemblies" ItemName="Targets" />
|
||||
@ -63,5 +69,4 @@
|
||||
<VersionNumber Include="$([System.Text.RegularExpressions.Regex]::Replace("%(Targets.Version)", "^(.*?)(\.0)*$", "$1"))" />
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
Loading…
Reference in New Issue
Block a user