IF EXIST outputs true on non-existent file - if-statement

IF EXIST %PROGRAMFILES%\Winamp\paths.ini ( REM do stuff )
This file (and the folder) DOESN'T exist but it outputs true.
The script is on "K:\" and eventually got started with another file (%1) which as far as i know changes the start directory.
I have no clue why this doesn't work.
Also i tried to navigate to %PROGRAMFILES% and check the existance of \Winamp\ but for some reason it stays at it's home directory (or the one of %1).

You probably need quotes around the path, because %PROGRAMFILES% is going to expand to C:\Program Files
IF EXIST "%PROGRAM%FILES%\Winamp\paths.ini%"
e.g. Without quotes, note how it shows "file not found" TWICE:
C:\Users\marc>dir %PROGRAMFILES%
Volume in drive C is Windows7_OS
Volume Serial Number is 0E31-0E35
Directory of C:\
File Not Found
Directory of C:\Users\marc
File Not Found
because it was interpreted as
dir C:\Program Files
which executes as
dir C:\Program
dir Files
With quotes, it works:
C:\Users\marc>dir "%PROGRAMFILES%"
Volume in drive C is Windows7_OS
Volume Serial Number is 0E31-0E35
Directory of C:\Program Files
18/07/2014 04:02 PM <DIR> .
18/07/2014 04:02 PM <DIR> ..

Related

How can I check if either or file exists in IF Exist?

How can I check if either or file exists in a If Exist statement?
Such as
If exist "C:/Windows/" OR "C:/Windows2" (
Do something
) else (
Something else
)
How would I do this? I just want either or to exist and to do something.
Simple example 1:
#echo off
if not exist "%SystemRoot%\" if not exist "C:\Windows2" goto MissingFolderFile
echo Found either the directory %SystemRoot% or the file/folder C:\Windows2.
rem Insert here more commands to run on either the folder C:\Windows
rem or the file/folder (=any file system entry) C:\Windows2 existing.
goto EndDemo
:MissingFolderFile
echo There is neither the directory %SystemRoot% nor the file/folder C:\Windows2.
rem Insert here more commands to run on neither folder C:\Windows
rem nor file/folder C:\Windows2 existing.
:EndDemo
pause
The Windows command processor is designed for processing one command line after the other which is the meaning of the word batch. The command GOTO is the preferred command to use in a batch file to continue batch processing not on next command line, but another one depending on an IF condition, i.e. change processing from one stack (other word for batch) of command lines to another group of command lines.
Simple example 2:
#echo off
if exist "%SystemRoot%\" goto FolderExists
if exist "C:\Windows2" goto FS_EntryExists
echo There is neither the directory %SystemRoot%\ nor C:\Windows2.
rem Insert here more commands to run on neither folder C:\Windows
rem nor file/folder/reparse point C:\Windows2 existing.
goto EndDemo
:FS_EntryExists
echo The file system entry (file or folder) C:\Windows2 exists.
rem Insert here more commands to run on C:\Windows2 existing.
goto EndDemo
:FolderExists
echo The folder %SystemRoot% exists.
rem Insert here more commands to run on folder C:\Windows existing.
:EndDemo
pause
For understanding the used commands and how they work, open a command prompt window, execute there the following commands, and read entirely all help pages displayed for each command very carefully.
echo /?
goto /?
if /?
rem /?
NOTE:
The directory separator on Windows is \ and not / as on Linux or Mac. The Windows file management automatically replaces usually all / by \ before passing a file/folder argument string without or with a wildcard pattern to the file system as explained by Microsoft in the documentation about Naming Files, Paths, and Namespaces. But the usage of / instead of \ in file/folder argument strings can result nevertheless in unexpected behavior.
Example for unexpected behavior because of using / on running following command line directly in a command prompt window:
for %I in ("%SystemDrive%/Windows/*.exe") do #if exist "%I" (echo Existing file: "%I") else echo File not found: "%I"
This command line outputs a list of executable file names found by FOR in the Windows directory which do not exist for command IF just because of usage of / resulting in getting assigned to the loop variable the found file names without path. So this command line works only if the current directory on system drive is by chance the Windows directory.
The same command line with usage of \ as directory separator:
for %I in ("%SystemDrive%\Windows\*.exe") do #if exist "%I" (echo Existing file: "%I") else echo File not found: "%I"
This command line outputs each file name of the executables in Windows directory as existing file with full path.
Another example:
There is in root directory of current drive a directory Downloads and the current directory on this drive is Temp, for example D:\Downloads is the wanted current directory and D:\Temp is the current directory.
The used command is:
cd /Downloads
The result is the error message:
The system cannot find the path specified.
The command with correct directory separator usage:
cd \Downloads
This command works on D:\Temp being the current directory and D:\Downloads existing.
CD interprets on incorrect /Downloads the string /D at beginning of the directory path as option /D to change also the drive and searches for that reason for ownloads in current directory instead of Downloads in root directory of current drive. This wrong interpretation by CD is avoided by using the correct directory argument string \Downloads.
SUMMARY: \ is the directory separator and / is for command options.

Issue in compiling this open source application

I am trying to set up and run LibreCAD and I am following their Build From Source Guide.
At some point, and after installing QT and boost, I reach the step where it says this:
To change these default settings you have to create the file
scripts/custom-windows.bat and overwrite the different settings
without effect to the SCM (git). Example for
scripts/custom-windows.bat:
set Qt_DIR=C:\Qt\5.4
set NSIS_DIR=C:\PROGRA~2\NSIS
set MINGW_VER=mingw491_32
So I created a custom-windows.bat file and overwrote the settings. Now, and since I am working on 64 bit Windows, They are saying that I need to do this:
There are issues with the NSIS_DIR path on 64 Bit Windows. When NSIS
is installed in the Program Files (x86) folder and NSIS_DIR is added
to the PATH, something goes wrong in the build process.
In this case use the command dir /X \ and get an output like this:
09/02/2014 09:50 PM <DIR> PROGRA~1 Program Files
10/27/2014 12:33 PM <DIR> PROGRA~2 Program Files (x86)
08/16/2014 10:49 PM <DIR> Qt
But what does that mean? "..use the command dir /X \ and get the output.." Where and how? Appreciate it if anyone could tell me how to solve that.
Open up a command prompt and literally type dir /X \. The output will show the mapping between the short folder names and the long ones.
Your goal is to use the correct short form representation for Program Files (x86) in NSIS_DIR, since it's not always PROGRA~2. It can vary from filesystem to filesystem, based on the history of the filesystem.

Where are files placed when a path does not include a path or drive letter?

When I indicate a file to create and write to via ofstream without a path or drive letter, i.e. "testfile.txt" where is it placed when NOT run in an IDE (when run in VS, the file is placed in the project working directory) and run from a shortcut (I needed to indicate command line arguments)? It does not place it in the same location as the executable when run from a shortcut.
Your shortcut has a "Start in" property, which is the directory where your files will be placed by default (i.e. if you don't specify a path). The main exception is that in Vista, if the directory is in \Program Files\ the actual writes will be redirected to your profile directory.
If you start the program from the command prompt, the default directory is the working directory (i.e. your CMD.EXE prompt when you started your program). This isn't necessarily where your program is located. If your program is on the %PATH% or if you specified a full path to your executable, CMD can run your executable even if is stored outside your current working directory.

'cmake' is not recognised as an internal or external command

I'm trying to run cmake in Visual Studio 10, for esys-particle-win.
My path to cmake:C:\Program Files (x86)\CMake 2.8\bin\cmake.exe
My path to esys-particle-win:C:\esys-particle-win\trunk\buildvs2010\mkvs10.bat
The commands I'm typing in the administrator command prompt of Visual Studio 2010 are:
cd c:\esys-particle-win\trunk\buildvs2010
mkvs10.bat
and I'm getting this error:
'cmake' is not recognized as an internal or external command
contents of mkvs10.bat:
cmake .. -G "Visual Studio 10" -G "NMake Makefiles"
could anyone tell me where I am wrong?. I don't know computer programming. I followed the instructions mentioned in section 2.3.1 of this site: `
https://launchpadlibrarian.net/139659869/esys-particle-win-%28v2.1%29-build-instructions.pdf
`
Any help would be greatly appreciated, Thank you.
The error message means it cannot find cmake.
You can add its location to your path from the prompt like this:
set PATH="C:\Program Files (x86)\CMake 2.8\bin\";%PATH%
As #doctorlove mentioned above, the error message means it cannont find Cmake.
Note that quotes aren't needed in PATH environmental variables on Windows. So the above example on Windows would look like:
set PATH=C:\Program Files (x86)\CMake 2.8\bin\;%PATH%
I had the same issue, and resolved it in this post.
note that if you installed cmake via chocolatey, you may have neglected to add the argument --installargs 'ADD_CMAKE_TO_PATH=System'. If you've already choco-installed cmake without that argument, re-installing via --force won't respect the new argument: you'll need to uninstall and then install. specifically choco install cmake --installargs 'ADD_CMAKE_TO_PATH=System'
I had the same problem since I intalled CMake in D:\Program Files , I fixed it by manually adding a path variable.
Open control panel
Go to System and Security then go to System.
How it looks like in after step 2
Here Select advanced System settings, a dialogue box will appear.
The dialogue box
Now go to Environment Variables.
Now select path and then click on edit
After the 4th Step
Here add a new path at the bottom of many pre existing paths.
In my case i installed CMake in D:\Program Files\
So I need to add path D:\Program Files\CMake\bin. You should copy the path to your CMake folder and add \bin at the end.
Now open you have to restart command prompt to see the changes.
I found the CMake to be:
C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin
I added it to the User PATH as described above, by hrithik singla, and node-gyp worked, specifically "npm install". I expect it will change again in the future. So the way I found it was by having Windows Explorer search "C:\Program Files (x86)\Microsoft Visual Studio\2019" and then dig through the results for the CMake path. Probably, other development tools will install CMake to different folders.
I'm trying to build a project with my recently downloaded Visual Studio Community 2017, but had no CMake on my path.
It did not help, even after I had gained VCVars: "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
Instead of separately installing a copy that might work with these answers, although I'm not sure it would have the generators I need(?), I found one in the installation directory, which had a different path than what was in the guide I was using.
Here is my invocation line: "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin\cmake.exe" -G "Visual Studio 15 2017" -DCMAKE_BUILD_TYPE=%CMAKE_BUILD_TYPE% ..
There are a few issues that can cause this. And it's mostly windows related. This is more on the cmake side of things, but it addresses a few windows specific problems you may encounter using CMake with Windows. This is fresh in my head, and this popped up, so I'll drop this here. Here we go.
1. CMake will separate a variable to list if there are spaces in the path.
If you are calling another instance of CMake from within CMake, Sending a Program Files path will slice those strings, and divide your variable into a 3 item list. The spaces will be replace by a semicolon divider.
set(CMAKE_EXE C:\Program Files (x86)\CMake\bin\cmake.exe)
"C:\Program;Files;(x86)\CMake\bin\cmake.exe <- CMAKE_EXE is now a 3 item list separated by ; "
list(LENGTH ${CMAKE_EXE} count)
message("CMAKE_EXE has ${count} items") "-> displays 3"
On Windows, All path variables should be enclosed in quotations to infer that they are 1 single string variable. Not just for cmake, but for batch scripting, basic command line etc.
set(CMAKE_EXE "C:/Program Files (x86)/CMake/bin/cmake.exe")
Now, any time you reference CMAKE_EXE you'll need to always keep it enclosed in quotations, becuase cmake WILL break it to a list again otherwise.
execute_command(COMMAND cmd /c ${CMAKE_EXE} -P myScript.cmake) <-- BAD
execute_command(COMMAND cmd /c "${CMAKE_EXE}" -P myScript.cmake) <- GOOD
Just get in the habit of always putting quotations around paths you reference.
2. Stay away from the Windows back slashes!.
Windows uses back slashes by default for it's path divider, which are escape sequences in most coding languages, including CMake. Just send windows / forward slashes instead. This eliminates any headaches you'll have with doubling up escape characters in string literals to match the path. \
And remember, windows is always gonna try to give you paths in \ format. Windows likes backslashes in certain places like environment paths, and settings files, while cmake likes forward slashes. You need at some point to convert between the different formats.
Use something like this to convert the path to be more cross platform compatible. You can replace "in place" on your existing variable.
"CMAKE_EXE = C:\Program Files (x86)\CMake\bin\cmake.exe <- value before"
string(REPLACE "\\" "/" CMAKE_EXE "${CMAKE_EXE}") "<- notice the quotes again"
"CMAKE_EXE = C:/Program Files (x86)/CMake/bin/cmake.exe <- value after"
Take a look at these CMake functions designed to do path conversions.
https://cmake.org/cmake/help/latest/command/file.html#to-native-path
3. Sometimes, Windows interprets unquoted paths as 8.3SFN (8DOT3) format
8.3 filename
Back in the days of MSDOS and Windows 95, we dealt with the FAT file system and 8.3Short Filenames. The command prompt could not work with more than 8 character filenames so we needed a way to access long windows filenames before quotation string support. 8 characters + 3 for the extension. And most systems still support 8.3 today. Here's an example.
C:\Program Files\Windows\System32\Calc.exe <- \Program Files\ is 13 characters
in order to CD into this path without quotes, you have to use the short path. like so.
CD C:\Progra~1\Windows\System32\Calc.exe <-- *Progra~1 is 8 characters, 1st occurrence.*
You just break the File or Folder name down to 6 characters, plus ~n (n=occurrence)
If we had a C:\Program Files (x86) path then, like we do today, it would be the 2nd path who's first 6 characters matched, and both exceeded 8 characters.
C:\Program Files becomes -> C:\Progra~1\
C:\Program Files (x86) becomes -> C:\Progra~2\
C:\MyLongFilename.txt becomes -> C:\MyLong~1\
Whenever I am having trouble accessing the full length file system through software that is unable to send escape sequences or quotations, some other kind of limitation, I have to resort to using the 8.3 short filename to access certain paths. On some Windows boxes, quotes won't even work and it will be some LONG process to enable them on the host machine. This makes for a good workaround when that happens.
Getting the short path (via sending to command prompt)
C:\ for %A in ("C:\Program Files (x86)\CMake\bin\cmake.exe") do #echo %~sA
will produce C:\Progra~1 for you to use
Or, get the short path by sending the path as an argument to a batch file.
::getShortPath.bat
#ECHO OFF
echo %~s1
USE:-> getShortPath.bat "C:\Program Files (x86)\CMake\bin\cmake.exe"
To wrap this up, here are three examples of what could be happening in the background behind CMake when a windows path is not resolving.
Not using quotations around the path
Using quotes works. But sometimes you can lose your quotes if the stdio >> runs through more than one process. In which case you'll need to send them in as escape sequences "\"C:/Program Files (x86)/CMake/bin/cmake.exe\""
4. Paths and Command Line Arguments need to be separate variable or instances from each other.
When sending arguments from CMake, you DO want them to be separate variables from the path variable. Set(CMAKE_EXE "C:\Program Files (x86)\CMake\bin\cmake.exe --version") will not work. Only paths and arguments with spaces in them need to be wrapped in quotes.
set(CMAKE_EXE "C:\Program Files (x86)\CMake\bin\cmake.exe" --version --trace "C:\My Soure Dir")
Putting it all together
If anyone is having problems with Windows/CMake paths like I was in the past, Study this code thoroughly until you completely understand it. All of the quotation placements. When you understanding what's quoted and what's not, and why, it should help a lot in the long run.
set(CMAKE_EXE "C:\Program Files (x86)\CMake\cmake.exe" CACHE INTERNAL "") <- make it a global variable.
set(ARGUMENTS --version --trace)
set(MyStringWithQuotesIncluded "\"This String wants it's quotes included\"")
set(MyCMakeLists "C:\MyApp\ProjectDirectory")
set(BuildHere "C:\MyBuilds\MyOSProject\bin")
set(FULL_COMMAND "${CMAKE_EXE}" ${ARGUMENTS} -DSTRING_VARIABLE="${MyStringWithQuotesIncluded}" -S "${MyCMakeLists}" -B "${BuildHere}")
execute_command(COMMAND cmd /c ${FULL_COMMAND} WORKING_DIRECTORY "${BuildHere}")
I had loads of issues working with windows paths through layers of CMake when I first started out. I hope this can help someone avoid all of that in the future.
Step 0: Install CMAKE
Make sure you have CMAKE installed on Windows:
https://cmake.org/download/
The installer will ask you if you want it to automatically set the PATH variable for you.
set the path to C:\Program Files\CMake\bin

C++ library path inclusion

i found C++ libraries could be included this way:
#include "..\example.h"
#include ".\another_example.h"
what is the dots used for?
They are to indicate the included file paths' are relative to the including file's actual path.
. points to the including file's actual directory
.. points to the including file's actual directories' parent diretory
Double dots stand for the parent directory of the currently entered path.
Single dot stands for the currently entered path on the left side of a dot and is used to show that you want a relative path.
A relative path is a path relative to the working directory of the
user or application, so the full absolute path will not have to be
given.
If you start your path with / (on *nix systems) or DRIVELETTER: (on Windows, e.g. D:) then the path is absolute. If you don't - the path is relative. If path is relative - it automatically prepends the directory of your file to the path entered.
Example:
"dir/././../dir/.." is the directory which contains the original file. The reductions are:
dir/././../dir/.. -> dir/./../dir/.. -> dir/../dir/.. -> /dir/.. -> . -> working directory. We removed ./ because it's alias to the current directory. We removed /dir/.. because we enter a directory with dir and get back with ..
One of the most often used features of ./ (but in the context of a shell, e.g. bash) - it forces to use a relative path instead of calling an executable program in the $PATH variable. For example if you type ls in terminal on *nix it will list the files in the working directory. If you type ./ls it will run executable with the name ls
in the current working directory and execute whatever this program does.
You can read more about path separators in this article on wikipedia
One dot is your current directory and two dots is your parent directory.
Two dots means one directory higher than the current one. For example, if you are in the directory C:\some\directory", "..\" would be "C:\some".
A single dot refers to the current directory. So using the previous example, ".\" would mean "C:\some\directory".
one dot . is for file's directory
2 dots .. are for file's parent directory.