I cannot use the msg command in cmd (or batch for that matter). How can I fix this?

msg.exe is not available on all Windows platforms in all environments.

There is just %SystemRoot%\System32\msg.exe (64-bit), but no %SystemRoot%\SysWOW64\msg.exe (32-bit) on Windows 7 x64 Enterprise whereby 64-bit msg.exe must be accessed from within a 32-bit command process by using %SystemRoot%\Sysnative\msg.exe.

For details about System32, SysWOW64 and Sysnative see the Microsoft documentation page File System Redirector.

What does this mean?

  1. A batch file being executed on 32-bit Windows needs to run %SystemRoot%\System32\msg.exe.

  2. A batch file being executed on 64-bit Windows by 64-bit cmd.exe needs to run %SystemRoot%\System32\msg.exe.

  3. A batch file being executed on 64-bit Windows by 32-bit cmd.exe needs to run %SystemRoot%\Sysnative\msg.exe.

It depends on architecture of parent process starting cmd.exe or the batch file which implicitly results in starting cmd.exe for execution of the batch file if the batch file is executed in 32-bit or 64-bit environment on 64-bit Windows.

So a batch file is called with using explicitly %SystemRoot%\Sysnative\cmd.exe from a 32-bit application on Windows x64 or inside the batch file %SystemRoot%\Sysnative\msg.exe is used on a Windows x64 machine while on a Windows x86 machine %SystemRoot%\System32\cmd.exe respectively %SystemRoot%\System32\msg.exe must be used.

Demo example for first variant with using 64-bit command line interpreter:

Batch file with name MsgDemo.bat:

@echo off
%SystemRoot%\System32\msg.exe /?
pause

is called from 32-bit process running on Windows x64 with:

%SystemRoot%\Sysnative\cmd.exe /C MsgDemo.bat

Demo example for second variant with referencing msg.exe correct:

@echo off
set "AppMsg=%SystemRoot%\System32\msg.exe"
if not "%ProgramFiles(x86)%" == "" (

    rem Explicitly reference 64-bit version on Windows x64 as there is
    rem no 32-bit version. But use Sysnative redirector only if the batch
    rem file was started with 32-bit cmd.exe as otherwise System32 contains
    rem msg.exe if it is not missing at all like on Windows 7 Home Premium.

    if exist %SystemRoot%\Sysnative\* set "AppMsg=%SystemRoot%\Sysnative\msg.exe"
)
%AppMsg% /?
set "AppMsg="
pause

The redirector %SystemRoot%\Sysnative doesn´t exist for 64-bit processes, just for 32-bit processes.

%SystemRoot%\Sysnative is not a directory. Therefore if exist %SystemRoot%\Sysnative does not work, just if exist %SystemRoot%\Sysnative\*.