Batch file behaves differently when ran from a SFX

2020-03-26 13:22发布

问题:

So I wrote a batch file to convert clients over to a cloud service and I'm seeing some weird behavior from it.

So this basically looks for a specific folder and whether or not it exists it uses GOTO to move on. When I compress this using WinRAR into a SFX and instruct it to run the batch file it NEVER detects the folder, however, when I run the batch file itself, it ALWAYS detects the folder, whether its there or not. I've been trying to figure this out for a few days now and I just don't understand why this is happening.

@ECHO Off
CD %~dp0
Goto DisableLocal


:DisableLocal
 IF EXIST "%ProgramFiles%\Server\" (
   GOTO Server
) ELSE (
GOTO Config
)

回答1:

For 32-bit applications executed on 64-bit Windows the environment variable ProgramFiles is set to value of environment variable ProgramFiles(x86) by Windows as Microsoft explains in MSDN article WOW64 Implementation Details.

The WinRAR SFX archive is created obviously using the x86 SFX module. The SFX archive could be also created using x64 SFX module, but then this SFX archive can be executed only on Windows x64.

The batch file is executed with 32-bit cmd.exe in 32-bit environment if the x86 SFX module is used on creating the archive.

So better is to adapt the batch code and add a detection for 32-bit execution on 64-bit Windows.

@ECHO OFF
CD /D "%~dp0"
GOTO DisableLocal

:DisableLocal
SET "ServerPath=%ProgramFiles%\Server\"
IF EXIST "%ServerPath%" GOTO Server

REM Is batch file processed in 32-bit environment on 64-bit Windows?
REM This is not the case if there is no variable ProgramFiles(x86)
REM because variable ProgramFiles(x86) exists only on 64-bit Windows.
IF "%ProgramFiles(x86)%" == "" GOTO Config

REM On 64-bit Windows 7 and later 64-bit Windows there is the variable
REM ProgramW6432 with folder path of 64-bit program files folder.
IF NOT "%ProgramW6432%" == "" (
    SET "ServerPath=%ProgramW6432%\Server\"
    IF EXIST "%ProgramW6432%\Server\" GOTO Server
)

REM For Windows x64 prior Windows 7 x64 and Windows Server 2008 R2 x64
REM get 64-bit program files folder from 32-bit program files folder
REM with removing the last 6 characters from folder path, i.e. " (x86)".
SET "ServerPath=%ProgramFiles:~0,-6%\Server\"
IF EXIST "%ServerPath%" GOTO Server

:Config
ECHO Need configuration.
GOTO :EOF

:Server
ECHO Server path is: %ServerPath%


回答2:

I have the same problem, I'm trying this way, but not sure if will work on a Windows 32 bits.

@ECHO Off
IF DEFINED ProgramW6432 (
    SET "ServerPath=%ProgramW6432%\Server\"
) ELSE (
    SET "ServerPath=%ProgramFiles%\Server\"
)

CD %~dp0
Goto DisableLocal

:DisableLocal
 IF EXIST "%ServerPath%" (
   GOTO Server
) ELSE (
GOTO Config
)