0

I have a program that asks for admin privileges, stops some services, deletes a few files that couldn't be deleted if the services were running, restarts the services, and goes to a hard coded address where I have a vbs script I want to run next.

My problem is I'm about to put it on more computers, and I don't want to edit the hard coded address each time I set it up. I know that when you open a batch file, it starts at the directory where its located. I would like to save that in a variable so i can come back to it later to run the vbs script. Is there any way to do this?

Here is my code: problem is at the bottom of the script

@echo off
REM  --> Check for permissions
    IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
) ELSE (
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
)

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )
@echo off
:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params= %*
    echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"
@echo off
net stop wuauserv
net stop bits
---save directory here--
cd /
cd Windows
echo To clean Windows Update, we need to wipe a folder. Wiping
rd /s SoftwareDistribution
mkdir SoftwareDistribution
echo The folder has been wiped.
pause
echo.
cd /
net start wuauserv
net start bits
---go to saved directory---
popup  <-- VBS Script
pause
exit
  • 2
    Just a couple of lines above where you want to save your current directory, you've used the `CD` command to change your Current Directory to that of the running script, i.e. `CD /D "%~dp0"`. That means you already know and have available the current directory, as `%~dp0`. In addition to that, what is the issue with saving the current directory to another variable, `Set "NewVar=%CD%"`. However, why use `PushD "%CD%"` at all? Why `CD /D "%~dp0"`, then `CD /`, then `CD Windows`, essentially `CD /D "%~d0\Windows"`, would do all of that at once. Then what is the need to use `CD /` later? – Compo Mar 07 '22 at 18:12
  • Just for additional clarification, there doesn't appear to be a single command, anywhere in your entire script which requires any change of directory at all, apart from 'possibly' `popup`, which should technically be `%SystemRoot%\System32\cscript.exe //NoLogo "%~dp0popup.vbs"`, or perhaps `%SystemRoot%\System32\wscript.exe "%~dp0popup.vbs"`. You could even use `%~d0\Windows\System32\cscript.exe //NoLogo "%~dp0popup.vbs"`, or perhaps `%~d0\Windows\System32\wscript.exe "%~dp0popup.vbs"`. – Compo Mar 07 '22 at 18:22
  • 2
    Also, if you really want to `cd` to one directory, then return later, use `pushd` instead to change directories, and later use `popd` to return. – Anon Coward Mar 07 '22 at 18:59
  • The first line to improve is `IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64"`. `==` is the string comparison operator and not `EQU` which is primary for integer comparisons (and results in running a string comparison on one of the two operands cannot be converted successfully from a string to an integer like here with `"` as first character of the left string and comparing the results of the string comparison (< 0, 0 or >0) with value `0`. So always use `==` on comparing to strings and not `EQU`. – Mofi Mar 07 '22 at 20:45
  • The __IF__ condition runs a case-sensitive string comparison (after failed conversion to an integer). This condition is therefore never true because of `%PROCESSOR_ARCHITECTURE%` expands to `AMD64` and not `amd64` on batch file processed by 64-bit `cmd.exe` in `%SystemRoot%\System32` on 64-bit Windows with a processor with AMD64 instruction set or to `x86` on 64-bit Windows with a processor with AMD64 instruction set and batch file processed with 32-bit `cmd.exe` in `%SystemRoot%\SysWOW64` or on 32-bit Windows with an Intel x86 or AMD64 processor. – Mofi Mar 07 '22 at 20:50
  • Yes, the environment variable `PROCESSOR_ARCHITECTURE` does not provide the information about bit with of currently running Windows nor of the really used processor. It contains the information with instruction set is used in the current execution environment. For details read the Microsoft documentation about [WOW64 Implementation Details](https://learn.microsoft.com/en-us/windows/win32/winprog64/wow64-implementation-details) and the other pages references on this page. So the first __IF__ condition is completely wrong for a string comparison and is never true on any Windows. – Mofi Mar 07 '22 at 20:53
  • There can be used on 32-bit and 64-bit Windows with a processor with an x86 or AMD64 instruction set the condition `if "%ProgramFiles(x86)" == ""` to find out if Windows is a 32-bit Windows on which this condition is true or 64-bit Windows on which this condition is false. There can be next used on 64-bit Windows `if exist %SystemRoot%\Sysnative\cmd.exe` to find out if the batch file is currently processed in 32-bit environment on which this condition is true or in 64-bit environment on which this condition is false. – Mofi Mar 07 '22 at 20:57
  • The next __IF__ condition `if '%errorlevel%' NEQ '0'` is also wrong although this time at least working. There is used the integer comparison operator `NEQ` although compared are two strings because of `'` on each side of the two strings which does not have any special meaning for `cmd.exe` on this command line and is therefore interpreted like the character `0`. The usage help of command __IF__ output on running `if /?` explains the syntax to use to evaluate the exit code of a previous command like `cacls.exe`. It is `if not errorlevel 1` to check if exit code of `cacls.exe` is `0` (success). – Mofi Mar 07 '22 at 21:02
  • I strongly recommend to read my long answer on [Can't run as Admin](https://stackoverflow.com/a/41493926/3074564) and use the posted batch file code with your command lines below the label `:RunApp`. The batch file can be reduced by removing all lines starting with `rem` which are just comments for people interested in __how__ the code works and why each command line above `:RunApp` is coded by me exactly as it can be read on looking on the command lines of the batch file. – Mofi Mar 07 '22 at 21:06
  • Some more hints: Do not use just `net` in your batch file, use `%SystemRoot%\System32\net.exe` to be fail safe. Do not use `cd /`. The directory separator on Windows is ``\`` and not `/` as document by Microsoft with [Naming Files, Paths, and Namespaces](https://docs.microsoft.com/en-us/windows/win32/fileio/naming-a-file). `/` is used for options and `cd` indeed supports options, see my __NOTE__ in the answer on [How can I check if either or file exists in IF Exist?](https://stackoverflow.com/a/68088287/3074564) It explains on examples why there should be never used `/` in file/folder paths. – Mofi Mar 07 '22 at 21:12
  • Replace `cd /` and `cd Windows` by the single command line `cd /D %SystemRoot%` as the Windows directory can be on any drive with also a different name then `Windows` although `C:\Windows` is really used on the vast majority of Windows computers nowadays. But if Windows (more precisely the Windows shell) itself overs an environment variable like `SystemRoot`, it is really advisable to make use of it. – Mofi Mar 07 '22 at 21:16
  • It is possible to delete the directory `SoftwareDistribution` completely and create it new, but I recommend to use `pushd "%SystemRoot%\SoftwareDistribution" 2>nul && ( rd /Q /S "%SystemRoot%\SoftwareDistribution" 2>nul & popd )` to delete just all files and subdirectories in the directory `%SystemRoot%\SoftwareDistribution`, but not the directory itself because of the NTFS permissions. The command `cd /D %SystemRoot%` is not needed at all on using this command line. – Mofi Mar 07 '22 at 21:20
  • Next read DosTips forum topic [ECHO. FAILS to give text or blank line - Instead use ECHO/](https://www.dostips.com/forum/viewtopic.php?f=3&t=774) and do not use `echo.` to output an empty line as that could fail although it is very unlikely, but has happened already on some Windows computers as it can be read in referenced forum topic. And finally remove the command `exit` which is (nearly) always useless at end of a batch file and here really not needed at all. – Mofi Mar 07 '22 at 21:23

1 Answers1

0

A big thank you to @Compo for suggesting to me the use of ‘’’%~dp0’’’ It fixed pretty much everything.