Launch-DevPackageInSandbox.ps1 (7060B)
1 Param( 2 [Parameter(HelpMessage = "The directory where local dev build is located; only the release build works.")] 3 [String] $DevPackagePath 4 ) 5 6 $ErrorActionPreference = "Stop" 7 8 # Validate that the local dev manifest exists 9 10 if (-not $DevPackagePath) 11 { 12 $DevPackagePath = Join-Path $PSScriptRoot "..\..\src\AppInstallerCLIPackage\bin\x64\Release\AppX" 13 } 14 15 $DevPackagePath = [System.IO.Path]::GetFullPath($DevPackagePath) 16 17 if ($DevPackagePath.ToLower().Contains("debug")) 18 { 19 Write-Error -Category InvalidArgument -Message @" 20 The Debug dev package does not work for unknown reasons. 21 Use the Release build or figure out how to make debug work and fix the scripts. 22 "@ 23 } 24 25 if (-not (Test-Path (Join-Path $DevPackagePath "AppxManifest.xml"))) 26 { 27 Write-Error -Category InvalidArgument -Message @" 28 AppxManifest.xml does not exist in the path $DevPackagePath 29 Either build the local dev package, or provide the location using -DevPackagePath 30 "@ 31 } 32 33 # Check if Windows Sandbox is enabled 34 35 if (-Not (Get-Command 'WindowsSandbox' -ErrorAction SilentlyContinue)) 36 { 37 Write-Error -Category NotInstalled -Message @' 38 Windows Sandbox does not seem to be available. Check the following URL for prerequisites and further details: 39 https://docs.microsoft.com/windows/security/threat-protection/windows-sandbox/windows-sandbox-overview 40 41 You can run the following command in an elevated PowerShell for enabling Windows Sandbox: 42 $ Enable-WindowsOptionalFeature -Online -FeatureName 'Containers-DisposableClientVM' 43 '@ 44 } 45 46 # Close Windows Sandbox 47 48 function Close-WindowsSandbox { 49 $sandbox = Get-Process 'WindowsSandboxClient' -ErrorAction SilentlyContinue 50 if ($sandbox) 51 { 52 Write-Host '--> Closing Windows Sandbox' 53 54 $sandboxServer = Get-Process 'WindowsSandbox' -ErrorAction SilentlyContinue 55 56 $sandbox | Stop-Process 57 $sandbox | Wait-Process -Timeout 120 58 59 # Also wait for the server to close 60 if ($sandboxServer) 61 { 62 try 63 { 64 $sandboxServer | Wait-Process -Timeout 120 65 } 66 catch [System.TimeoutException] 67 { 68 # Force stop the server if it does not automatically stop 69 $sandboxServer | Stop-Process 70 $sandboxServer | Wait-Process -Timeout 120 71 } 72 73 } 74 75 Write-Host 76 } 77 Remove-Variable sandbox 78 } 79 80 Close-WindowsSandbox 81 82 # Initialize Temp Folder 83 84 $tempFolderName = 'DevInSandboxStaging' 85 $tempFolder = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $tempFolderName 86 87 New-Item $tempFolder -ItemType Directory -ErrorAction SilentlyContinue | Out-Null 88 89 # Set dependencies 90 91 $desktopInSandbox = 'C:\Users\WDAGUtilityAccount\Desktop' 92 93 [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 94 $WebClient = New-Object System.Net.WebClient 95 96 # Hide the progress bar of Invoke-WebRequest 97 $oldProgressPreference = $ProgressPreference 98 $ProgressPreference = 'SilentlyContinue' 99 100 $ProgressPreference = $oldProgressPreference 101 102 $vcLibsUwp = @{ 103 fileName = 'Microsoft.VCLibs.x64.14.00.Desktop.appx' 104 url = 'https://aka.ms/Microsoft.VCLibs.x64.14.00.Desktop.appx' 105 hash = '9BFDE6CFCC530EF073AB4BC9C4817575F63BE1251DD75AAA58CB89299697A569' 106 folderInLocal = Join-Path ${env:ProgramFiles(x86)} "Microsoft SDKs\Windows Kits\10\ExtensionSDKs\Microsoft.VCLibs.Desktop\14.0\Appx\Retail\x64" 107 } 108 109 $dependencies = @($vcLibsUwp) 110 111 # Clean temp directory 112 113 Get-ChildItem $tempFolder -Recurse -Exclude $dependencies.fileName | Remove-Item -Force -Recurse 114 115 # Download dependencies 116 117 Write-Host '--> Checking dependencies' 118 119 foreach ($dependency in $dependencies) 120 { 121 $dependency.pathInSandbox = Join-Path -Path $desktopInSandbox -ChildPath (Join-Path -Path $tempFolderName -ChildPath $dependency.fileName) 122 123 # First see if the file exists locally to copy instead of downloading 124 if ($dependency.folderInLocal -ne $null) 125 { 126 $dependencyFilePath = Join-Path -Path $dependency.folderInLocal -ChildPath $dependency.fileName 127 if (Test-Path -Path $dependencyFilePath -PathType Leaf) 128 { 129 $dependencyFilePath 130 $tempFolder 131 Copy-Item -Path $dependencyFilePath -Destination $tempFolder -Force 132 continue 133 } 134 } 135 136 # File does not exist locally, we need to download 137 138 $dependency.file = Join-Path -Path $tempFolder -ChildPath $dependency.fileName 139 140 # Only download if the file does not exist, or its hash does not match. 141 if (-Not ((Test-Path -Path $dependency.file -PathType Leaf) -And $dependency.hash -eq $(Get-FileHash $dependency.file).Hash)) 142 { 143 Write-Host @" 144 - Downloading: 145 $($dependency.url) 146 "@ 147 148 try 149 { 150 $WebClient.DownloadFile($dependency.url, $dependency.file) 151 } 152 catch 153 { 154 #Pass the exception as an inner exception 155 throw [System.Net.WebException]::new("Error downloading $($dependency.url).",$_.Exception) 156 } 157 if (-not ($dependency.hash -eq $(Get-FileHash $dependency.file).Hash)) 158 { 159 throw [System.Activities.VersionMismatchException]::new('Dependency hash does not match the downloaded file') 160 } 161 } 162 } 163 164 # Copy main script 165 166 $mainPs1FileName = 'InSandboxScript.ps1' 167 Copy-Item (Join-Path $PSScriptRoot $mainPs1FileName) (Join-Path $tempFolder $mainPs1FileName) 168 169 $dependenciesPathsInSandbox = "@('$($vcLibsUwp.pathInSandbox)')" 170 $bootstrapPs1Content = ".\$mainPs1FileName -DesktopAppInstallerDependencyPath @($dependenciesPathsInSandbox)" 171 172 $bootstrapPs1FileName = 'Bootstrap.ps1' 173 $bootstrapPs1Content | Out-File (Join-Path $tempFolder $bootstrapPs1FileName) -Force 174 175 # Create Windows Sandbox configuration file 176 177 $bootstrapPs1InSandbox = Join-Path -Path $desktopInSandbox -ChildPath (Join-Path -Path $tempFolderName -ChildPath $bootstrapPs1FileName) 178 $tempFolderInSandbox = Join-Path -Path $desktopInSandbox -ChildPath $tempFolderName 179 180 $devPackageInSandbox = Join-Path -Path $desktopInSandbox -ChildPath "DevPackage" 181 $devPackageXMLFragment = "" 182 183 $devPackageXMLFragment = @" 184 <MappedFolder> 185 <HostFolder>$DevPackagePath</HostFolder> 186 <SandboxFolder>$devPackageInSandbox</SandboxFolder> 187 </MappedFolder> 188 "@ 189 190 $sandboxTestWsbContent = @" 191 <Configuration> 192 <MappedFolders> 193 <MappedFolder> 194 <HostFolder>$tempFolder</HostFolder> 195 <ReadOnly>true</ReadOnly> 196 </MappedFolder> 197 $devPackageXMLFragment 198 </MappedFolders> 199 <LogonCommand> 200 <Command>PowerShell Start-Process PowerShell -WindowStyle Maximized -WorkingDirectory '$tempFolderInSandbox' -ArgumentList '-ExecutionPolicy Bypass -NoExit -NoLogo -File $bootstrapPs1InSandbox'</Command> 201 </LogonCommand> 202 </Configuration> 203 "@ 204 205 $sandboxTestWsbFileName = 'SandboxTest.wsb' 206 $sandboxTestWsbFile = Join-Path -Path $tempFolder -ChildPath $sandboxTestWsbFileName 207 $sandboxTestWsbContent | Out-File $sandboxTestWsbFile -Force 208 209 Write-Host @" 210 --> Starting Windows Sandbox 211 $sandboxTestWsbFile 212 "@ 213 214 Write-Host 215 216 WindowsSandbox $SandboxTestWsbFile