another try

This commit is contained in:
Justin Bailey
2023-02-16 18:12:39 -05:00
parent 6a8fb722e1
commit ff1c67063d
+95 -65
View File
@@ -12,7 +12,7 @@ The URL of the Microsoft Store page for the app to download.
The root directory where the downloaded files should be saved. The default value is "%tmp%".
.EXAMPLE
pwsh .\msix_downloader.ps1 -StoreURL https://www.microsoft.com/store/productId/9NCB4Z0TZ6RR
pwsh .\msix_downloader.ps1 -StoreURL "https://www.microsoft.com/store/productId/9NCB4Z0TZ6RR"
Downloads the Microsoft Solitaire Collection app and its dependencies from the Microsoft Store, and saves the files to the default directory.
@@ -37,90 +37,120 @@ param (
$ErrorActionPreference = "Stop"
$ErrorMessage = ""
if ($StoreURL.EndsWith("/")) {
$StoreURL = $StoreURL.Substring(0, $StoreURL.Length - 1)
}
# Query the API to get the download links for the app
$wc = [System.Net.WebClient]::new()
$URI = "https://store.rg-adguard.net/api/GetFiles"
$myParameters = "type=url&url=$($StoreURL)"
$wc.Headers[[System.Net.HttpRequestHeader]::ContentType] = "application/x-www-form-urlencoded"
$HtmlResult = $wc.UploadString($URI, $myParameters)
# Parse the HTML response to get the download links
$start = $HtmlResult.IndexOf("<p>The links were successfully received from the Microsoft Store server.</p>")
if ($start -eq -1) {
throw "Could not get the links, please check the StoreURL."
}
$tableEnd = ($HtmlResult.LastIndexOf("</table>") + 8)
$semiCleaned = $HtmlResult.Substring($start, $tableEnd - $start)
$newHtml = New-Object -ComObject "HTMLFile"
try {
# Remove trailing slash from Store URL, if any
if ($StoreURL.EndsWith("/")) {
$StoreURL = $StoreURL.Remove($StoreUrl.Length - 1, 1)
}
# This works in PowerShell with Office installed
$newHtml.IHTMLDocument2_write($semiCleaned)
}
catch {
# This works when Office is not installed
$src = [System.Text.Encoding]::Unicode.GetBytes($semiCleaned)
$newHtml.write($src)
}
# Query the API to get the download links for the app
$wc = [System.Net.WebClient]::new()
$URI = "https://store.rg-adguard.net/api/GetFiles"
$myParameters = "type=url&url=$($StoreURL)"
$wc.Headers[[System.Net.HttpRequestHeader]::ContentType] = "application/x-www-form-urlencoded"
$HtmlResult = $wc.UploadString($URI, $myParameters)
$toDownload = $newHtml.getElementsByTagName("a") | Select-Object textContent, href
# Parse the HTML response to get the download links
$start = $HtmlResult.IndexOf("<p>The links were successfully received from the Microsoft Store server.</p>")
if ($start -eq -1) {
throw "Could not get the links, please check the StoreURL."
}
# Create the directory to save the downloaded files
$SavePathRoot = $([System.Environment]::ExpandEnvironmentVariables("$SavePathRoot"))
$lastFrontSlash = $StoreURL.LastIndexOf("/")
$productID = $StoreURL.Substring($lastFrontSlash + 1, $StoreURL.Length - $lastFrontSlash - 1)
$path = Join-Path $SavePathRoot $productID
$tableEnd = ($HtmlResult.LastIndexOf("</table>") + 8)
$semiCleaned = $HtmlResult.Substring($start, $tableEnd - $start)
if ($StoreURL.EndsWith("/")) {
$StoreURL = $StoreURL.Substring(0, $StoreURL.Length - 1)
}
# Query the API to get the download links for the app
$wc = [System.Net.WebClient]::new()
$URI = "https://store.rg-adguard.net/api/GetFiles"
$myParameters = "type=url&url=$($StoreURL)"
$wc.Headers[[System.Net.HttpRequestHeader]::ContentType] = "application/x-www-form-urlencoded"
$HtmlResult = $wc.UploadString($URI, $myParameters)
$newHtml = New-Object -ComObject "HTMLFile"
try {
# This works in PowerShell with Office installed
$newHtml.IHTMLDocument2_write($semiCleaned)
}
catch {
# This works when Office is not installed
$src = [System.Text.Encoding]::Unicode.GetBytes($semiCleaned)
$newHtml.write($src)
}
# Parse the HTML response to get the download links
$start = $HtmlResult.IndexOf("<p>The links were successfully received from the Microsoft Store server.</p>")
if ($start -eq -1) {
throw "Could not get the links, please check the StoreURL."
}
$toDownload = $newHtml.getElementsByTagName("a") | Select-Object textContent, href
$tableEnd = ($HtmlResult.LastIndexOf("</table>") + 8)
$semiCleaned = $HtmlResult.Substring($start, $tableEnd - $start)
# Create the directory to save the downloaded files
$SavePathRoot = $([System.Environment]::ExpandEnvironmentVariables("$SavePathRoot"))
$lastFrontSlash = $StoreURL.LastIndexOf("/")
$productID = $StoreURL.Substring($lastFrontSlash + 1, $StoreURL.Length - $lastFrontSlash - 1)
$path = Join-Path $SavePathRoot $productID
$newHtml = New-Object -ComObject "HTMLFile"
try {
# This works in PowerShell with Office installed
$newHtml.IHTMLDocument2_write($semiCleaned)
}
catch {
# This works when Office is not installed
$src = [System.Text.Encoding]::Unicode.GetBytes($semiCleaned)
$newHtml.write($src)
}
if (!(Test-Path $path)) {
New-Item -ItemType Directory $path -ErrorAction Stop | Out-Null
Write-Verbose "Created directory $path."
}
# Download the files
$totalSize = $toDownload | Measure-Object -Property href -Sum | Select-Object -ExpandProperty Sum
$currentSize = 0
foreach ($download in $toDownload) {
$toDownload = $newHtml.getElementsByTagName("a") | Select-Object textContent, href
# Create the directory to save the downloaded files
$SavePathRoot = $([System.Environment]::ExpandEnvironmentVariables("$SavePathRoot"))
$lastFrontSlash = $StoreURL.LastIndexOf("/")
$productID = $StoreURL.Substring($lastFrontSlash + 1, $StoreURL.Length - $lastFrontSlash - 1)
$path = Join-Path $SavePathRoot $productID
if (!(Test-Path $path)) {
New-Item -ItemType Directory $path -ErrorAction Stop | Out-Null
Write-Verbose "Created directory $path."
}
# Download the files
$currentSize = 0
$totalSize = $toDownload | Where-Object { $_.href -match '\d+' } | Measure-Object -Property href -Sum | Select-Object -ExpandProperty Sum
foreach ($download in $toDownload) {
# Check if the href is a number before downloading
if ($download.href -match '\d+') {
$downloadPath = Join-Path $path $download.textContent
$progressLabel = "Downloading $($download.textContent)..."
$progressPercentage = [math]::Round(($currentSize / $totalSize) * 100, 0)
Write-Progress -Activity "Downloading files" -Status $progressLabel -PercentComplete $progressPercentage
try {
$wc.DownloadFile($download.href, $downloadPath)
Write-Verbose "Downloaded $($download.textContent) to $downloadPath."
# Get the file size and add it to the current size
$contentLength = $wc.ResponseHeaders["Content-Length"]
if ($null -ne $contentLength -and $contentLength -is [int]) {
$currentSize += $contentLength
}
else {
Write-Warning "Could not get the size of $($download.textContent)."
}
}
catch {
$ErrorMessage = "Failed to download $($download.textContent): $_"
Write-Error $ErrorMessage
}
$currentSize += $wc.ResponseHeaders["Content-Length"]
}
# Open the directory where the files were saved
Write-Verbose "Download complete. Opening directory $path."
Start-Sleep -Seconds 3
Start $path
}
catch {
$ErrorMessage = "An error occurred while downloading the app: $_"
Write-Error $ErrorMessage
}
finally {
# Clean up
$wc.Dispose()
}
if ($ErrorMessage -ne "") {
throw $ErrorMessage
}
# Open the directory where the files were saved
Write-Verbose "Download complete. Opening directory $path."