|
Set-StrictMode -Version Latest |
|
$ErrorActionPreference = "Stop" |
|
|
|
function Get-LocalizedTitle { |
|
$Lang = [System.Globalization.CultureInfo]::CurrentUICulture.Name |
|
|
|
switch -Regex ($Lang) { |
|
'^zh-' { |
|
# avoid powershell 5 mojibake |
|
return [System.Text.Encoding]::UTF8.GetString([byte[]]( |
|
0xE9, 0x80, 0x9A, 0xE8, 0xBF, 0x87, 0x20, |
|
0x43, 0x6F, 0x64, 0x65, 0x20, |
|
0xE6, 0x89, 0x93, 0xE5, 0xBC, 0x80 |
|
)) |
|
} |
|
default { return "Open with Code" } |
|
} |
|
} |
|
|
|
$Title = Get-LocalizedTitle |
|
|
|
$Version = "3.0.4" |
|
|
|
$OsArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture.ToString().ToUpperInvariant() |
|
|
|
$ArchMap = @{ |
|
"X64" = "x64" |
|
"X86" = "x86" |
|
"ARM64" = "arm64" |
|
} |
|
|
|
$Arch = $ArchMap[$OsArch] |
|
|
|
if (-not $Arch) { |
|
throw "Unsupported architecture: $OsArch" |
|
} |
|
|
|
$ZipName = "code_explorer_${Arch}.zip" |
|
$DownloadUrl = "https://github.com/microsoft/vscode-explorer-command/releases/download/$Version/$ZipName" |
|
|
|
$VsCodeInstallPath = Join-Path $env:LOCALAPPDATA "Programs\Microsoft VS Code" |
|
|
|
if (-not (Test-Path $VsCodeInstallPath)) { |
|
throw "VSCode installation not found: $VsCodeInstallPath" |
|
} |
|
|
|
$ShellPath = Join-Path $VsCodeInstallPath "shell" |
|
$ZipPath = Join-Path $env:TEMP $ZipName |
|
|
|
|
|
function Set-DeveloperMode { |
|
$RegPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock" |
|
|
|
if (-not (Test-Path $RegPath)) { |
|
New-Item -Path $RegPath -Force | Out-Null |
|
} |
|
|
|
$Current = Get-ItemProperty -Path $RegPath -Name AllowDevelopmentWithoutDevLicense -ErrorAction SilentlyContinue |
|
|
|
if ($null -eq $Current) { |
|
New-ItemProperty ` |
|
-Path $RegPath ` |
|
-Name AllowDevelopmentWithoutDevLicense ` |
|
-PropertyType DWord ` |
|
-Value 1 ` |
|
-Force | Out-Null |
|
} |
|
elseif ($Current.AllowDevelopmentWithoutDevLicense -ne 1) { |
|
Set-ItemProperty ` |
|
-Path $RegPath ` |
|
-Name AllowDevelopmentWithoutDevLicense ` |
|
-Value 1 |
|
} |
|
} |
|
|
|
function Expand-CompatArchive { |
|
param( |
|
[Parameter(Mandatory)] |
|
[string]$Path, |
|
|
|
[Parameter(Mandatory)] |
|
[string]$Destination |
|
) |
|
|
|
if (Test-Path $Destination) { |
|
Remove-Item $Destination -Recurse -Force |
|
} |
|
|
|
New-Item ` |
|
-ItemType Directory ` |
|
-Path $Destination ` |
|
-Force | Out-Null |
|
|
|
$Extension = [System.IO.Path]::GetExtension($Path).ToLowerInvariant() |
|
|
|
$CanUseExpandArchive = |
|
$PSVersionTable.PSVersion.Major -ge 7 ` |
|
-or $Extension -eq ".zip" |
|
|
|
if ($CanUseExpandArchive) { |
|
Expand-Archive ` |
|
-Path $Path ` |
|
-DestinationPath $Destination ` |
|
-Force |
|
|
|
return |
|
} |
|
|
|
# PowerShell 5.x |
|
Add-Type -AssemblyName System.IO.Compression.FileSystem |
|
|
|
[System.IO.Compression.ZipFile]::ExtractToDirectory( |
|
$Path, |
|
$Destination |
|
) |
|
} |
|
|
|
|
|
Write-Host "Creating shell directory" -ForegroundColor Cyan |
|
|
|
New-Item ` |
|
-ItemType Directory ` |
|
-Path $ShellPath ` |
|
-Force | Out-Null |
|
|
|
|
|
Write-Host "Downloading package" -ForegroundColor Cyan |
|
|
|
Invoke-WebRequest ` |
|
-Uri $DownloadUrl ` |
|
-OutFile $ZipPath |
|
|
|
|
|
Write-Host "Extracting package" -ForegroundColor Cyan |
|
|
|
Expand-CompatArchive ` |
|
-Path $ZipPath ` |
|
-Destination $ShellPath |
|
|
|
|
|
$appxFile = Get-ChildItem ` |
|
-Path $ShellPath ` |
|
-Filter "*.appx" ` |
|
| Select-Object -First 1 |
|
|
|
if (-not $appxFile) { |
|
throw "No .appx file found." |
|
} |
|
|
|
Write-Host "Extracting AppX manifest files" -ForegroundColor Cyan |
|
|
|
$tempAppxExtract = Join-Path $env:TEMP "vscode_shell_appx_extract" |
|
|
|
if (Test-Path $tempAppxExtract) { |
|
Remove-Item $tempAppxExtract -Recurse -Force |
|
} |
|
|
|
Expand-CompatArchive ` |
|
-Path $appxFile.FullName ` |
|
-Destination $tempAppxExtract |
|
|
|
foreach ($file in @( |
|
"[Content_Types].xml", |
|
"AppxBlockMap.xml", |
|
"AppxManifest.xml" |
|
)) { |
|
Copy-Item ` |
|
-Path (Join-Path $tempAppxExtract $file) ` |
|
-Destination $ShellPath ` |
|
-Force |
|
} |
|
|
|
|
|
$ManifestPath = Join-Path $ShellPath "AppxManifest.xml" |
|
|
|
Write-Host "Patching AppxManifest publisher" -ForegroundColor Cyan |
|
|
|
$content = Get-Content ` |
|
-Path $ManifestPath ` |
|
-Raw |
|
|
|
$content = $content -replace ` |
|
'Publisher="CN=Microsoft Corporation, O=Microsoft Corporation, L=Redmond, S=Washington, C=US"', |
|
'Publisher="CN=Microslop Corporation, O=Microslop Corporation, L=Redmond, S=Washington, C=US"' |
|
|
|
Set-Content ` |
|
-Path $ManifestPath ` |
|
-Value $content ` |
|
-Encoding UTF8 |
|
|
|
|
|
Write-Host "Creating registry entries" -ForegroundColor Cyan |
|
|
|
$RegistryPath = "HKCU:\Software\Classes\VSCodeContextMenu" |
|
|
|
New-Item ` |
|
-Path $RegistryPath ` |
|
-Force | Out-Null |
|
|
|
New-ItemProperty ` |
|
-Path $RegistryPath ` |
|
-Name "Title" ` |
|
-Value $Title ` |
|
-PropertyType String ` |
|
-Force | Out-Null |
|
|
|
|
|
Write-Host "Ensuring Developer Mode is enabled" -ForegroundColor Cyan |
|
|
|
Set-DeveloperMode |
|
|
|
|
|
Write-Host "Registering AppX package" -ForegroundColor Cyan |
|
|
|
Add-AppxPackage ` |
|
-Path $ManifestPath ` |
|
-Register ` |
|
-ExternalLocation $ShellPath |
|
|
|
|
|
Write-Host "Restarting explorer.exe" -ForegroundColor Cyan |
|
|
|
Get-Process explorer -ErrorAction SilentlyContinue | Stop-Process -Force |
|
|
|
|
|
Write-Host "Installation completed." -ForegroundColor Green |