Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Chocolatey installer to use same .MSI install as WinGet #213

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
11 changes: 3 additions & 8 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,20 +46,15 @@ jobs:
[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
- name: Upload build artifacts
uses: actions/upload-artifact@v3
with:
name: Installer
path: ./artifacts/gsudoSetup.msi
name: Binaries
path: ./artifacts
- name: Create Release
uses: ncipollo/release-action@v1.11.1
with:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -306,9 +306,9 @@ How to use, very briefly:

No. `gsudo` reminds of the original sudo regarding user expectations. Many `sudo` features are `*nix` specific and could never have a `Windows` counterpart. Other features (such as `sudoers`) could potentially be implemented but are not at this point.

- Does it work in Windows 7/8?
- What are the requirements? Does it work in Windows 7/8?

Yes, it works from Win7 SP1 onwards, except the credentials cache.
It works on Win7 SP1 onwards. Some features may only work in Windows 10/11, like elevating as TrustedInstaller.

- How do I return to the previous security level after using gsudo?

Expand Down
9 changes: 7 additions & 2 deletions build/05-release-Chocolatey.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@ if ($env:version) {
"- 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 chocolateyinstall.ps1
(Get-Content .\build\Chocolatey\chocolateyinstall.ps1.template) `
-replace '#VERSION#', "$version" `
-replace '#SHA#', (Get-FileHash .\artifacts\gsudoSetup.msi).Hash |
Out-File -encoding UTF8 .\build\Chocolatey\gsudo\tools\chocolateyinstall.ps1

# Generate Tools\VERIFICATION.txt
Get-Content .\Build\Chocolatey\verification.txt.template | Out-File -encoding UTF8 .\Build\Chocolatey\gsudo\Tools\VERIFICATION.txt

Expand Down
119 changes: 119 additions & 0 deletions build/Chocolatey/chocolateyinstall.ps1.template
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
function MarkFileDelete {
param(
[parameter(Mandatory=$true)]
[string] $path
)

Add-Type @'
using System;
using System.Text;
using System.Runtime.InteropServices;

public class Posh
{
public enum MoveFileFlags
{
MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004
}

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);

public static bool MarkFileDelete (string sourcefile)
{
return MoveFileEx(sourcefile, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
}
}
'@
$deleteResult = [Posh]::MarkFileDelete($path)

if ($deleteResult) {
write-Warning "(Delete of $path failed: Will be deleted at next boot.)"
} else {
write-Warning "(Error marking $path for deletion at next boot.)"
}
}

Import-Module (Join-Path (Split-Path -parent $MyInvocation.MyCommand.Definition) "Uninstall-ChocolateyPath.psm1")

# ********* Uninstall previous versions from $(Get-ToolsLocation)\gsudo

$installPath = "$(Get-ToolsLocation)\gsudo"
Uninstall-ChocolateyPath "$installPath\Current" 'Machine'

$ErrorActionPreference="Ignore"

# Delete symlinks in Pwsh 5.
Get-ChildItem $installPath -Recurse |? LinkType -eq 'SymbolicLink'|%{$_.Delete()}
# Delete the rest.
Remove-Item $installPath -Recurse -Force -ErrorAction Ignore
Remove-Item $installPath -Recurse -Force -ErrorAction Ignore

if (Test-Path $installPath) {
# Files are in use so delete failed.
# Rename used files and directories.

Get-ChildItem $installPath -Recurse -Exclude "*.deleteMe" | Sort-Object -Descending {(++$script:i)} | % { Rename-Item -Path $_.FullName -NewName ($_.Name + ".deleteMe") ; } *> $NULL
# Mark remaining for delete after restart.
Get-ChildItem $installPath -Recurse | % { MarkFileDelete ( $_.FullName) }
MarkFileDelete ( $installPath );
}

# ********* Install new versions using From GitHub's .MSI file. ** Based From Choco MSI Template.

$ErrorActionPreference = 'Stop';

$packageName= 'gsudo'
$toolsDir = "$(Split-Path -parent $MyInvocation.MyCommand.Definition)"
#$fileLocation = Join-Path $toolsDir 'NAME_OF_EMBEDDED_INSTALLER_FILE'

$packageArgs = @{
packageName = $packageName
unzipLocation = $toolsDir
fileType = 'MSI'
url = 'https://github.com/gerardog/gsudo/releases/download/v#VERSION#/gsudoSetup.msi' # download url, HTTPS preferred
url64bit = 'https://github.com/gerardog/gsudo/releases/download/v#VERSION#/gsudoSetup.msi' # 64bit URL here (HTTPS preferred) or remove - if installer contains both (very rare), use $url
# url = '[[Url]]' # download url, HTTPS preferred
# url64bit = '[[Url64]]' # 64bit URL here (HTTPS preferred) or remove - if installer contains both (very rare), use $url
#file = $fileLocation

softwareName = 'gsudo v*' #part or all of the Display Name as you see it in Programs and Features. It should be enough to be unique

checksum = '#SHA#'
checksumType = 'sha256' #default is md5, can also be sha1, sha256 or sha512
checksum64 = '#SHA#'
checksumType64= 'sha256'

silentArgs = "/qn /norestart" # ALLUSERS=1 DISABLEDESKTOPSHORTCUT=1 ADDDESKTOPICON=0 ADDSTARTMENU=0
validExitCodes= @(0, 3010, 1641)
}

#https://chocolatey.org/docs/helpers-install-chocolatey-package
Install-ChocolateyPackage @packageArgs
## If you are making your own internal packages (organizations), you can embed the installer or
## put on internal file share and use the following instead (you'll need to add $file to the above)
# https://chocolatey.org/docs/helpers-install-chocolatey-install-package
#Install-ChocolateyInstallPackage @packageArgs

# gsudo powershell module banner.
"";

Update-SessionEnvironment

$ErrorActionPreference = 'SilentlyContinue';

if (Get-Module gsudoModule) {
if ((Split-Path (Get-Module gsudoModule).Path -Parent) -ne (Split-Path (Get-Command gsudoModule.psd1). Source -Parent)) {
"IMPORTANT! Please update your `$PROFILE: Use the following gsudoModule path."
" Import-Module `'$((Get-Command gsudoModule.psd1).Source)`'"
}
} elseif (Get-Command gsudoModule.psd1) {
& {
"PowerShell users: To use enhanced gsudo and Invoke-Gsudo cmdlet, add the following line to your `$PROFILE"
" Import-Module `'$((Get-Command gsudoModule.psd1).Source)`'"
"Or run: "
" Get-Command gsudoModule.psd1 | % { Write-Output `"``nImport-Module ```"`$(`$_.Source)```"`" | Add-Content `$PROFILE }"
}

Write-Output "`nPlease restart your consoles to use gsudo.`n"
}
2 changes: 1 addition & 1 deletion build/Chocolatey/gsudo.nuspec.template
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
<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>
<tags>sudo for windows run elevated command runas powershell wsl</tags>
<summary>gsudo is a `sudo` for Windows with a similar user-experience as *nix sudo.</summary>
<description>
`gsudo` allows to run commands with elevated permissions within the current console.
Expand Down
Empty file.
6 changes: 0 additions & 6 deletions build/Chocolatey/gsudo/tools/chocolateybeforemodify.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,4 @@ if (Get-Process gsudo 2> $null) {
}
}

$ToolsLocation = Get-ToolsLocation
if ([System.Environment]::CurrentDirectory -like "$ToolsLocation*") {
Write-Output -Verbose "Changing directory to $ToolsLocation to ensure successfull install/upgrade."
Set-Location $ToolsLocation
}

$ErrorActionPreference = 'Continue'
55 changes: 0 additions & 55 deletions build/Chocolatey/gsudo/tools/chocolateyinstall.ps1

This file was deleted.

111 changes: 45 additions & 66 deletions build/Chocolatey/gsudo/tools/chocolateyuninstall.ps1
Original file line number Diff line number Diff line change
@@ -1,68 +1,47 @@
Import-Module (Join-Path (Split-Path -parent $MyInvocation.MyCommand.Definition) "Uninstall-ChocolateyPath.psm1")

function MarkFileDelete {
param(
[parameter(Mandatory=$true)]
[string] $path
)

# the code below has been used from
# https://blogs.technet.com/b/heyscriptingguy/archive/2013/10/19/weekend-scripter-use-powershell-and-pinvoke-to-remove-stubborn-files.aspx
# with inspiration from
# http://www.leeholmes.com/blog/2009/02/17/moving-and-deleting-really-locked-files-in-powershell/
# and error handling from
# https://blogs.technet.com/b/heyscriptingguy/archive/2013/06/25/use-powershell-to-interact-with-the-windows-api-part-1.aspx

Add-Type @'
using System;
using System.Text;
using System.Runtime.InteropServices;

public class Posh
{
public enum MoveFileFlags
{
MOVEFILE_DELAY_UNTIL_REBOOT = 0x00000004
}

[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern bool MoveFileEx(string lpExistingFileName, string lpNewFileName, MoveFileFlags dwFlags);

public static bool MarkFileDelete (string sourcefile)
{
return MoveFileEx(sourcefile, null, MoveFileFlags.MOVEFILE_DELAY_UNTIL_REBOOT);
}
$ErrorActionPreference = 'Stop'; # stop on all errors

$packageName = 'gsudo'
$softwareName = 'gsudo v*' #part or all of the Display Name as you see it in Programs and Features. It should be enough to be unique
$installerType = 'MSI'
$silentArgs = '/qb /norestart'
# https://msdn.microsoft.com/en-us/library/aa376931(v=vs.85).aspx
$validExitCodes = @(0, 3010, 1605, 1614, 1641)

$uninstalled = $false
# Get-UninstallRegistryKey is new to 0.9.10, if supporting 0.9.9.x and below,
# take a dependency on "chocolatey-uninstall.extension" in your nuspec file.
# This is only a fuzzy search if $softwareName includes '*'. Otherwise it is
# exact. In the case of versions in key names, we recommend removing the version
# and using '*'.
[array]$key = Get-UninstallRegistryKey -SoftwareName $softwareName

if ($key.Count -eq 1) {
$key | ForEach-Object {
$file = "$($_.UninstallString)"

if ($installerType -eq 'MSI') {
# The Product Code GUID is all that should be passed for MSI, and very
# FIRST, because it comes directly after /x, which is already set in the
# Uninstall-ChocolateyPackage msiargs (facepalm).
$silentArgs = "$($_.PSChildName) $silentArgs"

# Don't pass anything for file, it is ignored for msi (facepalm number 2)
# Alternatively if you need to pass a path to an msi, determine that and
# use it instead of the above in silentArgs, still very first
$file = ''
}
'@
$deleteResult = [Posh]::MarkFileDelete($path)

if ($deleteResult) {
write-Warning "(Delete of $path failed: Will be deleted at next boot.)"
} else {
write-Warning "(Error marking $path for deletion at next boot.)"
}
}


$installPath = "$(Get-ToolsLocation)\gsudo"
Uninstall-ChocolateyPath "$installPath\Current" 'Machine'

$ErrorActionPreference="Ignore"

# Delete symlinks in Pwsh 5.
Get-ChildItem $installPath -Recurse |? LinkType -eq 'SymbolicLink'|%{$_.Delete()}
# Delete the rest.
Remove-Item $installPath -Recurse -Force -ErrorAction Ignore
Remove-Item $installPath -Recurse -Force -ErrorAction Ignore

if (Test-Path $installPath) {
# Files are in use so delete failed.
# Rename used files and directories.

Get-ChildItem $installPath -Recurse -Exclude "*.deleteMe" | Sort-Object -Descending {(++$script:i)} | % { Rename-Item -Path $_.FullName -NewName ($_.Name + ".deleteMe") ; } *> $NULL
# Mark remaining for delete after restart.
Get-ChildItem $installPath -Recurse | % { MarkFileDelete ( $_.FullName) }
MarkFileDelete ( $installPath );
}

$ErrorActionPreference = 'Continue'
Uninstall-ChocolateyPackage -PackageName $packageName `
-FileType $installerType `
-SilentArgs "$silentArgs" `
-ValidExitCodes $validExitCodes `
-File "$file"
}
} elseif ($key.Count -eq 0) {
Write-Warning "$packageName has already been uninstalled by other means."
} elseif ($key.Count -gt 1) {
Write-Warning "$key.Count matches found!"
Write-Warning "To prevent accidental data loss, no programs will be uninstalled."
Write-Warning "Please alert package maintainer the following keys were matched:"
$key | ForEach-Object {Write-Warning "- $_.DisplayName"}
}
2 changes: 1 addition & 1 deletion docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const config = {
showReadingTime: true,
// Please change this to your repo.
editUrl:
'https://github.com/gerardog/gsudo/tree/docs/docs/blog/',
'https://github.com/gerardog/gsudo/tree/master/docs/blog/',
},
theme: {
customCss: require.resolve('./src/css/custom.css'),
Expand Down
Loading