Skip to content

Instantly share code, notes, and snippets.

@AveYo
Last active May 4, 2024 15:47
Show Gist options
  • Star 25 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save AveYo/0f9e52da11f490435faa5ec091bd33e9 to your computer and use it in GitHub Desktop.
Save AveYo/0f9e52da11f490435faa5ec091bd33e9 to your computer and use it in GitHub Desktop.
Simple GUI helpers for batch files
@echo off &title Multiple GUI choices via powershell snippet by AveYo &rem preview: https://i.imgur.com/JjazNR0.png
:: setup gui dialog choices
set all_choices=Option 1,Option 2,Option 3,Option4,Option5
set def_choices=Option 1,Option 2,Option5
:: Show gui dialog choices 1=title 2=all_choices 3=def_choices 4=output_variable
call :choices "Multiple GUI choices" "%all_choices%" "%def_choices%" CHOICES
:: Quit if no choice selected
if not defined CHOICES color 0c &echo ERROR! No choice selected.. &timeout /t 20 &color 07 &exit/b
:: Print choices
echo Choices: %CHOICES% & echo.
:: Process choices
call :process "%CHOICES%"
:Done
timeout /t -1
exit/b
:"Option 1"
echo running code for %0
rem do stuff here
exit/b
:"Option 2"
echo running code for %0
rem do stuff here
exit/b
:"Option 3"
echo running code for %0
rem do stuff here
exit/b
:"Option4"
echo running code for %0
rem do stuff here
exit/b
:"Option5"
echo running code for %0
rem do stuff here
exit/b
:process %1=choices
for /f "tokens=1* delims=," %%a in ("%~1") do if %%a.==. (exit/b) else call :"%%a" &call :process "%%b"
exit/b
::---------------------------------------------------------------------------------------------------------------------------------
:choices 1=title 2=all_choices 3=def_choices 4=output_variable GUI dialog with autosize checkboxes - outputs %CHOICES%
setlocal &set "parameters=$n='%~1'; $all='%~2'; $def='%~3'; $p='HKCU:\Environment'; $pad=32;"
set "s1=[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms'); $f=New-Object System.Windows.Forms.Form;"
set "s2=[void][System.Reflection.Assembly]::LoadWithPartialName('System.Drawing'); $f.Forecolor='Black';$f.BackColor='WhiteSmoke';"
set "s3=$r=(Get-ItemProperty $p).$n; if($r -ne $null){$opt=$r.split(',')}else{$opt=$def.split(',')}; function CLK(){ $v=@();"
set "s4=foreach($x in $cb){if($x.Checked){$v+=$x.Text}}; New-ItemProperty -Path $p -Name $n -Value $($v -join ',') -Force };"
set "s5=$BCLK=@(0, {CLK}, {foreach($z in $cb){$z.Checked=$false;if($def.split(',') -contains $z.Text){$z.Checked=$true}};CLK});"
set "s6=$i=1; $cb=foreach($l in $all.split(',')){$c=New-Object System.Windows.Forms.CheckBox; $c.Name='c$i'; $c.AutoSize=$true;"
set "s7=$c.Text=$l; $c.Location=New-Object System.Drawing.Point(($pad*2.5),(16+(($i-1)*24))); $c.BackColor='Transparent';"
set "s8=$c.add_Click({CLK}); $f.Controls.Add($c); $c; $i++; }; foreach($s in $cb){if($opt -contains $s.Text){$s.Checked=$true}};"
set "s9=$j=1; $bn=@('OK','Reset');foreach($t in $bn){ $b=New-Object System.Windows.Forms.Button; $b.BackColor='Transparent';"
set "s10=$b.Location=New-Object System.Drawing.Point(($pad*2+($j-1)*$pad*3),(32+(($i-1)*24))); $b.Margin='0,0,72,20';"
set "s11=$b.add_Click($BCLK[$j]); if ($t -eq 'OK'){$b.DialogResult=1;$f.AcceptButton=$b}; $b.Name='b$j'; $b.Text=$t;"
set "s12=$f.Controls.Add($b);$j++;}; $f.Text=$n; $f.FormBorderStyle='Fixed3D'; $f.AutoSize=$true; $f.AutoSizeMode='GrowAndShrink';"
set "s13=$f.MaximizeBox=$false; $f.StartPosition='CenterScreen'; $f.Add_Shown({$f.Activate()}); $ret=$f.ShowDialog();"
set "s14=if ($ret -ne 1) {Remove-ItemProperty -Path $p -Name $n -Force -erroraction 'silentlycontinue' | out-null}"
set "s15=else {write-host (Get-ItemProperty -Path $p -Name $n).$n;}"
for /l %%# in (1,1,15) do call set "ps_Choices=%%ps_Choices%%%%s%%#:"=\"%%"
for /f "usebackq tokens=* delims=" %%# in (`powershell -c "%parameters% %ps_Choices%"`) do set "choices_var=%%#"
endlocal & set "%~4=%choices_var%" & exit/b &rem snippet by AveYo released under MIT License
::---------------------------------------------------------------------------------------------------------------------------------
@echo off &title Nested GUI buttons example via mshta snippet by AveYo &rem preview: https://i.imgur.com/bAIuIHy.png
:: v2: less flicker
:gui_dialog_1
set first_choices=Option 1,Option 2,Option3,Option4,Finish&set title=Simple GUI choices #1
:: Show gui dialog 1=Title 2=choices 3=outputvariable
call :choice "Simple GUI buttons" "%first_choices%" CHOICE
:: Quit if no choice selected
if not defined CHOICE color 0c &echo ERROR! No choice selected.. &timeout /t 20 &color 07 &exit/b
:: Print choices
echo Choice1: %CHOICE% & echo.
:: Continue to dialog_2
goto gui_dialog_2
:gui_dialog_2
:: Process results from dialog_1
if "%CHOICE%"=="Option 1" set next_choices=Suboption 1 1,Suboption 1 2,Suboption 1 3,Back&set title=Option 1
if "%CHOICE%"=="Option 2" set next_choices=Suboption 2 1,Suboption 2 2,Back&set title=Option 2
if "%CHOICE%"=="Option3" set next_choices=Suboption 3 1,Suboption 3 2,Suboption 3 3,Suboption 3 4,Back&set title=Option3
if "%CHOICE%"=="Option4" call :"Option4" &goto Done no suboption
if "%CHOICE%"=="Finish" call :"Finish" &goto Done no suboption
:: Show gui dialog 1=Title 2=choices 3=outputvariable
call :choice "%title%" "%next_choices%" CHOICE
:: Quit if no choice selected
if not defined CHOICE color 0c &echo ERROR! No choice selected.. &timeout /t 20 &color 07 &exit/b
:: Print choices
echo Choice2: %CHOICE% & echo.
:: Back to dialog_1
if "%CHOICE%"=="Back" goto gui_dialog_1
:: Process final choice
call :"%CHOICE%"
:Done
timeout /t -1
exit/b
:: Choice code
:"Option4"
echo running code for %0
rem do stuff here
exit/b
:"Finish"
echo running code for %0
rem do stuff here
goto :Done
:"Suboption 1 1"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 1 2"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 1 3"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 2 1"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 2 2"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 1"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 2"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 3"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 4"
echo running code for %0
rem do stuff here
exit/b
::---------------------------------------------------------------------------------------------------------------------------------
:choice
rem 1=title 2=options 3=output_variable example: call :choice Choose "op1,op2,op3" result
setlocal & set "c=about:<title>%~1</title><head><script language='javascript'>window.moveTo(-200,-200);window.resizeTo(100,100);"
set "c=%c% </script><hta:application innerborder='no' sysmenu='yes' scroll='no'><style>body{background-color:#17141F;}"
set "c=%c% br{font-size:14px;vertical-align:-4px;} .button{background-color:#7D5BBE;border:2px solid #392E5C; color:white;"
set "c=%c% padding:4px 4px;text-align:center;text-decoration:none;display:inline-block;font-size:16px;cursor:pointer;"
set "c=%c% width:100%%;display:block;}</style></head><script language='javascript'>function choice(){"
set "c=%c% var opt=document.getElementById('options').value.split(','); var btn=document.getElementById('buttons');"
set "c=%c% for (o in opt){var b=document.createElement('button');b.className='button';b.onclick=function(){
set "c=%c% close(new ActiveXObject('Scripting.FileSystemObject').GetStandardStream(1).Write(this.value));};"
set "c=%c% b.appendChild(document.createTextNode(opt[o]));btn.appendChild(b);btn.appendChild(document.createElement('br'));};"
set "c=%c% btn.appendChild(document.createElement('br'));var r=window.parent.screen;"
set "c=%c% window.moveTo(r.availWidth/3,r.availHeight/6);window.resizeTo(r.availWidth/3,document.body.scrollHeight);}</script>"
set "c=%c% <body onload='choice()'><div id='buttons'/><input type='hidden' name='options' value='%~2'></body>"
for /f "usebackq tokens=* delims=" %%# in (`mshta "%c%"`) do set "choice_var=%%#"
endlocal & set "%~3=%choice_var%" & exit/b &rem snippet by AveYo released under MIT License
::--------------------------------------------------------------------------------------------------------------------------------
@echo off &title Nested GUI buttons example via powershell snippet by AveYo
:gui_dialog_1
set first_choices=Option 1,Option 2,Option3,Option4,Finish&set title=Simple GUI choices #1
:: Show gui dialog %1=Title %2=choices %3=outputvariable
call :choice "Simple GUI buttons" "%first_choices%" CHOICE
:: Quit if no choice selected
if not defined CHOICE color 0c &echo ERROR! No choice selected.. &timeout /t 20 &color 07 &exit/b
:: Print choices
echo Choice1: %CHOICE% & echo.
:: Continue to dialog_2
goto gui_dialog_2
:gui_dialog_2
:: Process results from dialog_1
if "%CHOICE%"=="Option 1" set next_choices=Suboption 1 1,Suboption 1 2,Suboption 1 3,Back&set title=Option 1
if "%CHOICE%"=="Option 2" set next_choices=Suboption 2 1,Suboption 2 2,Back&set title=Option 2
if "%CHOICE%"=="Option3" set next_choices=Suboption 3 1,Suboption 3 2,Suboption 3 3,Suboption 3 4,Back&set title=Option3
if "%CHOICE%"=="Option4" call :"Option4" &goto Done no suboption
if "%CHOICE%"=="Finish" call :"Finish" &goto Done no suboption
:: Show gui dialog %1=Title %2=choices %3=outputvariable
call :choice "%title%" "%next_choices%" CHOICE
:: Quit if no choice selected
if not defined CHOICE color 0c &echo ERROR! No choice selected.. &timeout /t 20 &color 07 &exit/b
:: Print choices
echo Choice2: %CHOICE% & echo.
:: Back to dialog_1
if "%CHOICE%"=="Back" goto gui_dialog_1
:: Process final choice
call :"%CHOICE%"
:Done
timeout /t -1
exit/b
:: Choice code
:"Option4"
echo running code for %0
rem do stuff here
exit/b
:"Finish"
echo running code for %0
rem do stuff here
goto :Done
:"Suboption 1 1"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 1 2"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 1 3"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 2 1"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 2 2"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 1"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 2"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 3"
echo running code for %0
rem do stuff here
exit/b
:"Suboption 3 4"
echo running code for %0
rem do stuff here
exit/b
::------------------------------------------------------------------------------------------------------------------------------
:choice
rem 1=title 2=choices 3=output_variable [button number] [GUI buttons dialog snippet by AveYo] released under MIT License
setlocal & set "ps_Choice=$title='%~1'; $choices='%~2'.split(','); $n=$choices.length; $global:c=''; $i=1; "
set "s1=[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms');$f=New-Object System.Windows.Forms.Form"
set "s2=;$f.Text=$title; $f.BackColor=0xff180052; $f.Forecolor='Snow'; $f.StartPosition=4; $f.AutoSize=1; $f.FormBorderStyle=3;"
set "s3=foreach($l in $choices){ $b=New-Object System.Windows.Forms.Button; $b.Text=$l; $b.Name=$n-$i; $b.cursor='Hand';"
set "s4= $b.Location='8,'+(32*$i);$b.Margin='8,4,8,4';$b.MinimumSize='320,20';$b.add_Click({$global:c=$this.Text;$f.Close()});"
set "s5= $f.Controls.Add($b); $i++ }; $f.AcceptButton=$f.Controls[0]; $f.CancelButton=$f.Controls[-1]; $f.MaximizeBox=0; "
set "s6=$f.Add_Shown({$f.Activate()}); $null=$f.ShowDialog(); if($global:c -ne ''){write-host $global:c}"
for /l %%# in (1,1,6) do call set "ps_Choice=%%ps_Choice%%%%s%%#:"=\"%%"
endlocal & for /f "tokens=* delims=" %%# in ('powershell -noprofile -c "%ps_Choice%"') do set "%~3=%%#"
exit/b
::------------------------------------------------------------------------------------------------------------------------------
@AveYo
Copy link
Author

AveYo commented Oct 19, 2018

fixed some weird behavior in redstone 5

@HaKDMoDz
Copy link

HaKDMoDz commented Aug 5, 2022

@AveYo Excellent work I didn't know batch files could create a GUI-based application.

@jedis00
Copy link

jedis00 commented Jan 3, 2023

@AveYo Anything to add an input box to the first script, in addition to the checkboxes?

@zSoloo
Copy link

zSoloo commented May 18, 2023

Hello!

Thanks for this great codeing - Ive been trying to put it too use for my case but it seems When i add more Buttons i have 9, when i get to 6, i dont get any type of Button menu/sub menu despite having included it in the code for Chose statements

ie.

if "%CHOICE%"=="Area 1" set next_choices=Area 2,Area 3,Book,Spare Area, Bump 1, Bump 2,Back & goto "Area1" & set title=Connected to Area 1 on %input%
if "%CHOICE%"=="Area 2" set next_choices=Area 1,Area 3,Tablet,Spare Area, Bump 1, Bump 2,Back & goto "Area2"&set title=Connected to Area 2 on %input%
if "%CHOICE%"=="Area 3" set next_choices=Area 1,Area 2,Tablet,Spare Area, Bump 1, Bump 2,Back & goto "Area3"&set title=Connected to Area 3 on %input%
if "%CHOICE%"=="Tablet" set next_choices=Area 1,Area 2,Area 3,Spare Area, Bump 1, Bump 2,Back & goto "Tablet"&set title=Connected to Tablet on %input%
if "%CHOICE%"=="Spare" set next_choices=Area 1,Area 2,Area 3,Spare Area, Bump 1, Bump 2,Back & goto "Spare"&set title=Connected to Spare on %input%
if "%CHOICE%"=="Bump 1" set next_choices=Area 1,Area 2,Area 3,Spare Area, Bump 1, Bump 2,Back& goto "Bump1"&set title=Connected to Bump Area 1 on Store %input%
if "%CHOICE%"=="Bump 2" set next_choices=1, Bump 2,Back&goto "Bump2"&set title=Connected to Bump Area 2 on Store %input%
if "%CHOICE%"=="Enter New area Number" start /b "" cscript test.vbs & exit

@SZRabinowitz
Copy link

Love it thanks!

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