Compare commits

...

7 Commits

Author SHA1 Message Date
Gabi
72ad35bbd8 Remove product key from autounattend.xml (#4152) 2026-03-04 12:26:53 -06:00
Chris Titus
df17ca4695 Fix offline mode (#4153)
* Fix usb error on drive with no existing partitions

* fix offline mode

* Add offline banner
2026-03-04 12:21:18 -06:00
Chris Titus
7f46e8d60d Fix usb error on drive with no existing partitions (#4151) 2026-03-04 11:44:10 -06:00
Chris Titus
9769cafa7d change willshow ui (#4150) 2026-03-04 09:25:54 -06:00
Chris Titus
42dfc8c82b fix write failure on letter assignment from failed usb format 2026-03-04 09:21:39 -06:00
Gabi
d13295bdd8 Update start.ps1 (#4141) 2026-03-03 14:25:14 -06:00
Sean (ANGRYxScotsman)
5fc566b46f Winutil website edit (#4140)
* updated the iso creator docs

* added creator info to the arch docs
2026-03-03 09:17:19 -06:00
8 changed files with 249 additions and 69 deletions

View File

@@ -128,6 +128,154 @@ winutil/
- CheckBoxes for options - CheckBoxes for options
- ListBoxes for selections - ListBoxes for selections
## Win11 Creator Architecture
The **Win11 Creator** is a specialized subsystem within Winutil that creates customized Windows 11 ISOs. It operates independently from the main package installation and tweak system.
### Win11 Creator Components
**Core Functions** (`functions/private/`):
- `Invoke-WinUtilISO.ps1`: Main orchestrator containing all Win11 Creator functions
- `Invoke-WinUtilISOBrowse`: ISO file selection dialog
- `Invoke-WinUtilISOMountAndVerify`: Validates and mounts ISO, verifies it's official Windows 11
- `Invoke-WinUtilISOModify`: Launches modification in background runspace
- `Invoke-WinUtilISOExport`: Handles ISO and USB export
- `Invoke-WinUtilISOCheckExistingWork`: Recovers incomplete work sessions
- `Invoke-WinUtilISOCleanAndReset`: Cleans up temp directories and resets UI
- `Invoke-WinUtilISOScript.ps1`: Applies modifications to mounted install.wim
- Removes provisioned AppX packages (40+ bloatware apps)
- Injects drivers (optional) from current system
- Removes OneDrive setup files
- Applies offline registry tweaks (hardware bypass, privacy, telemetry, OOBE)
- Deletes telemetry scheduled task definitions
- Pre-stages setup scripts from autounattend.xml
- Removes unused Windows editions
- Cleans component store via DISM
### Win11 Creator Data Flow
```
User selects official Windows 11 ISO
Invoke-WinUtilISOBrowse → OpenFileDialog, validates file size
Invoke-WinUtilISOMountAndVerify
├─ Mount ISO via Mount-DiskImage
├─ Verify install.wim or install.esd exists
├─ Check for "Windows 11" in image metadata
├─ Extract available editions (Home, Pro, Enterprise, etc.)
└─ Store ISO path, drive letter, WIM path, image info in $sync
User optionally enables Driver Injection checkbox
Invoke-WinUtilISOModify (runs in background runspace)
├─ Create work directory: ~WinUtil_Win11ISO_[timestamp]
├─ Copy ISO contents to disk (~5-6 GB)
├─ Mount install.wim at selected edition/index
├─ Invoke-WinUtilISOScript:
│ ├─ Remove 40+ bloat AppX packages
│ ├─ Export and inject drivers (if enabled)
│ ├─ Remove OneDrive setup
│ ├─ Load offline registry hives
│ ├─ Apply 50+ registry tweaks (hardware bypass, privacy, telemetry, OOBE, etc.)
│ ├─ Delete telemetry scheduled task files
│ ├─ Pre-stage setup scripts from autounattend.xml to C:\Windows\Setup\Scripts\
│ └─ Unload registry hives
├─ DISM /Cleanup-Image /StartComponentCleanup /ResetBase (saves 300-800 MB)
├─ Dismount and save modified install.wim (~10+ minutes, slowest step)
├─ Export selected edition only (removes all other editions, saves 1-2 GB each)
├─ Dismount source ISO
└─ Report completion, enable export options
Invoke-WinUtilISOExport (user chooses output)
├─ Option 1: Save as ISO
│ ├─ Build bootable ISO via oscdimg.exe (BIOS/UEFI dual-boot)
│ └─ Output: Win11_Modified_[date].iso (2.5-3.5 GB)
└─ Option 2: Write to USB
├─ Format USB as GPT
├─ Create 512 MB EFI partition
├─ Copy modified ISO contents
└─ Output: Bootable USB (minimum 8 GB)
Invoke-WinUtilISOCleanAndReset (optional)
└─ Delete temp working directory (~10-15 GB)
└─ Reset UI to initial state
```
### Win11 Creator Validation & Safety
**ISO Validation**:
- Only accepts official Microsoft Windows 11 ISOs
- Validates presence of install.wim or install.esd
- Checks image metadata for "Windows 11" string
- Rejects custom, modified, or non-Windows 11 ISOs
**Work Session Recovery**:
- Auto-detects incomplete work from previous sessions
- Allows resuming Step 4 (export) without re-running Steps 1-3
- Prevents redundant modifications
**Modification Safety**:
- All registry changes are documented in script (reversible)
- Original ISO never modified; only working copy
- Logged to `WinUtil_Win11ISO.log` for debugging
- DISM handles image dismount with automatic cleanup on error
### Win11 Creator Registry Tweaks
The `Invoke-WinUtilISOScript` function applies **50+ offline registry tweaks**:
**Hardware Bypass**:
- TPM 2.0 check bypass
- Secure Boot requirement bypass
- CPU compatibility bypass
- RAM requirement bypass
- Storage check bypass
**Privacy & Telemetry**:
- Disable advertising ID
- Disable tailored experiences
- Disable input personalization
- Disable speech online privacy
- Disable cloud content suggestions
- Disable app suggestion subscriptions
- Remove CEIP, Appraiser, WaaSMedic, etc.
**OOBE & Setup**:
- Enable local account setup
- Skip Microsoft account requirement
- Dark mode by default
- Empty taskbar and Start Menu
**Post-Setup Installations**:
- Prevent DevHome auto-installation
- Prevent new Outlook Mail app installation
- Prevent Teams auto-installation
**System Features**:
- Disable BitLocker and device encryption
- Disable Chat icon from taskbar
- Disable OneDrive folder backup
- Disable Copilot
- Disable Windows Update during OOBE (re-enabled at first login)
### Driver Injection Feature
**Optional Enhancement**: When enabled, exports all drivers from the running system and injects them into both:
- `install.wim` (main OS image)
- `boot.wim` index 2 (Windows Setup PE environment)
**Use Case**: Enables offline installation on systems with missing drivers.
### Disk Space Requirements
- **Temporary working directory**: ~10-15 GB
- **Original ISO**: 4-6 GB
- **Modified ISO**: 2.5-3.5 GB
- **Total needed**: ~25 GB for safe operation
## Data Flow ## Data Flow
### Application Installation Flow ### Application Installation Flow
@@ -514,6 +662,7 @@ Outputs `winutil.ps1` in the root directory.
- [Contributing Guide](../../contributing/) - How to contribute code - [Contributing Guide](../../contributing/) - How to contribute code
- [User Guide](../../userguide/) - End-user documentation - [User Guide](../../userguide/) - End-user documentation
- [Win11 Creator Guide](../../userguide/win11Creator/) - Building customized Windows 11 ISOs
- [FAQ](../../faq/) - Common questions - [FAQ](../../faq/) - Common questions
## Additional Resources ## Additional Resources

View File

@@ -8,14 +8,14 @@ weight: 5
Winutil includes a built-in **Win11 Creator** tool that lets you take any official Windows 11 ISO and produce a customized, debloated version — with telemetry removed, hardware requirement checks bypassed, and local account setup enabled out of the box. You can export the result as a new ISO file or write it directly to a USB drive. Winutil includes a built-in **Win11 Creator** tool that lets you take any official Windows 11 ISO and produce a customized, debloated version — with telemetry removed, hardware requirement checks bypassed, and local account setup enabled out of the box. You can export the result as a new ISO file or write it directly to a USB drive.
> [!IMPORTANT] > [!IMPORTANT]
> You need a valid Windows 11 ISO before starting. Download one from [Microsoft's official site](https://www.microsoft.com/en-us/software-download/windows11) or use [UUP Dump](https://uupdump.net/). The process uses ~1015 GB of temporary disk space, so make sure you have room. > You need an **official Windows 11 ISO** from [Microsoft's website](https://www.microsoft.com/en-us/software-download/windows11) before starting. Custom, modified, or non-official ISOs are not supported. The process uses ~1015 GB of temporary disk space, so make sure you have room.
--- ---
### Step 1 — Select Your ISO ### Step 1 — Select Your Official Windows 11 ISO
1. Open Winutil and go to the **Win11 Creator** tab. 1. Open Winutil and go to the **Win11 Creator** tab.
2. Click **Browse** and select your Windows 11 ISO file (must be 4 GB or larger). 2. Click **Browse** and select your **official Windows 11 ISO file** from Microsoft (must be 4 GB or larger). Custom or modified ISOs are not supported.
3. The file path and size will appear on screen once selected. 3. The file path and size will appear on screen once selected.
--- ---
@@ -35,14 +35,31 @@ Winutil includes a built-in **Win11 Creator** tool that lets you take any offici
Click **Run Windows ISO Modification and Creator** to start the customization process. Winutil will: Click **Run Windows ISO Modification and Creator** to start the customization process. Winutil will:
**App & Component Removal:**
- **Remove 40+ bloat apps** — Clipchamp, Teams, Copilot, Dev Home, new Outlook, Bing apps, Solitaire, and more - **Remove 40+ bloat apps** — Clipchamp, Teams, Copilot, Dev Home, new Outlook, Bing apps, Solitaire, and more
- **Delete OneDrive setup** from the image - **Delete OneDrive setup** from the image
- **Apply registry tweaks** — disables telemetry, advertising ID, tailored experiences, and cloud content features
**System Customization:**
- **Bypass hardware checks** — removes TPM, Secure Boot, CPU, and RAM requirement enforcement so the ISO installs on unsupported hardware - **Bypass hardware checks** — removes TPM, Secure Boot, CPU, and RAM requirement enforcement so the ISO installs on unsupported hardware
- **Enable local account setup** — injects an `autounattend.xml` that skips the Microsoft account screen during OOBE - **Enable local account setup** — injects an `autounattend.xml` that skips the Microsoft account screen during OOBE
- **Disable BitLocker and device encryption** — removes startup overhead
- **Disable Chat icon** — removes chat taskbar button
- **Strip unused editions** — keeps only your selected edition, saving 12 GB per removed edition - **Strip unused editions** — keeps only your selected edition, saving 12 GB per removed edition
- **Clean the component store** — runs DISM cleanup to reclaim another 300800 MB - **Clean the component store** — runs DISM cleanup to reclaim another 300800 MB
**Privacy & Telemetry Tweaks:**
- **Disable telemetry** — advertising ID, tailored experiences, input personalization, speech online privacy
- **Disable cloud content features** — app suggestions, Microsoft Store recommendations
- **Remove telemetry scheduled tasks** — CEIP, Appraiser, WaaSMedic, and others - **Remove telemetry scheduled tasks** — CEIP, Appraiser, WaaSMedic, and others
- **Disable OneDrive folder backup** — prevents automatic backups to cloud
- **Prevent DevHome and Outlook post-setup installation**
- **Prevent Teams installation** — blocks auto-install after OOBE
- **Prevent new Outlook Mail app installation**
- **Disable Windows Update during OOBE** — re-enabled automatically on first login
- **Disable Copilot and search box suggestions**
**Optional: Driver Injection**
- If enabled, injects all drivers from your current system into the install.wim and boot.wim — useful for offline installations on machines with missing drivers. This is an optional checkbox in Step 3.
A live log shows progress as each step completes. This stage takes **1030 minutes** depending on your disk speed — the WIM dismount near the end is the slowest part, so don't close Winutil while it's running. A live log shows progress as each step completes. This stage takes **1030 minutes** depending on your disk speed — the WIM dismount near the end is the slowest part, so don't close Winutil while it's running.
@@ -94,9 +111,9 @@ When you install Windows 11 from your modified ISO:
- **No Microsoft account required** — create a local account directly during setup - **No Microsoft account required** — create a local account directly during setup
- **No hardware checks** — installs on machines without TPM 2.0, Secure Boot, or supported CPUs - **No hardware checks** — installs on machines without TPM 2.0, Secure Boot, or supported CPUs
- **Dark mode enabled by default** - **Dark mode enabled by default**
- **Empty taskbar and Start Menu** — no pinned apps - **Empty taskbar and Start Menu** — no pinned apps, Chat icon removed
- **Windows Update re-enabled automatically** after first login (it's paused during OOBE to prevent interruption) - **Windows Update disabled during OOBE** — automatically re-enabled on first login to prevent setup interruptions
- **BitLocker disabled**, Recall disabled, desktop shortcuts removed - **BitLocker disabled** — removes startup overhead on first boot
--- ---

View File

@@ -103,13 +103,24 @@ function Invoke-WinUtilISOWriteUSB {
try { try {
SetProgress "Formatting USB drive..." 10 SetProgress "Formatting USB drive..." 10
# Phase 1: Clean disk via diskpart # Phase 1: Clean disk via diskpart (retry once if the drive is not yet ready)
$dpFile1 = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt" $dpFile1 = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt"
"select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1 -Encoding ASCII "select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1 -Encoding ASCII
Log "Running diskpart clean on Disk $diskNum..." Log "Running diskpart clean on Disk $diskNum..."
diskpart /s $dpFile1 2>&1 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" } $dpCleanOut = diskpart /s $dpFile1 2>&1
$dpCleanOut | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" }
Remove-Item $dpFile1 -Force -ErrorAction SilentlyContinue Remove-Item $dpFile1 -Force -ErrorAction SilentlyContinue
if (($dpCleanOut -join ' ') -match 'device is not ready') {
Log "Disk $diskNum was not ready; waiting 5 seconds and retrying clean..."
Start-Sleep -Seconds 5
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
$dpFile1b = Join-Path $env:TEMP "winutil_diskpart_$(Get-Random).txt"
"select disk $diskNum`nclean`nexit" | Set-Content -Path $dpFile1b -Encoding ASCII
diskpart /s $dpFile1b 2>&1 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" }
Remove-Item $dpFile1b -Force -ErrorAction SilentlyContinue
}
# Phase 2: Initialize as GPT # Phase 2: Initialize as GPT
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
@@ -122,7 +133,8 @@ function Invoke-WinUtilISOWriteUSB {
Log "Disk $diskNum converted to GPT (was $($diskObj.PartitionStyle))." Log "Disk $diskNum converted to GPT (was $($diskObj.PartitionStyle))."
} }
# Phase 3: Create FAT32 partition via diskpart # Phase 3: Create FAT32 partition via diskpart, then format with Format-Volume
# (diskpart's 'format' command can fail with "no volume selected" on fresh/never-formatted drives)
$volLabel = "W11-" + (Get-Date).ToString('yyMMdd') $volLabel = "W11-" + (Get-Date).ToString('yyMMdd')
$dpFile2 = Join-Path $env:TEMP "winutil_diskpart2_$(Get-Random).txt" $dpFile2 = Join-Path $env:TEMP "winutil_diskpart2_$(Get-Random).txt"
$maxFat32PartitionMB = 32768 $maxFat32PartitionMB = 32768
@@ -136,28 +148,38 @@ function Invoke-WinUtilISOWriteUSB {
@( @(
"select disk $diskNum" "select disk $diskNum"
$createPartitionCommand $createPartitionCommand
"format quick fs=fat32 label=`"$volLabel`""
"exit" "exit"
) | Set-Content -Path $dpFile2 -Encoding ASCII ) | Set-Content -Path $dpFile2 -Encoding ASCII
Log "Creating partitions on Disk $diskNum..." Log "Creating partitions on Disk $diskNum..."
diskpart /s $dpFile2 2>&1 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" } diskpart /s $dpFile2 2>&1 | Where-Object { $_ -match '\S' } | ForEach-Object { Log " diskpart: $_" }
Remove-Item $dpFile2 -Force -ErrorAction SilentlyContinue Remove-Item $dpFile2 -Force -ErrorAction SilentlyContinue
SetProgress "Assigning drive letters..." 30 SetProgress "Formatting USB partition..." 25
Start-Sleep -Seconds 3 Start-Sleep -Seconds 3
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
$partitions = Get-Partition -DiskNumber $diskNum -ErrorAction Stop $partitions = Get-Partition -DiskNumber $diskNum -ErrorAction Stop
Log "Partitions on Disk $diskNum after format: $($partitions.Count)" Log "Partitions on Disk $diskNum after creation: $($partitions.Count)"
foreach ($p in $partitions) { foreach ($p in $partitions) {
Log " Partition $($p.PartitionNumber) Type=$($p.Type) Letter=$($p.DriveLetter) Size=$([math]::Round($p.Size/1MB))MB" Log " Partition $($p.PartitionNumber) Type=$($p.Type) Letter=$($p.DriveLetter) Size=$([math]::Round($p.Size/1MB))MB"
} }
$winpePart = $partitions | Where-Object { $_.Type -eq "Basic" } | Select-Object -Last 1 $winpePart = $partitions | Where-Object { $_.Type -eq "Basic" } | Select-Object -Last 1
if (-not $winpePart) { if (-not $winpePart) {
throw "Could not find the WINPE (Basic) partition on Disk $diskNum after format." throw "Could not find the Basic partition on Disk $diskNum after creation."
} }
# Format using Format-Volume (reliable on fresh drives; diskpart format fails
# with 'no volume selected' when the partition has never been formatted before)
Log "Formatting Partition $($winpePart.PartitionNumber) as FAT32 (label: $volLabel)..."
Get-Partition -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber |
Format-Volume -FileSystem FAT32 -NewFileSystemLabel $volLabel -Force -Confirm:$false | Out-Null
Log "Partition $($winpePart.PartitionNumber) formatted as FAT32."
SetProgress "Assigning drive letters..." 30
Start-Sleep -Seconds 2
Update-Disk -Number $diskNum -ErrorAction SilentlyContinue
try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" -ErrorAction SilentlyContinue } catch {} try { Remove-PartitionAccessPath -DiskNumber $diskNum -PartitionNumber $winpePart.PartitionNumber -AccessPath "$($winpePart.DriveLetter):" -ErrorAction SilentlyContinue } catch {}
$usbLetter = Get-FreeDriveLetter $usbLetter = Get-FreeDriveLetter
if (-not $usbLetter) { throw "No free drive letters (D-Z) available to assign to the USB data partition." } if (-not $usbLetter) { throw "No free drive letters (D-Z) available to assign to the USB data partition." }
@@ -166,6 +188,12 @@ function Invoke-WinUtilISOWriteUSB {
Start-Sleep -Seconds 2 Start-Sleep -Seconds 2
$usbDrive = "${usbLetter}:" $usbDrive = "${usbLetter}:"
$retries = 0
while (-not (Test-Path $usbDrive) -and $retries -lt 6) {
$retries++
Log "Waiting for $usbDrive to become accessible (attempt $retries/6)..."
Start-Sleep -Seconds 2
}
if (-not (Test-Path $usbDrive)) { throw "Drive $usbDrive is not accessible after letter assignment." } if (-not (Test-Path $usbDrive)) { throw "Drive $usbDrive is not accessible after letter assignment." }
Log "USB data partition: $usbDrive" Log "USB data partition: $usbDrive"

View File

@@ -1,26 +0,0 @@
function Test-WinUtilInternetConnection {
<#
.SYNOPSIS
Tests if the computer has internet connectivity
.OUTPUTS
Boolean - True if connected, False if offline
#>
try {
# Test multiple reliable endpoints
$testSites = @(
"8.8.8.8", # Google DNS
"1.1.1.1", # Cloudflare DNS
"208.67.222.222" # OpenDNS
)
foreach ($site in $testSites) {
if (Test-Connection -ComputerName $site -Count 1 -Quiet -ErrorAction SilentlyContinue) {
return $true
}
}
return $false
}
catch {
return $false
}
}

View File

@@ -15,12 +15,14 @@ $maxthreads = [int]$env:NUMBER_OF_PROCESSORS
$hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null $hashVars = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'sync',$sync,$Null
$debugVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'DebugPreference',$DebugPreference,$Null $debugVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'DebugPreference',$DebugPreference,$Null
$uiVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_NOUI',$PARAM_NOUI,$Null $uiVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_NOUI',$PARAM_NOUI,$Null
$offlineVar = New-object System.Management.Automation.Runspaces.SessionStateVariableEntry -ArgumentList 'PARAM_OFFLINE',$PARAM_OFFLINE,$Null
$InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault() $InitialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
# Add the variable to the session state # Add the variable to the session state
$InitialSessionState.Variables.Add($hashVars) $InitialSessionState.Variables.Add($hashVars)
$InitialSessionState.Variables.Add($debugVar) $InitialSessionState.Variables.Add($debugVar)
$InitialSessionState.Variables.Add($uiVar) $InitialSessionState.Variables.Add($uiVar)
$InitialSessionState.Variables.Add($offlineVar)
# Get every private function and add them to the session state # Get every private function and add them to the session state
$functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' } $functions = Get-ChildItem function:\ | Where-Object { $_.Name -imatch 'winutil|WPF' }
@@ -350,11 +352,10 @@ $sync["Form"].Add_ContentRendered({
Write-Debug "Unable to retrieve information about the primary monitor." Write-Debug "Unable to retrieve information about the primary monitor."
} }
# Check internet connectivity and disable install tab if offline if ($PARAM_OFFLINE) {
#$isOnline = Test-WinUtilInternetConnection # Show offline banner
$isOnline = $true # Temporarily force online mode until we can resolve false negatives $sync.WPFOfflineBanner.Visibility = [System.Windows.Visibility]::Visible
if (-not $isOnline) {
# Disable the install tab # Disable the install tab
$sync.WPFTab1BT.IsEnabled = $false $sync.WPFTab1BT.IsEnabled = $false
$sync.WPFTab1BT.Opacity = 0.5 $sync.WPFTab1BT.Opacity = 0.5

View File

@@ -9,7 +9,8 @@
param ( param (
[string]$Config, [string]$Config,
[switch]$Run, [switch]$Run,
[switch]$Noui [switch]$Noui,
[switch]$Offline
) )
if ($Config) { if ($Config) {
@@ -27,25 +28,10 @@ if ($Noui) {
$PARAM_NOUI = $true $PARAM_NOUI = $true
} }
# Load DLLs $PARAM_OFFLINE = $false
Add-Type -AssemblyName PresentationFramework if ($Offline) {
Add-Type -AssemblyName System.Windows.Forms $PARAM_OFFLINE = $true
}
# Variable to sync between runspaces
$sync = [Hashtable]::Synchronized(@{})
$sync.PSScriptRoot = $PSScriptRoot
$sync.version = "#{replaceme}"
$sync.configs = @{}
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
$sync.preferences = @{}
$sync.ProcessRunning = $false
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
$sync.selectedTweaks = [System.Collections.Generic.List[string]]::new()
$sync.selectedToggles = [System.Collections.Generic.List[string]]::new()
$sync.selectedFeatures = [System.Collections.Generic.List[string]]::new()
$sync.currentTab = "Install"
$sync.selectedAppsStackPanel
$sync.selectedAppsPopup
if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) { if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
@@ -80,6 +66,26 @@ if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]:
break break
} }
# Load DLLs
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName System.Windows.Forms
# Variable to sync between runspaces
$sync = [Hashtable]::Synchronized(@{})
$sync.PSScriptRoot = $PSScriptRoot
$sync.version = "#{replaceme}"
$sync.configs = @{}
$sync.Buttons = [System.Collections.Generic.List[PSObject]]::new()
$sync.preferences = @{}
$sync.ProcessRunning = $false
$sync.selectedApps = [System.Collections.Generic.List[string]]::new()
$sync.selectedTweaks = [System.Collections.Generic.List[string]]::new()
$sync.selectedToggles = [System.Collections.Generic.List[string]]::new()
$sync.selectedFeatures = [System.Collections.Generic.List[string]]::new()
$sync.currentTab = "Install"
$sync.selectedAppsStackPanel
$sync.selectedAppsPopup
$dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss" $dateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
# Set the path for the winutil directory # Set the path for the winutil directory

View File

@@ -6,8 +6,7 @@
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<UserData> <UserData>
<ProductKey> <ProductKey>
<Key>00000-00000-00000-00000-00000</Key> <WillShowUI>Never</WillShowUI>
<WillShowUI>Always</WillShowUI>
</ProductKey> </ProductKey>
<AcceptEula>true</AcceptEula> <AcceptEula>true</AcceptEula>
</UserData> </UserData>

View File

@@ -943,13 +943,19 @@
</Window.Resources> </Window.Resources>
<Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Name="WPFMainGrid" Width="Auto" Height="Auto" HorizontalAlignment="Stretch"> <Grid Background="{DynamicResource MainBackgroundColor}" ShowGridLines="False" Name="WPFMainGrid" Width="Auto" Height="Auto" HorizontalAlignment="Stretch">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Grid Grid.Row="0" Background="{DynamicResource MainBackgroundColor}"> <!-- Offline banner -->
<Border Name="WPFOfflineBanner" Grid.Row="0" Background="#8B0000" Visibility="Collapsed" Padding="6,4">
<TextBlock Text="&#x26A0; Offline Mode - No Internet Connection" Foreground="White" FontWeight="Bold"
HorizontalAlignment="Center" FontSize="13" Background="Transparent"/>
</Border>
<Grid Grid.Row="1" Background="{DynamicResource MainBackgroundColor}">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <!-- Navigation buttons --> <ColumnDefinition Width="Auto"/> <!-- Navigation buttons -->
<ColumnDefinition Width="*"/> <!-- Search bar and buttons --> <ColumnDefinition Width="*"/> <!-- Search bar and buttons -->
@@ -1192,7 +1198,7 @@
</Grid> </Grid>
</Grid> </Grid>
<TabControl Name="WPFTabNav" Background="Transparent" Width="Auto" Height="Auto" BorderBrush="Transparent" BorderThickness="0" Grid.Row="1" Grid.Column="0" Padding="-1"> <TabControl Name="WPFTabNav" Background="Transparent" Width="Auto" Height="Auto" BorderBrush="Transparent" BorderThickness="0" Grid.Row="2" Grid.Column="0" Padding="-1">
<TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1"> <TabItem Header="Install" Visibility="Collapsed" Name="WPFTab1">
<Grid Background="Transparent" > <Grid Background="Transparent" >