Search code examples
powershellbatch-filegithubffmpegchocolatey

Restart environment and script during batch script


I've built a few FFmpeg powershell scripts for me and a few others to use and I'm attempting to make the setup and update process as easy as possible. The end goal is to be able to run 1 batch file that installs Chocolatey, FFmpeg, git, clones the github repo (for updates), and edits the Windows registry to add the actual FFmpeg powershell scripts / console programs to the Windows Explorer contextual menu. This way I just pass them the folder containing everything once and any time I change or add something to the project I can just tell them to run the batch file again, and presto everything is up to date.

However I'm struggling to find a way to install Chocolatey, then git with Chocolatey, and then run a git command with the execution of a single .bat file. From what I can tell after installing Chocolatey I need to restart the shell entirely before I can install git, and then I have to restart the shell again before I can use a git command. As of right now most of the actual processing is happening via Powershell scripts that are launched from the .bat file, and as each step is taken I update a txt file, attempt to restart the batch script, and read the txt file to pick up where I left off:

@echo off
echo Administrative permissions required. Detecting permissions...
echo.

net session >nul 2>&1
if %errorLevel% == 0 (
    echo Success: Administrative permissions confirmed.
    echo.
) else (
    echo Failure: Current permissions inadequate.

    PAUSE

    exit
)

set relativePath=%~dp0
set relativePath=%relativePath:~0,-1%

PowerShell -NoProfile -ExecutionPolicy Bypass -File "%relativePath%\Setup\CheckRequiredPackages.ps1" -relativePath "%relativePath%"

set /p step=<"%relativePath%\Setup\Step.txt"

if %step% == 1 (
    (echo 2) > "%relativePath%\Setup\Step.txt"

    PowerShell -NoProfile -ExecutionPolicy Bypass -File "%relativePath%\Setup\GetChocolatey.ps1"

    start "" "%relativePath%\RunMe.bat"

    exit
) 

if %step% == 2 (
    (echo 3) > "%relativePath%\Setup\Step.txt"

    PowerShell -NoProfile -ExecutionPolicy Bypass -File "%relativePath%\Setup\GetRequiredPackages.ps1"

    start "" "%relativePath%\RunMe.bat"

    exit
) 

if %step% == 3 (
    (echo 0) > "%relativePath%\Setup\Step.txt"

    PowerShell -NoProfile -ExecutionPolicy Bypass -File "%relativePath%\Setup\Update.ps1" -relativePath "%relativePath%"
) 

PAUSE
Exit

The problem is using the start command in the batch script doesn't seem to work, I'm guessing since that new process is spawned from the same process that handles the Chocolatey install it doesn't count as actually restarting the shell. Is there any way to actually restart the shell and somehow have the batch file start back up without user intervention?


Solution

  • I'm not sure why I didn't initially think of reloading the path environment variable but that's a whole lot more reasonable than restarting the script 4 times with an intermediary file.

    Firstly I moved 99% of the heavy lifting from the .bat file to a Powershell script, as the only reason I'm using Batch is so the user can easily run the file by clicking it in Explorer. I couldn't get RefreshEnv to work, which is a feature of Chocolatey, but running this between each new package worked great:

    $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
    

    So I have something like this now, and the Batch scrip just launches this Powershell Script:

    Write-Host "Installing / updating required packages..."
    
    Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = 
    [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
    
    $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
    
    choco install ffmpeg -y
    choco install git -y
    
    $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") 
    
    Write-Host "Deleting old files..."
    
    Remove-Item -LiteralPath $relativePath -Force -Recurse
    Start-Sleep 2
    
    Write-Host "`nUpdating Files..."
    git clone https://github.com/TheNimble1/FFmpegContextCommands.git $relativePath
    

    Which installs Chocolatey, refreshes the path, installs FFmpeg & Git, refreshes the path, deletes the old files, and then clones the git to replace with new files.