-2

I am trying to create a batch script that will download a file based on the computers OS and Architecture. My only problem is whenever I run the batch file, it closes after checking what archeticture the computer is using. I feel like its the if statements inside another if statement but I'm not sure. (Also, I know it specifically says not to have a vague title, but I wasnt sure what a better one would be.)

My intent is to have a portable program that runs an exe file, and runs this when the file is missing. I've tried different ways to check for the OS, and have tried rearranging the if statements, but nothing's worked so far.

setlocal
for /f "tokens=4-5 delims=. " %%i in ('ver') do set WINOS=%%i.%%j
reg Query "HKLM\Hardware\Description\System\CentralProcessor\0" | find /I "x86" > NUL && set ARCHCHECK=32BIT || set ARCHCHECK=64BIT
if %WINOS%==10.0 (
   if %ARCHCHECK%==32BIT (
      echo You are running Windows 10 on a 32 Bit architecture. Getting right files.
      powershell -Command "IInvoke-WebRequest https://example.com/example.zip -OutFile example.zip"
   if %ARCHCHECK%==64BIT (
      echo You are running Windows 10 on a 64 Bit architecture. Getting right files.
      powershell -Command "Invoke-WebRequest https://example.com/example.zip -OutFile example.zip"
if %WINOS%==6.1 (
   if %ARCHCHECK%==32BIT (
      echo You are running Windows 7 on a 32 Bit architecture. Getting right files.
      powershell -Command "(New-Object Net.WebClient).DownloadFile('https://example.com/example.zip', 'example.zip')"
   if %ARCHCHECK%==64BIT (
      echo You are running Windows 7 on a 64 Bit architecture. Getting right files.
      powershell -Command "(New-Object Net.WebClient).DownloadFile('https://example.com/example.zip', 'example.zip')"

And so on for Windows 8

I am expecting for the batch script to find the OS (To know which powershell command to use) then the architecture (To know what version to download) then run the download command. What actually happens is the script will run all the way up to the registry query, and then before it starts working on the if statements, it stops and closes the window.

  • 2
    You are not closing any of the command blocks with a right parentheses. – Squashman Dec 30 '18 at 18:45
  • I recommend reading the Microsoft documentation pages [WOW64 Implementation Details](https://docs.microsoft.com/en-us/windows/desktop/WinProg64/wow64-implementation-details), [File System Redirector](https://docs.microsoft.com/en-us/windows/desktop/WinProg64/file-system-redirector) and [Registry Keys Affected by WOW64](https://docs.microsoft.com/en-us/windows/desktop/WinProg64/shared-registry-keys). There is the environment variable `PROCESSOR_ARCHITECTURE`. But if the batch file is executed by 32-bit `%SystemRoot%\SysWOW64\cmd.exe` on 64-bit Windows, the value is `x86` and not `AMD64`. – Mofi Dec 30 '18 at 18:53
  • However, the environment variable `ProgramFiles(x86)` is defined only on 64-bit Windows. So following can be used to get architecture of Windows (with ignoring IA64): `if "%ProgramFiles(x86)%" == "" ( set "ARCHCHECK=32BIT" ) else set "ARCHCHECK=64BIT"`. The real architecture of the processor does not really matter because on a computer with a 64-bit processor can be nevertheless installed a 32-bit Windows which means only 32-bit applications can be used on this computer. – Mofi Dec 30 '18 at 18:59
  • Next it is always advisable to read the documentation of a command/function which should be used in a script. This is very easy for [Windows Commands](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/windows-commands). Open a command prompt window and run `help` to get displayed a list of commands with brief description and run the command with `/?` to get displayed the help/documentation of the command in language of OS. Try that out with running `if /?` in cmd window and read the help explaining syntax for command __IF__. – Mofi Dec 30 '18 at 19:03
  • Determining the machines architecture is irrelevant, you only need to know the Operating System architecture. You can only run a 64bit program on a 64bit OS, an x64 processor with a x86 OS can only run x86 programs! – Compo Dec 30 '18 at 19:10
  • See also [this answer](https://stackoverflow.com/a/34118487/3074564) explaining detailed the syntax of command __IF__. For this task it is definitely a good idea to make use of [List of Microsoft Windows versions](https://en.wikipedia.org/wiki/Windows_versions). And take also into account that execution of `for /f "tokens=4-5 delims=. " %i in ('ver') do @echo %i.%j` results on Windows XP in output of `[Version.5` because of `ver` outputs `Microsoft Windows XP [Version 5.1.2600]` on Windows XP while output is `Microsoft Windows [Version 6.1.7601]` on Windows 7. – Mofi Dec 30 '18 at 19:10
  • For that reason the second line should be `for /F "tokens=2 delims=[]" %%I in ('ver') do for /F "tokens=2,3 delims=. " %%A in ("%%I") do set "WINOS=%%A.%%B"` to get with first __FOR__ the version string in square brackets and process this string with second __FOR__ to get the Windows major and minor version numbers really correct for all versions of Windows. – Mofi Dec 30 '18 at 19:18

1 Answers1

1

Here's a method of performing your checks using WMIC and GoTO's:

@Echo Off
Set "MJ="
Set "MN="
For /F "EOL=O Delims=" %%A In ('"WMIc OS Get OSArchitecture,Version 2>Nul"'
) Do For /F "Tokens=1,3-4 Delims=-. " %%B In ("%%A"
) Do Set/A "OA=%%B, MJ=%%C, MN=%%D"
If Not Defined MN (If Not Defined MJ (Echo Unsupported OS&Pause&Exit/B) Else (
    Set/A MJ=5, MN=1))
Call :v%MJ%%MN%x%OA%
Pause
Exit/B

:v51x32
Echo Windows XP, Whistler Server x%OA% Commands
GoTo :EOF

:v51x64
Echo Windows XP, Whistler Server x%OA% Commands
GoTo :EOF

:v52x32
Echo Windows NET Server, Home Server, Server 2003 x%OA% Commands
GoTo :EOF

:v52x64
Echo Windows NET Server, Home Server, Server 2003 x%OA% Commands
GoTo :EOF

:v60x32
Echo Windows Longhorn, Vista, Server 2008 x%OA% Commands
GoTo :EOF

:v60x64
Echo Windows Longhorn, Vista, Server 2008 x%OA% Commands
GoTo :EOF

:v61x32
Echo Windows 7, Server 2008 R2, Home Server 2011 x%OA% Commands
GoTo :EOF

:v61x64
Echo Windows 7, Server 2008 R2, Home Server 2011 x%OA% Commands
GoTo :EOF

:v62x32
Echo Windows 8, Server 2012 x%OA% Commands
GoTo :EOF

:v62x64
Echo Windows 8, Server 2012 x%OA% Commands
GoTo :EOF

:v63x32
Echo Windows 8.1, Server 2012 R2 x%OA% Commands
GoTo :EOF

:v63x64
Echo Windows 8.1, Server 2012 R2 x%OA% Commands
GoTo :EOF

:v100x32
Echo Windows 10, Server 2016 x%OA% Commands
GoTo :EOF

:v100x64
Echo Windows 10, Server 2016 x%OA% Commands
GoTo :EOF

You can replace the Echo commands or add your specific commands between them and their respective GoTo's.

Hope it helps!

Compo
  • 36,585
  • 5
  • 27
  • 39
  • I like this approach, but how it works is really mysterious, not because of the commands in the batch file, but because of output of `wmic`. `wmic OS GET /?` lists neither on Windows 7 with version `6.1.7601` nor on Windows XP version `5.1.2600` the property `OSArchitecture`. On both Windows the command `wmic OS GET OSArchitecture /?` results in error message `OSArchitecture - Invalid property(s).` and the help for `GET`. But `wmic OS Get OSArchitecture,Version` works on Windows 7 and outputs both information processed correct by .bat while on Windows XP just an error is output. – Mofi Dec 30 '18 at 20:50
  • @Mofi Seems there is incomplete documentation and not all properties are well documented. The reason can be that they are added later after all other properties and MS just forgot to update documentation on them for the `wmic` utility. – Andry Dec 30 '18 at 21:11
  • @Andry. That is right. I found the Microsoft support article [How to detect the bitness of an operating system?](https://support.microsoft.com/en-us/help/2060044/how-to-detect-the-bitness-of-an-operating-system) which contains the information: *The __OSArchitecture__ property of the WMI class __Win32_OperatingSystem__ can also tell the bitness of OS, but the property is only available on Windows Vista and newer operating systems.* – Mofi Dec 31 '18 at 10:15