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

You don't need Visual Studio, just Windows 10 SDK #2

Open
NotSoCheezy opened this issue Sep 19, 2020 · 10 comments
Open

You don't need Visual Studio, just Windows 10 SDK #2

NotSoCheezy opened this issue Sep 19, 2020 · 10 comments

Comments

@NotSoCheezy
Copy link

https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk/

@xtcrefugee
Copy link

I just tried this, unfortunately even with all options checked it did not download MakeAppx.exe etc. required for this script.

@blacklightpy
Copy link

I just tried this, unfortunately even with all options checked it did not download MakeAppx.exe etc. required for this script.

It is apparently in Windows App Certification Kit
https://stackoverflow.com/questions/38755063/what-part-of-windows-10-sdk-do-i-need-to-install-to-get-makeappx-exe

@blacklightpy
Copy link

blacklightpy commented May 20, 2021

I just tried this, unfortunately even with all options checked it did not download MakeAppx.exe etc. required for this script.

I tried it myself and found the fix!

Made some changes to the script (just changed the locations)

[CmdletBinding()]
param (
	[Parameter(Mandatory=$True)]
	[string] $WSAppPath,

	[Parameter(Mandatory=$True)]
	[string] $WSAppOutputPath,

	[Parameter(Mandatory=$True)]
	[string] $WSTools,
	
	[Parameter(Mandatory=$True)]
	[string] $arch
)

function Run-Process {
	Param ($p, $a)
	$pinfo = New-Object System.Diagnostics.ProcessStartInfo
	$pinfo.FileName = $p
	$pinfo.Arguments = $a
	$pinfo.RedirectStandardError = $true
	$pinfo.RedirectStandardOutput = $true
	$pinfo.UseShellExecute = $false
	$p = New-Object System.Diagnostics.Process
	$p.StartInfo = $pinfo
	$p.Start() | Out-Null
	$output = $p.StandardOutput.ReadToEnd()
	$output += $p.StandardError.ReadToEnd()
	$p.WaitForExit()
	return $output
}

# find tools
$FileExists = Test-Path "$WSTools\App Certification Kit\MakeAppx.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: MakeAppx.exe not found in WSTools path."
	Exit
}
$FileExists = Test-Path "$WSTools\bin\10.0.19041.0\$arch\MakeCert.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: MakeCert.exe not found in WSTools path."
	Exit
}
$FileExists = Test-Path "$WSTools\bin\10.0.19041.0\$arch\Pvk2Pfx.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: Pvk2Pfx.exe not found in WSTools path."
	Exit
}
$FileExists = Test-Path "$WSTools\App Certification Kit\SignTool.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: SignTool.exe not found in WSTools path."
	Exit
}

$WSAppXmlFile="AppxManifest.xml"

# read manifest
Write-Output "Reading ""$WSAppPath\$WSAppXmlFile"""
$FileExists = Test-Path "$WSAppPath\$WSAppXmlFile"
if ($FileExists -eq $False) {
	Write-Output "ERROR: Windows Store manifest not found."
	Exit
}
[xml]$manifest = Get-Content "$WSAppPath\$WSAppXmlFile"
$WSAppName = $manifest.Package.Identity.Name
$WSAppPublisher = $manifest.Package.Identity.Publisher
Write-Output "  App Name : $WSAppName"
Write-Output "  Publisher: $WSAppPublisher"

# prepare
$WSAppFileName = gi $WSAppPath | select basename
$WSAppFileName = $WSAppFileName.BaseName

Write-Output "Creating ""$WSAppOutputPath\$WSAppFileName.appx""."
if (Test-Path "$WSAppOutputPath\$WSAppFileName.appx") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.appx"
}
$proc = "$WSTools\App Certification Kit\MakeAppx.exe"
$args = "pack /d ""$WSAppPath"" /p ""$WSAppOutputPath\$WSAppFileName.appx"" /l"
$output = Run-Process $proc $args
if ($output -inotlike "*succeeded*") {
	Write-Output "  ERROR: Appx creation failed!"
	Write-Output "  proc = $proc"
	Write-Output "  args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Write-Output "Creating self-signed certificates."
Write-Output "  Click NONE in the 'Create Private Key Passsword' pop-up."
if (Test-Path "$WSAppOutputPath\$WSAppFileName.pvk") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.pvk"
}
if (Test-Path "$WSAppOutputPath\$WSAppFileName.cer") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.cer"
}
$proc = "$WSTools\bin\10.0.19041.0\$arch\MakeCert.exe"
$args = "-n ""$WSAppPublisher"" -r -a sha256 -len 2048 -cy end -h 0 -eku 1.3.6.1.5.5.7.3.3 -b 01/01/2000 -sv ""$WSAppOutputPath\$WSAppFileName.pvk"" ""$WSAppOutputPath\$WSAppFileName.cer"""
$output = Run-Process $proc $args
if ($output -inotlike "*succeeded*") {
	Write-Output "ERROR: Certificate creation failed!"
	Write-Output "proc = $proc"
	Write-Output "args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Write-Output "Converting certificate to pfx."
if (Test-Path "$WSAppOutputPath\$WSAppFileName.pfx") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.pfx"
}
$proc = "$WSTools\bin\10.0.19041.0\$arch\Pvk2Pfx.exe"
$args = "-pvk ""$WSAppOutputPath\$WSAppFileName.pvk"" -spc ""$WSAppOutputPath\$WSAppFileName.cer"" -pfx ""$WSAppOutputPath\$WSAppFileName.pfx"""
$output = Run-Process $proc $args
if ($output.Length -gt 0) {
	Write-Output "  ERROR: Certificate conversion to pfx failed!"
	Write-Output "  proc = $proc"
	Write-Output "  args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Write-Output "Signing the package."
$proc = "$WSTools\App Certification Kit\SignTool.exe"
$args = "sign -fd SHA256 -a -f ""$WSAppOutputPath\$WSAppFileName.pfx"" ""$WSAppOutputPath\$WSAppFileName.appx"""
$output = Run-Process $proc $args
if ($output -inotlike "*successfully signed*") {
	Write-Output "ERROR: Package signing failed!"
	Write-Output $output.Length
	Write-Output "proc = $proc"
	Write-Output "args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Remove-Item "$WSAppOutputPath\$WSAppFileName.pvk"
Remove-Item "$WSAppOutputPath\$WSAppFileName.pfx"

Write-Output "Success!"
Write-Output "  App Package: ""$WSAppOutputPath\$WSAppFileName.appx"""
Write-Output "  Certificate: ""$WSAppOutputPath\$WSAppFileName.cer"""
Write-Output "Install the '.cer' file to [Local Computer\Trusted Root Certification Authorities] before you install the App Package."
Exit

And the input statement should be

PS C:\Users\Blacklight> .\Appx-Backup.ps1 -WSAppPath "C:\Program Files\WindowsApps\SpotifyAB.SpotifyMusic_1.158.820.0_x86__zpdnekdrzrea0" -WSAppOutputPath "C:\Users\Blacklight\Onedrive\Desktop\Spotify64\" -WSTools "C:\Program Files (x86)\Windows Kits\10\" -arch "x64"

I added an extra arch parameter to switch between x86 and x64 tools, and also note the change in the WSTools path.

@superbonaci
Copy link

@NotSoCheezyTech is right, please update README.

@DJ8014
Copy link

DJ8014 commented Oct 29, 2021

I found that all the needed tools (Makeappx.exe, Signtool.exe, and Pvk2pfx.exe) were installed by installing just these 3 packages from the Windows SDK:

Windows SDK Desktop Tools x64-x86_en-us.msi
Windows SDK for Windows Store Apps Tools-x86_en-us.msi
Windows SDK Signing Tools-x86_en-us.msi

As noted elsewhere, you need to adjust the WSTools path in your command to include the build number. For me (on Windows 11), it was:
C:\Program Files (x86)\Windows Kits\10\bin\10.0.22000.0\x64

@PeachPiesky
Copy link

Hey, pardon the newb question here. I'm trying this with an app and don't understand what the arch input should be, could someone fill me in?
And besides running the whole script above, where does the Input statement go?
Thanks!

@blacklightpy
Copy link

Hey, pardon the newb question here. I'm trying this with an app and don't understand what the arch input should be, could someone fill me in? And besides running the whole script above, where does the Input statement go? Thanks!

I don't remember this exactly, but I think you just have to run the script like I posted, and use the input statement I gave.

@yeet-dot-org
Copy link

Hey, pardon the newb question here. I'm trying this with an app and don't understand what the arch input should be, could someone fill me in? And besides running the whole script above, where does the Input statement go? Thanks!

I don't remember this exactly, but I think you just have to run the script like I posted, and use the input statement I gave.

i get ERROR: MakeCert.exe not found in WSTools path.

@Starworshipp3r
Copy link

Hey, pardon the newb question here. I'm trying this with an app and don't understand what the arch input should be, could someone fill me in? And besides running the whole script above, where does the Input statement go? Thanks!

I don't remember this exactly, but I think you just have to run the script like I posted, and use the input statement I gave.

i get ERROR: MakeCert.exe not found in WSTools path.

The latest build of the Windows 10 SDK changes the folder names.

In my case, the code provided targeted: $WSTools\bin\10.0.19041.0\$arch\MakeCert.exe

When it should be:
$WSTools\bin\10.0.22621.0\$arch\MakeCert.exe

Since 10.0.22621.0 is the latest versioned folder.

Here is the full updated code:

[CmdletBinding()]
param (
	[Parameter(Mandatory=$True)]
	[string] $WSAppPath,

	[Parameter(Mandatory=$True)]
	[string] $WSAppOutputPath,

	[Parameter(Mandatory=$True)]
	[string] $WSTools,
	
	[Parameter(Mandatory=$True)]
	[string] $arch
)

function Run-Process {
	Param ($p, $a)
	$pinfo = New-Object System.Diagnostics.ProcessStartInfo
	$pinfo.FileName = $p
	$pinfo.Arguments = $a
	$pinfo.RedirectStandardError = $true
	$pinfo.RedirectStandardOutput = $true
	$pinfo.UseShellExecute = $false
	$p = New-Object System.Diagnostics.Process
	$p.StartInfo = $pinfo
	$p.Start() | Out-Null
	$output = $p.StandardOutput.ReadToEnd()
	$output += $p.StandardError.ReadToEnd()
	$p.WaitForExit()
	return $output
}

# find tools
$FileExists = Test-Path "$WSTools\App Certification Kit\makeappx.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: MakeAppx.exe not found in WSTools path."
	Exit
}
$FileExists = Test-Path "$WSTools\bin\10.0.22621.0\$arch\MakeCert.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: MakeCert.exe not found in WSTools path."
	Exit
}
$FileExists = Test-Path "$WSTools\bin\10.0.22621.0\$arch\pvk2pfx.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: Pvk2Pfx.exe not found in WSTools path."
	Exit
}
$FileExists = Test-Path "$WSTools\App Certification Kit\signtool.exe"
if ($FileExists -eq $False) {
	Write-Output "ERROR: SignTool.exe not found in WSTools path."
	Exit
}

$WSAppXmlFile="AppxManifest.xml"

# read manifest
Write-Output "Reading ""$WSAppPath\$WSAppXmlFile"""
$FileExists = Test-Path "$WSAppPath\$WSAppXmlFile"
if ($FileExists -eq $False) {
	Write-Output "ERROR: Windows Store manifest not found."
	Exit
}
[xml]$manifest = Get-Content "$WSAppPath\$WSAppXmlFile"
$WSAppName = $manifest.Package.Identity.Name
$WSAppPublisher = $manifest.Package.Identity.Publisher
Write-Output "  App Name : $WSAppName"
Write-Output "  Publisher: $WSAppPublisher"

# prepare
$WSAppFileName = gi $WSAppPath | select basename
$WSAppFileName = $WSAppFileName.BaseName

Write-Output "Creating ""$WSAppOutputPath\$WSAppFileName.appx""."
if (Test-Path "$WSAppOutputPath\$WSAppFileName.appx") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.appx"
}
$proc = "$WSTools\App Certification Kit\makeappx.exe"
$args = "pack /d ""$WSAppPath"" /p ""$WSAppOutputPath\$WSAppFileName.appx"" /l"
$output = Run-Process $proc $args
if ($output -inotlike "*succeeded*") {
	Write-Output "  ERROR: Appx creation failed!"
	Write-Output "  proc = $proc"
	Write-Output "  args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Write-Output "Creating self-signed certificates."
Write-Output "  Click NONE in the 'Create Private Key Passsword' pop-up."
if (Test-Path "$WSAppOutputPath\$WSAppFileName.pvk") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.pvk"
}
if (Test-Path "$WSAppOutputPath\$WSAppFileName.cer") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.cer"
}
$proc = "$WSTools\bin\10.0.22621.0\$arch\MakeCert.exe"
$args = "-n ""$WSAppPublisher"" -r -a sha256 -len 2048 -cy end -h 0 -eku 1.3.6.1.5.5.7.3.3 -b 01/01/2000 -sv ""$WSAppOutputPath\$WSAppFileName.pvk"" ""$WSAppOutputPath\$WSAppFileName.cer"""
$output = Run-Process $proc $args
if ($output -inotlike "*succeeded*") {
	Write-Output "ERROR: Certificate creation failed!"
	Write-Output "proc = $proc"
	Write-Output "args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Write-Output "Converting certificate to pfx."
if (Test-Path "$WSAppOutputPath\$WSAppFileName.pfx") {
	Remove-Item "$WSAppOutputPath\$WSAppFileName.pfx"
}
$proc = "$WSTools\bin\10.0.22621.0\$arch\pvk2pfx.exe"
$args = "-pvk ""$WSAppOutputPath\$WSAppFileName.pvk"" -spc ""$WSAppOutputPath\$WSAppFileName.cer"" -pfx ""$WSAppOutputPath\$WSAppFileName.pfx"""
$output = Run-Process $proc $args
if ($output.Length -gt 0) {
	Write-Output "  ERROR: Certificate conversion to pfx failed!"
	Write-Output "  proc = $proc"
	Write-Output "  args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Write-Output "Signing the package."
$proc = "$WSTools\App Certification Kit\signtool.exe"
$args = "sign -fd SHA256 -a -f ""$WSAppOutputPath\$WSAppFileName.pfx"" ""$WSAppOutputPath\$WSAppFileName.appx"""
$output = Run-Process $proc $args
if ($output -inotlike "*successfully signed*") {
	Write-Output "ERROR: Package signing failed!"
	Write-Output $output.Length
	Write-Output "proc = $proc"
	Write-Output "args = $args"
	Write-Output ("  " + $output)
	Exit
}
Write-Output "  Done."

Remove-Item "$WSAppOutputPath\$WSAppFileName.pvk"
Remove-Item "$WSAppOutputPath\$WSAppFileName.pfx"

Write-Output "Success!"
Write-Output "  App Package: ""$WSAppOutputPath\$WSAppFileName.appx"""
Write-Output "  Certificate: ""$WSAppOutputPath\$WSAppFileName.cer"""
Write-Output "Install the '.cer' file to [Local Computer\Trusted Root Certification Authorities] before you install the App Package."
Exit

@mjmeans
Copy link
Owner

mjmeans commented May 7, 2024

If you want to contribute, fork this repo, make and test your changes in a new branch in your fork, and then submit a pull request. Any change will need to be backward compatible, so if you want it to be MakeCert version agnostic within 10,0,x,y, you will need to either add code to properly detect the currently installed versions, or perhaps allow the user to specify the version number in a parameter in order to override the default location in the script.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants