Core/DependencyManager.ps1

# Core\DependencyManager.ps1
# Handles WebView2 detection and installation

function Test-WebView2Installed {
    <#
    .SYNOPSIS
        Check if WebView2 DLLs are available.
    #>

    $nugetPath  = "$env:LOCALAPPDATA\PackageManagement\NuGet\Packages"
    $wv2Package = Get-ChildItem $nugetPath -Filter "Microsoft.Web.WebView2*" -Directory -ErrorAction SilentlyContinue |
                  Sort-Object Name -Descending | Select-Object -First 1

    if (-not $wv2Package) { return $false }

    $net462  = Join-Path $wv2Package.FullName "extracted\lib\net462"
    $coreDll = Join-Path $net462 "Microsoft.Web.WebView2.Core.dll"
    $wfDll   = Join-Path $net462 "Microsoft.Web.WebView2.WinForms.dll"
    $loader  = Join-Path $net462 "WebView2Loader.dll"

    if ((Test-Path $coreDll) -and (Test-Path $wfDll) -and (Test-Path $loader)) {
        $script:PoshDE.WebView2DllPath = $net462
        return $true
    }

    return $false
}

function Test-PoshDependencies {
    <#
    .SYNOPSIS
        Test whether all PoshDE dependencies are satisfied.
    .OUTPUTS
        [bool]
    #>

    [CmdletBinding()]
    param()

    $script:PoshDE.WebView2Ready = Test-WebView2Installed
    return $script:PoshDE.WebView2Ready
}

function Get-PoshDependencyStatus {
    <#
    .SYNOPSIS
        Return a detailed status object for all PoshDE dependencies.
    #>

    [CmdletBinding()]
    param()

    $wv2Ready = Test-WebView2Installed

    $version = $null
    if ($wv2Ready) {
        $pkg = Get-ChildItem "$env:LOCALAPPDATA\PackageManagement\NuGet\Packages" `
                   -Filter "Microsoft.Web.WebView2*" -Directory -ErrorAction SilentlyContinue |
               Sort-Object Name -Descending | Select-Object -First 1
        # Package folder is named e.g. Microsoft.Web.WebView2.1.0.2849.39
        if ($pkg) { $version = ($pkg.Name -split 'WebView2\.')[-1] }
    }

    [PSCustomObject]@{
        WebView2 = [PSCustomObject]@{
            Installed = $wv2Ready
            Version   = $version
            DllPath   = $script:PoshDE.WebView2DllPath
        }
        ConfigPath = $script:PoshDE.AppDataPath
    }
}

function Get-WebView2DllPath {
    <#
    .SYNOPSIS
        Return the path to the WebView2 DLL folder.
    .DESCRIPTION
        Used by Posh apps to load WebView2 assemblies.
        Runs Install-PoshDependencies automatically if needed.
    #>

    [CmdletBinding()]
    param()

    if (-not $script:PoshDE.WebView2Ready) {
        if (-not (Test-WebView2Installed)) {
            Write-Warning "WebView2 not found. Running Install-PoshDependencies..."
            Install-PoshDependencies
        }
    }

    return $script:PoshDE.WebView2DllPath
}

function Install-PoshDependencies {
    <#
    .SYNOPSIS
        Download and configure all PoshDE dependencies.
    .DESCRIPTION
        Downloads the Microsoft.Web.WebView2 NuGet package directly from
        the NuGet API (no package source registration required) and extracts
        the .NET Framework 4.6.2 DLLs required by the WebView2 subprocess.
    #>

    [CmdletBinding()]
    param()

    Write-Host ""
    Write-Host " Installing PoshDE dependencies..." -ForegroundColor Cyan
    Write-Host ""

    # ── Resolve latest WebView2 version from NuGet API ──────────────────────
    Write-Host " [1/3] Resolving latest WebView2 version..." -ForegroundColor Yellow
    try {
        $indexUrl  = "https://api.nuget.org/v3-flatcontainer/microsoft.web.webview2/index.json"
        $index     = Invoke-RestMethod -Uri $indexUrl -ErrorAction Stop
        $wv2Version = $index.versions | Where-Object { $_ -notmatch '-' } | Select-Object -Last 1

        if (-not $wv2Version) { throw "Could not determine latest version." }
        Write-Host " v$wv2Version" -ForegroundColor Green
    } catch {
        Write-Host " FAILED: $_" -ForegroundColor Red
        return
    }

    # ── Download .nupkg directly ─────────────────────────────────────────────
    Write-Host " [2/3] Downloading package..." -ForegroundColor Yellow
    try {
        $pkgName    = "microsoft.web.webview2"
        $nupkgUrl   = "https://api.nuget.org/v3-flatcontainer/$pkgName/$wv2Version/$pkgName.$wv2Version.nupkg"

        $destDir    = "$env:LOCALAPPDATA\PackageManagement\NuGet\Packages\Microsoft.Web.WebView2.$wv2Version"
        $nupkgPath  = Join-Path $destDir "Microsoft.Web.WebView2.$wv2Version.nupkg"
        $extractPath = Join-Path $destDir "extracted"

        if (-not (Test-Path $destDir)) {
            New-Item -Path $destDir -ItemType Directory -Force | Out-Null
        }

        if (-not (Test-Path $nupkgPath)) {
            Invoke-WebRequest -Uri $nupkgUrl -OutFile $nupkgPath -ErrorAction Stop
        }
        Write-Host " OK" -ForegroundColor Green
    } catch {
        Write-Host " FAILED: $_" -ForegroundColor Red
        return
    }

    # ── Extract and configure DLLs ───────────────────────────────────────────
    Write-Host " [3/3] Extracting and configuring DLLs..." -ForegroundColor Yellow
    try {
        if (-not (Test-Path $extractPath)) {
            Add-Type -AssemblyName System.IO.Compression.FileSystem
            [System.IO.Compression.ZipFile]::ExtractToDirectory($nupkgPath, $extractPath)
        }

        # Copy the native loader into the net462 folder so Add-Type can find it
        $net462     = Join-Path $extractPath "lib\net462"
        $loaderSrc  = Join-Path $extractPath "runtimes\win-x64\native\WebView2Loader.dll"
        $loaderDest = Join-Path $net462 "WebView2Loader.dll"

        if ((Test-Path $loaderSrc) -and -not (Test-Path $loaderDest)) {
            Copy-Item $loaderSrc $loaderDest -Force
        }
        Write-Host " OK" -ForegroundColor Green
    } catch {
        Write-Host " FAILED: $_" -ForegroundColor Red
        return
    }

    # ── Verify ──────────────────────────────────────────────────────────────
    Write-Host ""
    if (Test-WebView2Installed) {
        $script:PoshDE.WebView2Ready = $true
        Write-Host " Dependencies ready." -ForegroundColor Green
        Write-Host " DLL path: $($script:PoshDE.WebView2DllPath)" -ForegroundColor DarkGray
    } else {
        Write-Host " Installation finished but verification failed." -ForegroundColor Red
        Write-Host " Try running Get-PoshDependencyStatus for details." -ForegroundColor DarkGray
    }
    Write-Host ""
}

Write-Verbose "DependencyManager loaded"