0

I need a batch file that will toggle between running two command lines;

One being

nircmd.exe setdefaultsounddevice "Speakers"

The other being

nircmd.exe setdefaultsounddevice "Headset"

Ive tried using the existence of a .txt file as a flag, but for some reason it just always sees it as not existing. How do you make a batch file (silently) tick/tock every time it runs?

Sokonomi
  • 41
  • 2
  • 4
  • 2
    **[Edit your question](https://stackoverflow.com/posts/50314550/edit)** to include the code you tried, which uses the existence of a `.txt` file as a flag, but always sees it as not existing. We cannot help you with your failing code if we cannot see it, and not posting it means you're expecting somebody to write the script for you, _(which is rude and off-topic)_. – Compo May 13 '18 at 10:32

3 Answers3

4

You can store the toggle value in the Batch file itself in a very simple way:

@echo off
setlocal

rem Get current value and update it
call :GetToggle
set /P "=+1" < nul >> "%~F0"
set /A "toggle%%=2"

if %toggle% equ 0 (
   echo Set "Speakers"
) else (
   echo Set "Headset"
)

goto :EOF

:GetToggle
rem Be sure that next line does NOT end in CR+LF:
set /A toggle=0

This method works correctly for a little less than 4096 times. If the Batch file run once everyday, this covers more than 11 years! If this is not enough for you, just add an if command after get the toggle value to check if it exceeds 4090, and in such a case insert a breaking CR+LF characters at end of the file followed by a new line with set /A toggle=0

Note that this method also allows to know how many times the Batch file had been used, so it may be used in other scenario...

Aacini
  • 65,180
  • 12
  • 72
  • 108
  • Is it not possible to toggle a variable between 0 and 1 instead of adding "+1" each time the script is run? Would seem like a cleaner option imo. – Yannic Jan 17 '20 at 23:31
  • @Yannic: Yes, in a very simple way: `set /A "toggle=!toggle"`, but in such a case it would be needed to insert a complete `set toggle=%toggle%` line at end of the Batch file each time the script is run (instead of just `+1` two characters). – Aacini Jan 24 '20 at 16:01
2

A good solution is to store the switch in an ADS (alternative data stream) in the bat itself (will work only if your file system is NTFS):

You just will get a file not found warning at the first run while it can find the ADS stream but after that it will be created

@echo off

set "$activ="
set /p $activ=<%~nx0:activ

if not defined $activ (
    echo speaker>%~nx0:activ
    set "$activ=speaker"
    )

echo actual [%$activ%]

if /i "%$activ%"=="speaker" (
    nircmd.exe setdefaultsounddevice "Headset"
    echo headset>%~nx0:activ
    ) else (
    nircmd.exe setdefaultsounddevice "Speakers"
    echo speaker>%~nx0:activ
    )

EDIT : Thanks @aschipfl here is the solution to avoid the first run Warning

@echo off
set "$activ="

2> nul (set /P $activ= < "%~nx0:activ") || set "$activ=speaker"

echo actual [%$activ%]

if /i "%$activ%"=="speaker" (
    nircmd.exe setdefaultsounddevice "Headset"
    echo headset>%~nx0:activ
    ) else (
    nircmd.exe setdefaultsounddevice "Speakers"
    echo speaker>%~nx0:activ
    )

very easy and don't need any temp file and don't have call limitation

SachaDee
  • 9,245
  • 3
  • 23
  • 33
0
  • However you name the following batch, it will create an Ini file with the same name at the same location (Initially set to Speakers)
  • It uses nircmds inisetval for this and also changes the Active key to the current selection

:: ToggleSnd.cmd
@Echo off
set "NC="
::check nircmd
for /f "delims=" %%A in ("nircmd.exe") do Set "NC=%%~f$PATH:A"
if Not defined NC (Echo Can't Locate nircmd.exe&Pause&Exit /B 1)
Set "Ini=%~dpn0.Ini"

If Not Exist "%Ini%" goto :Speakers
:: get current selection
For /f %%A in ('Findstr /i "Active" %Ini%') Do Set "%%A"
if /I "%Active%"=="Headset" goto :Speakers

:: switch to Headset
%nc% setdefaultsounddevice "Headset"
%nc% inisetval "%Ini%" DefaultSoundDevice Active Headset
Echo switched to Headset
Goto :Eof

:Speakers
%nc% setDefaultSoundDevice "Speakers"
%nc% inisetval "%Ini%" DefaultSoundDevice Active Speakers
Echo switched to Speakers

Sometimes you are lucky if someone finds the task interresting.