0

I'm new to any sort of programming at all and I've been working on this tool, but I've finally hit a wall. I've read every article, post, and watched every video I could find but runspaces just aren't making sense to me. All I'm trying to do is get the auto search function to run on separate thread to keep the main window from locking up. I've been stuck on this for so long now that I considered ditching Powershell to start learning Python, but I'd rather understand this than quit. I think I even understand how to set the function to run on a separate runspace but the specific part that I don't understand is how to run the UI in it's own runspace and have the two communicate. I've even tried using some boilerplate with a syncHash table but I could never get it working. I'd really appreciate any help before I go insane.

All Files:

https://mega.nz/folder/251yHaBJ#bHYNYdNfAmia5mEhE5IOKQ

Powershell script in question:

#Xaml import

    Add-Type -AssemblyName PresentationFramework
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    
    $xamlFile = "MainWindow.xaml"
    
    $inputXAML = Get-Content -Path $xamlFile -Raw
    $inputXAML = $inputXAML -replace 'mc:Ignorable="d"','' -replace "x:N","N" -replace '^<Win.*','<Window'
    [XML]$XAML = $inputXAML
    
    $reader = New-Object System.Xml.XmlNodeReader $XAML
    try {
        $psform = [Windows.Markup.XamlReader]::Load($reader)
        }
    catch {
        Write-Host $_.Exception
        throw
        }
    
    $xaml.SelectNodes("//*[@Name]") | ForEach-Object {
        try {
            Set-Variable -Name "var_$($_.Name)" -Value $psform.FindName($_.Name) -ErrorAction Stop
            }
        catch {
            throw
        }
    }
    
#Functions

    function autoSearch {
        $Drives = Get-PSDrive -PSProvider "FileSystem"
        $a1 = foreach ($Drive in $Drives) {Get-ChildItem -Path $Drive.Root -Recurse -ErrorAction SilentlyContinue -Directory -Filter "Steam"}
        $a2 = Get-ChildItem (Join-Path $a1.FullName "userdata") -ErrorAction SilentlyContinue -Directory
        $a3 = Get-ChildItem (Join-Path $a2.FullName "*") -ErrorAction SilentlyContinue -Directory -Filter "1446780"
        
        if ($a3) {
            $var_saveR.Foreground = "Green"
            $var_saveR.Content = "Found"
            $timer = New-Object System.Windows.Forms.Timer -Property @{
                Enabled = $true
                Interval = 3000
            }
            $timer.add_Tick({$var_saveR.Content = ""})
            $var_loc1.Content = $a3
            $filePath = "Config.txt"
            $lineNumber = "1"
            $fileContent = Get-Content $filePath
            $fileContent[$lineNumber-1] = $a3.FullName + "\*"
            $fileContent | Set-Content $filePath -Force
            }
        else {
            $var_saveR.Foreground = "Red"
            $var_saveR.Content = "Not Found"
            $timer = New-Object System.Windows.Forms.Timer -Property @{
                Enabled = $true
                Interval = 7000
            }
            $timer.add_Tick({$var_saveR.Content = ""})
            }
    }
    
    function manualSave {
        Add-Type -AssemblyName System.Windows.Forms
        $browser = New-Object System.Windows.Forms.FolderBrowserDialog
        $browser.ShowDialog()
        $var_loc1.Content = $browser.SelectedPath
        $filePath = "Config.txt"
        $lineNumber = "1"
        $fileContent = Get-Content $filePath
        $fileContent[$lineNumber-1] = $var_loc1.Content + "\*"
        $fileContent | Set-Content $filePath -Force
    }
    
    function manualBack {
        Add-Type -AssemblyName System.Windows.Forms
        $browser = New-Object System.Windows.Forms.FolderBrowserDialog
        $browser.ShowDialog()
        $var_loc2.Content = $browser.SelectedPath
        $filePath = "Config.txt"
        $lineNumber = "2"
        $fileContent = Get-Content $filePath
        $fileContent[$lineNumber-1] = $var_loc2.Content + "\*"
        $fileContent | Set-Content $filePath -Force
    }
    
    function backup {
        $file = "Config.txt"
        $a1 = Get-Content $file
        $a1[0]
        $a1[1]
        Copy-Item $a1[0] ($a1[1] -replace '\\\*','') -Recurse
        $var_backupStatus.Foreground = "Green"
        $var_backupStatus.Content = "Done"
        $timer = New-Object System.Windows.Forms.Timer -Property @{
            Enabled = $true
            Interval = 5000
        }
        $timer.add_Tick({$var_backupStatus.Content = ""})
    }
    
    function restore {
        $file = "Config.txt"
        $a1 = Get-Content $file
        $a1[0]
        $a1[1]
        Copy-Item $a1[1] ($a1[0] -replace '\\\*','') -Recurse #-Confirm
        $var_restoreStatus.Foreground = "Green"
        $var_restoreStatus.Content = "Done"
        $timer = New-Object System.Windows.Forms.Timer -Property @{
            Enabled = $true
            Interval = 5000
        }
        $timer.add_Tick({$var_restoreStatus.Content = ""})
    }
    
#UI

    $var_aSearchButton.Add_Click({autoSearch})
    $var_mSetButton1.Add_Click({manualSave})
    $var_mSetButton2.Add_Click({manualBack})
    $var_backupButton.Add_Click({backup})
    $var_restoreButton.Add_Click({restore})
    
    $var_loc1.Content = (Get-Content "Config.txt" -TotalCount 1)  -replace '\\\*',''
    $var_loc2.Content = (Get-Content "Config.txt" -TotalCount 2)[-1]  -replace '\\\*',''
    
    $psform.ShowDialog() | Out-Null
  • It probably doesn't make much over a difference whether you use Python or PowerShell. PowerShell has several commands as `Start-Job` to start a background job and can be fully integrated with .Net which allows you to use classes as the [`RusSpace` class](https://learn.microsoft.com/dotnet/api/system.management.automation.runspaces.runspace) in case you want more control over e.g. syncing information. I have created a minimal, reproducible example here: [Write PowerShell Output (as it happens) to WPF UI Control](https://stackoverflow.com/a/36716964/1701026) – iRon Jul 16 '22 at 10:07
  • Fellow SO user Foxdeploy has an excellent blog which covers this exact topic, see https://www.foxdeploy.com/ for more info. I'd also advise against mixing WPF with Winforms controlls as you are doing now (unless you're 100 sure what you're doing of course) – bluuf Jul 16 '22 at 11:16

0 Answers0