Skip to content

Support exporting configuration and installing plug-in configuration #195

Description

@chenbihao

Support exporting configuration and installing plug-in configuration

This is more convenient for multiple computers to simultaneously configure directly

Activity

  1. DepressedOptimist commented on Jul 26, 2024

    @DepressedOptimist

    Duplicate(?) of #155?

    I have successfully exported settings manually a few times now, as confirmed in that discussion.

  2. iamLazyCode commented on Dec 30, 2024

    @iamLazyCode

    Duplicate(?) of #155?

    I have successfully exported settings manually a few times now, as confirmed in that discussion.

    hi , how did you backup manually ?

  3. DepressedOptimist commented on Dec 30, 2024

    @DepressedOptimist

    Duplicate(?) of #155?
    I have successfully exported settings manually a few times now, as confirmed in that discussion.

    hi , how did you backup manually ?

    https://github.com/ramensoftware/windhawk/discussions/155#discussioncomment-8495683

    Copy the following folders:

    • %ProgramData%\Windhawk\Engine\Mods
    • %ProgramData%\Windhawk\ModsSource

    To make things easier, I:

    1. Created a folder called "Windhawk Backup"
    2. Copied the ModsSource folder to it
    3. Added a subfolder called Engine
    4. Copied the Mods folder to the Engine subfolder.

    And, using REGEDIT, save the following key (I saved mine to my Windhawk Backup folder):

    • HKEY_LOCAL_MACHINE\SOFTWARE\Windhawk

    I did this when I was switching over to a new computer. Once I backed up the above from the old computer, I installed Windhawk on my new one, then:

    1. Copied the contents of my Windhawk Backup folder except the registry key to the Windhawk folder. When asked to replace something, clicked Replace or Okay.
    2. Double-clicked on the registry key to add it to the registry.

    This successfully migrated all the mods and settings to my new computer.

    **When using REGEDIT, be careful not to delete or modify anything. You only need to Save the key.

  4. iamLazyCode commented on Dec 30, 2024

    @iamLazyCode

    Duplicate(?) of #155?
    I have successfully exported settings manually a few times now, as confirmed in that discussion.

    hi , how did you backup manually ?

    https://github.com/ramensoftware/windhawk/discussions/155#discussioncomment-8495683

    Copy the following folders:

    • %ProgramData%\Windhawk\Engine\Mods
    • %ProgramData%\Windhawk\ModsSource

    To make things easier, I:

    1. Created a folder called "Windhawk Backup"
    2. Copied the ModsSource folder to it
    3. Added a subfolder called Engine
    4. Copied the Mods folder to the Engine subfolder.

    And, using REGEDIT, save the following key (I saved mine to my Windhawk Backup folder):

    • HKEY_LOCAL_MACHINE\SOFTWARE\Windhawk

    I did this when I was switching over to a new computer. Once I backed up the above from the old computer, I installed Windhawk on my new one, then:

    1. Copied the contents of my Windhawk Backup folder except the registry key to the Windhawk folder. When asked to replace something, clicked Replace or Okay.
    2. Double-clicked on the registry key to add it to the registry.

    This successfully migrated all the mods and settings to my new computer.

    **When using REGEDIT, be careful not to delete or modify anything. You only need to Save the key.

    you sir are awesome, thankyou il try this weekend need to reinstall windows ...thanks alot mate

  5. DovieW commented on Jan 10, 2025

    @DovieW

    i had o1 make a PS script to automate this a bit:
    https://chatgpt.com/share/6780d0de-c34c-800f-a7f4-5a3823bfbe2b

  6. boredwz commented on May 16, 2025

    @boredwz

    @DovieW Thank you for the script.
    I made a few changes and uploaded to Gist.

    & $([scriptblock]::Create((iwr -useb 'https://gist.githubusercontent.com/boredwz/5c8099ed46eda614257188c6efcbd6db/raw/windhawk-backup.ps1')))
    • Added an administrator check due to issues with accessing the Windhawk dir in ProgramData
    • The directory has been changed to user desktop
    • UPD. fixed admin elevation: iwr|iex -> & {scriptblock}

    * Tested on Windows 10, b19044.5737, AMD64

  7. akamienski commented on May 16, 2025

    @akamienski

    @DovieW Thank you for the script. I made a few changes and uploaded to Gist.

    iwr -useb 'https://gist.githubusercontent.com/boredwz/5c8099ed46eda614257188c6efcbd6db/raw/windhawk-backup.ps1' | iex

    * Added an administrator check due to issues with accessing the Windhawk dir in ProgramData
    
    * The directory has been changed to user desktop
    
    • Tested on Windows 10, b19044.5737

    Has this been tested for ARM version?

  8. boredwz commented on May 17, 2025

    @boredwz

    Has this been tested for ARM version?

    Unfortunately, no. I have an amd64 PC.
    But, in theory, it should work on ARM.

  9. akamienski commented on May 17, 2025

    @akamienski

    Has this been tested for ARM version?

    Unfortunately, no. I have an amd64 PC. But, in theory, it should work on ARM.

    will test it next week and let you know, as I've wrote similar script which worked for x64, but didn't for ARM.

  10. akamienski commented on May 27, 2025

    @akamienski

    Has this been tested for ARM version?

    Unfortunately, no. I have an amd64 PC. But, in theory, it should work on ARM.

    @boredwz Do I need to prepare seperate backup zip files for arm and x64? As I've imported the one from ARM and tried to apply for both, but only worked for ARM. Mods are listed, but just do not apply.

  11. boredwz commented on May 27, 2025

    @boredwz

    @akamienski,

    I've imported the one from ARM and tried to apply for both, but only worked for ARM. Mods are listed, but just do not apply.

    Some modifications may not work because the way they work differs between architectures.


    I've imported the one from ARM and tried to apply for both ... Mods are listed

    This means that the script was executed correctly.


    To find the differences between amd and arm, you can try the following:

    1. Install the same modifications on two systems (amd and arm)
    2. Find these keys in the registry:
      • HKEY_LOCAL_MACHINE\SOFTWARE\Windhawk
      • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Windhawk
    3. Compare
      or
      Export and compare as .reg files
  12. akamienski commented on May 30, 2025

    @akamienski

    @akamienski,

    I've imported the one from ARM and tried to apply for both, but only worked for ARM. Mods are listed, but just do not apply.

    Some modifications may not work because the way they work differs between architectures.

    I've imported the one from ARM and tried to apply for both ... Mods are listed

    This means that the script was executed correctly.

    To find the differences between amd and arm, you can try the following:

    1. Install the same modifications on two systems (amd and arm)

    2. Find these keys in the registry:

      • HKEY_LOCAL_MACHINE\SOFTWARE\Windhawk
      • HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Windhawk
    3. Compare
      or
      Export and compare as .reg files

    it worked, indeed the reg file was an issue, thanks

  13. lokize commented on Aug 13, 2025

    @lokize

    My small contribution:

    • Custom and check backup location: Changed the default backup path.
    • Timestamped filenames: Added date and time to the backup filename to avoid overwriting and help organize versions.
    • Interactive restore menu: Replaced static restore path with a dynamic list of available backups, allowing the user to select which one to restore.

    #requires -Version 5
    
    [CmdletBinding()]
    param()
    
    # Elevate to administrator
    iwr -useb 'https://gist.githubusercontent.com/boredwz/f7e908dd8d25cc8345ef2065e093d63c/raw/admin.ps1' | iex
    If (!(Admin)) {
        Write-Warning 'Administrator rights required.';'Press [Enter] or [Y] to run as Admin...'
        if([Console]::ReadKey($true).Key -match '^(Enter|Y)$') {Admin -Elevate $MyInvocation.Line};return
    }
    
    ###############################################################################
    #                            CONFIGURABLE VARIABLES                           #
    ###############################################################################
    
    # Ensure the backup destination folder exists
    $destinationFolder = "C:\Softwares\Windhawk\Backups"
    if (!(Test-Path $destinationFolder)) {
        New-Item -ItemType Directory -Path $destinationFolder -Force | Out-Null
    }
    
    # Final backup zip path with timestamp
    $timeStamp = (Get-Date -Format 'yyyyMMdd_HHmmss')
    $backupZipPath = Join-Path $destinationFolder "windhawk-backup_$timeStamp.zip"
    
    # Windhawk installation folder
    $windhawkRoot  = "C:\ProgramData\Windhawk"
    
    # Windhawk registry key
    $registryKey   = "HKLM:\SOFTWARE\Windhawk"
    
    ###############################################################################
    #                               HELPER FUNCTIONS                              #
    ###############################################################################
    
    function Test-WindhawkInstalled {
        param([string]$WindhawkFolder)
        return (Test-Path $WindhawkFolder)
    }
    
    function Do-Backup {
        param(
            [string]$WindhawkFolder,
            [string]$BackupPath,
            [string]$RegistryKey
        )
    
        Write-Host "`n--- Starting Windhawk backup ---" -ForegroundColor Cyan
    
        $timeStamp    = (Get-Date -Format 'yyyyMMddHHmmss')
        $backupFolder = Join-Path $env:TEMP ("WindhawkBackup_$timeStamp")
        New-Item -ItemType Directory -Path $backupFolder -Force | Out-Null
    
        $engineFolder = Join-Path $backupFolder "Engine"
        New-Item -ItemType Directory -Path $engineFolder -Force | Out-Null
    
        $modsSourceFolder = Join-Path $WindhawkFolder "ModsSource"
        $modsFolder       = Join-Path $WindhawkFolder "Engine\Mods"
    
        if (Test-Path $modsSourceFolder) {
            Write-Host "Copying ModsSource folder..."
            Copy-Item -Path $modsSourceFolder -Destination $backupFolder -Recurse -Force
        } else {
            Write-Warning "ModsSource folder not found at: $modsSourceFolder"
        }
    
        if (Test-Path $modsFolder) {
            Write-Host "Copying Engine\Mods folder..."
            Copy-Item -Path $modsFolder -Destination $engineFolder -Recurse -Force
        } else {
            Write-Warning "Mods folder not found at: $modsFolder"
        }
    
        Write-Host "Exporting Windhawk registry key..."
        $regExportFile = Join-Path $backupFolder "Windhawk.reg"
        reg export "HKLM\SOFTWARE\Windhawk" $regExportFile /y | Out-Null
    
        Write-Host "Compressing backup to: $BackupPath"
        Compress-Archive -Path (Join-Path $backupFolder '*') -DestinationPath $BackupPath -Force
    
        Write-Host "`nBackup completed successfully!"
        Write-Host "Backup archive saved to: $BackupPath"
    }
    
    function Do-Restore {
        param(
            [string]$WindhawkFolder,
            [string]$BackupPath,
            [string]$RegistryKey
        )
    
        Write-Host "`n--- Starting Windhawk restore ---" -ForegroundColor Cyan
    
        if (!(Test-Path $BackupPath)) {
            Write-Warning "Backup zip not found at: $BackupPath"
            return
        }
    
        $timeStamp     = (Get-Date -Format 'yyyyMMddHHmmss')
        $extractFolder = Join-Path $env:TEMP ("WindhawkRestore_$timeStamp")
        New-Item -ItemType Directory -Path $extractFolder -Force | Out-Null
    
        Write-Host "Extracting backup zip: $BackupPath"
        Expand-Archive -Path $BackupPath -DestinationPath $extractFolder -Force
    
        $modsSourceBackup = Join-Path $extractFolder "ModsSource"
        $modsBackup       = Join-Path $extractFolder "Engine\Mods"
        $regBackup        = Join-Path $extractFolder "Windhawk.reg"
    
        if (Test-Path $modsSourceBackup) {
            Write-Host "Copying ModsSource to Windhawk folder..."
            Copy-Item -Path $modsSourceBackup -Destination $WindhawkFolder -Recurse -Force
        } else {
            Write-Warning "ModsSource not found in backup."
        }
    
        if (Test-Path $modsBackup) {
            Write-Host "Copying Engine\Mods to Windhawk folder..."
            $engineFolder = Join-Path $WindhawkFolder "Engine"
            if (!(Test-Path $engineFolder)) {
                New-Item -ItemType Directory -Path $engineFolder -Force | Out-Null
            }
            Copy-Item -Path $modsBackup -Destination $engineFolder -Recurse -Force
        } else {
            Write-Warning "Mods folder not found in backup."
        }
    
        if (Test-Path $regBackup) {
            Write-Host "Importing Windhawk registry settings..."
            reg import $regBackup | Out-Null
        } else {
            Write-Warning "Windhawk registry file not found in backup."
        }
    
        Write-Host "`nRestore completed successfully!"
    }
    
    ###############################################################################
    #                                 MAIN SCRIPT                                 #
    ###############################################################################
    
    Write-Host "Checking if Windhawk is installed at: $windhawkRoot"
    
    if (!(Test-WindhawkInstalled -WindhawkFolder $windhawkRoot)) {
        Write-Warning "`nWindhawk folder not found at: $windhawkRoot"
        $choice = Read-Host "Windhawk might not be installed. Continue anyway? (y/n)"
        if ($choice -notmatch '^(y|Y)$') {
            Write-Host "Exiting."
            return
        }
    }
    
    Write-Host "`nWould you like to (B)ackup or (R)estore or (E)xit?"
    $action = Read-Host "Enter your choice (B/R/E)"
    
    switch ($action.ToUpper()) {
        'B' {
            Do-Backup -WindhawkFolder $windhawkRoot -BackupPath $backupZipPath -RegistryKey $registryKey
        }
        'R' {
            # List available backup files
            $backupFiles = Get-ChildItem -Path $destinationFolder -Filter "windhawk-backup_*.zip"
    
            if ($backupFiles.Count -eq 0) {
                Write-Warning "No backup files found in: $destinationFolder"
                return
            }
    
            Write-Host "`nAvailable backups:"
            $backupFiles | ForEach-Object -Begin { $i = 1 } -Process {
                Write-Host "$i. $($_.Name)"
                $i++
            }
    
            $selection = Read-Host "Enter the number of the backup you want to restore"
            if ($selection -match '^\d+$' -and $selection -ge 1 -and $selection -le $backupFiles.Count) {
                $selectedBackup = $backupFiles[$selection - 1].FullName
                Do-Restore -WindhawkFolder $windhawkRoot -BackupPath $selectedBackup -RegistryKey $registryKey
            } else {
                Write-Warning "Invalid selection. Exiting."
            }
        }
        'E' {
            Write-Host "Exiting script."
        }
        Default {
            Write-Host "Unrecognized choice. Exiting."
        }
    }
    
    Write-Host "`nDone."
    
  14. grngxd commented on Aug 20, 2025

    @grngxd

    is this still planned?

  15. m417z commented on Aug 20, 2025

    @m417z
    Member

    @grngxd yes, it's still planned.

  16. scorpion421 commented on Aug 26, 2025

    @scorpion421

    @lokize Thanks for the inspiration. I created something based on your idea:
    https://github.com/scorpion421/Windhawk-Services-Backup-Utility

    Have fun!

    Edit: I renamed the repo. Winhawk > Windhawk. To be fair: Winhawk also sounds very nice :D

    P.S.: The tool has grown to a more or less like management tool for backups/restores - 2.5.0 is now available.

    Image
  17. LiivaneLord commented on Mar 31, 2026

    @LiivaneLord

    Long story short - Is it enough to delete old

    Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Windhawk

    key and import my backup key? And then I just press update for all my mods to download latest version of each mod instead.

  18. piknockyou commented on May 11, 2026

    @piknockyou

    @lokize Thanks for the inspiration. I created something based on your idea: https://github.com/scorpion421/Windhawk-Services-Backup-Utility

    Hey @scorpion421 !
    I forked your excellent utility and essentially overhauled it to fit my workflow – great code base, thanks for sharing it!

    Image

    https://github.com/piknockyou/Windhawk-Services-Backup-Utility

    The reason is, when transferring my Windhawk configuration to a new machine, I ran into an issue where restored mods displayed raw, dashed file names instead of proper titles, lacked descriptions, and constantly prompted for manual updates. Through deep diagnostics, I discovered that Windhawk relies heavily on a local cache file (userprofile.json) to display UI metadata, and it also accumulates obsolete compiled mod DLLs indefinitely. Simply copying backup files over an existing installation merges them into this "dirty" state, causing hash mismatches and broken UI text.

    To solve this, I implemented a "Clean Existing State" feature that specifically targets and wipes the destination machine's userprofile.json, stale compiled DLLs, and old registry keys before applying the restore. By destroying this out-of-sync cache and laying down only the clean source code and base registry backup, Windhawk is forced to perform a clean initialization on startup: reading titles and descriptions freshly from the code headers. Paired with a new smart filter that automatically drops obsolete DLLs during the backup phase, the utility now guarantees every restore applies perfectly to a flawless, deterministic baseline.

    Here’s a quick summary of the other massive changelog additions in my version (compared to your v2.5.0):

    Mod State Management & Safety

    • Stale DLL Exclusion: Windhawk accumulates old compiled DLLs over time (e.g., multiple versions of the same mod). The backup process now analyzes these binaries and automatically excludes older, stale versions from the archive to keep restores clean.
    • "Clean Existing State" Tool: Added a dedicated maintenance button to wipe existing mod state (source files, compiled DLLs, registry keys) while preserving Windhawk's core runtime files. This guarantees a deterministic, clean baseline before a restore.
    • Architecture Validation: manifest.json now records "arch" (e.g. AMD64). On restore, it warns you if you try to restore a backup onto a mismatched CPU architecture.

    UI & UX Overhaul

    • Tooltips Everywhere: Built a custom lightweight Tooltip engine. Hovering over almost any element now explains exactly what it does.
    • Right-Click Context Menus & Hotkeys: The backup list now supports Right-Click menus (Restore, Delete, View Details, Open Folder) and native Delete key bindings.
    • Smart UI Memory & Autosizing: The app remembers your window size, maximized state, and custom column widths.
    • Flicker-Free Auto-Refresh: Auto-refresh now uses a silent background snapshot system, so the UI only updates if the files on disk actually change.
    • Advanced Logging: Added a toggleable Large Log window, a Verbose mode for deep diagnostics (logs every single file touched), live-updating log callbacks, and Copy/Clear/Export buttons.
    • Help & README UI: A built-in tabbed dialog explains exactly what files/registry keys are touched and details how the tool works under the hood.

    Portability & Under-the-Hood Fixes

    • Portable Configs: Config now lives right next to the script (migrates automatically from %appdata%).
    • Smart Pathing: If you select a backup folder in your user directory, it automatically converts it to %USERPROFILE%\... in the config so the app remains completely portable across different PCs. UI buttons added to quickly set the path to "Script" or "Desktop".
    • Smarter Root Detection: On startup, it probes several known Windows installation paths to auto-detect Windhawk if the saved path is missing.
    • .pyw Silent UAC Fix: Fixed an elevation bug so the script runs perfectly in windowless Python (.pyw) environments without UI console flashes.
    • Archive Enrichment: Backups now include the hostname in the filename (e.g. windhawk-backup_DESKTOP-ABC_AMD64_...zip).

    All of this is built on your solid core – I just wrapped it with deeper system checks, safer cleanup routines, and a layer of UI polish. You can find the code in my fork if you’re curious.

    Cheers, and thanks again for the original utility!

  19. m417z commented on Jul 27, 2026

    @m417z
    Member

    That's now available in Windhawk 2.0 alpha which can be downloaded here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions