How do you avoid over-populating the PATH Environment Variable in Windows? - windows

I would like to know what are the approaches that you use to manage the executables in your system. For example I have almost everything accessible through the command line, but now I come to the limit of the path string, so i can't add any more dir.
So what do you recommend?
A long time ago, I tried to use softLinks of the executables in a Dir that belonged to the path, but that approach didn't work.
Throw the "executable only" to a known Dir,has the problems that almost any application require a set of files, so this also is bad.
Throw the executable and all his files to a known Dir, mmm this will work, but the possibility to get a conflict in the name of the files is very very high.
Create a HardLink? i don't know. What do you think?

This will parse your %PATH% environment variable and convert each directory to its shortname equivalent and then piece it all back together:
#echo off
SET MyPath=%PATH%
echo %MyPath%
echo --
setlocal EnableDelayedExpansion
SET TempPath="%MyPath:;=";"%"
SET var=
FOR %%a IN (%TempPath%) DO (
IF exist %%~sa (
SET "var=!var!;%%~sa"
) ELSE (
echo %%a does not exist
)
)
echo --
echo !var:~1!
Take the output and update the PATH variable in environment variables.

One way I can think of is to use other environment variables to store partial paths; for example, if you have
C:\this_is_a\long_path\that_appears\in_multiple_places\subdir1;
C:\this_is_a\long_path\that_appears\in_multiple_places\subdir2;
then you can create a new environment variable such as
SET P1=C:\this_is_a\long_path\that_appears\in_multiple_places
after which your original paths become
%P1%\subdir1;
%P1%\subdir2;
EDIT: Another option is to create a bin directory that holds .bat files that point to the appropriate .exe files.
EDIT 2: Ben Voigt's comment to another answer mentions that using other environment variables as suggested might not reduce the length of %PATH% because they would be expanded prior to being stored. This may be true and I have not tested for it. Another option though is to use 8dot3 forms for longer directory names, for example C:\Program Files is typically equivalent to C:\PROGRA~1. You can use dir /x to see the shorter names.
EDIT 3: This simple test leads me to believe Ben Voigt is right.
set test1=hello
set test2=%test1%hello
set test1=bye
echo %test2%
At the end of this, you see output hellohello rather than byehello.
EDIT 4: In case you decide to use batch files to eliminate certain paths from %PATH%, you might be concerned about how to pass on arguments from your batch file to your executable such that the process is transparent (i.e., you won't notice any difference between calling the batch file and calling the executable). I don't have a whole lot of experience writing batch files, but this seems to work fine.
#echo off
rem This batch file points to an executable of the same name
rem that is located in another directory. Specify the directory
rem here:
set actualdir=c:\this_is\an_example_path
rem You do not need to change anything that follows.
set actualfile=%0
set args=%1
:beginloop
if "%1" == "" goto endloop
shift
set args=%args% %1
goto beginloop
:endloop
%actualdir%\%actualfile% %args%
As a general rule, you should be careful about running batch files from the internet, since you can do all sorts of things with batch files such as formatting your hard drive. If you don't trust the code above (which I wrote), you can test it by replacing the line
%actualdir%\%actualfile% %args%
with
echo %actualdir%\%actualfile% %args%
Ideally you should know exactly what every line does before you run it.

if you are using windows vista or higher, you can make a symbolic link to the folder. for example:
mklink /d C:\pf "C:\Program Files"
would make a link so c:\pf would be your program files folder. I shaved off 300 characters from my path by using this trick.

In case anyone's interested...
I find I never really need all those paths at once, so I create a bunch of "initialization" batch files which modify the path accordingly.
For example, if I wanted to do some C++ development in Eclipse, I would do:
> initmingw
> initeclipse
> eclipse
This is also handy for avoiding conflicts between executables with the same name (such as the C++ and D compilers, which both have a make.exe).
My batch files typically look like this:
#echo off
set PATH=C:\Path\To\My\Stuff1;%PATH%
set PATH=C:\Path\To\My\Stuff2;%PATH%
I find this approach relatively clean and have yet to run into any problems with it.

I generally don't have to worry about this (I haven't run into a path size limit - I don't even know what that is on modern Windows systems), but here's what I might do to avoid putting a program's directory in the path:
most command line utilities get thrown into a c:\util directory that's on the path
otherwise, I'll add a simple cmd/batch file to the c:\util directory that looks something like:
#"c:\program files\whereever\foo.exe" %*
which essentially creates an alias for the command. It's not necessarily perfect. Some programs really insist on being in the path (that's pretty rare nowadays), and other programs that try to invoke it might not find it properly. But for most uses it works well.
But generally, I haven't had to worry about avoiding adding directories to the path.

Another idea: Use DIR /X to determine the short names generated for non-8dot3 file
names. Then use these in your %PATH%.
For example, 'C:\Program Files' becomes 'C:\PROGRA~1'.

USe the App Path registry key instead of the path variable for application-specific paths:
http://msdn.microsoft.com/en-us/library/windows/desktop/ee872121(v=vs.85).aspx

I wrote and use on a every-time basis a standard stream (stdin/stderr/stdout) & exit code PROXY program (called dispatcher https://github.com/131/dispatcher)
All CLI program i use (node, php, python, git, svn, rsync, plink ...) i'm using are actually the same exe file (around 10kb, that i just name differently), that i put in the same directory. A dummy static clear text file do the "proxy file name to real exe mapping".
Dispatcher use low level Process management win32 API to be absolutly transparent.
Using this software, i only do have ONE additionnal directory set in my PATH for all programs i might use.

Creating a folder c:\bin adding to your path and hardlinking like you said could shorten the string. Maybe add a variable pf to system vars with value c:\Program Files then replace c:\Program Files with %pf% in path.
Edit:
Create a virtual drive.
subst p: "c:\program files"

I follow these steps to make the entries manageable:
Created different users for different combination of software packages usage.
Example: (a) Created a user web for making available all the web development software; (b) Created a user database for making available all the database and data warehousing software packages. Remember some software may create more than one entry. Or sometime I break this into oracle specific and MSSQL specific and oracle specific users. I put MySQL/PostgreSQL, tomcat, wamp, xamp all into the user account webr.
If possible install common packages like office, photoshop, .. as system specific available for all users and special packages as user specific. Of course I had to log into different users and install them. Not all software may provide this option. If "install for this user only" option is not available, install it for the whole system.
I avoid installing programs in to the folder Program File (x86) or in to Program File. I always install into the base directory. For example MySQL 64 bit goes into "C:\mysql64" and MySQL 32 bit goes into "C:\mysql" folder. I always assume adding a suffix 64 only for 64bit software. If no suffix, then it is a 32 bit. I follow the same thing to Java and others. This way my path will be shorter, not including "C:\Program File (x86)". For some software the configuration file may need to be edited to show where exactly the .exe file is. Only program that demands to be installed into "C:\Program File (x86)" will be installed into that folder. Always I remember to shorten the names. I avoid version number like tomcat/release/version-2.5.0.3 such details. If I need to the know version, I create a file by name version and put it into the tomcat folder. In general shorten the link as much as possible.
Include any batch to replace abbreviated link to the path, if all the above steps passed the Windows limit.
Then Log into usage specific (mobile application, or database/data warehousing or web-development.. ..) user and do the relevant tasks.
You can also create virtual windows within windows. As long as you have one licensed OS copy, creating multiple virtual windows with same key is possible. You can put packages specific for a particular task in that machine. You have to launch separate VM each time. Some memory intensive packages like 3D animation movie makers all should be put into the main machine, not into VM as VM will have only a part of the RAM available for its use. It is a pain to boot each VM though.

The solutions above only work if you can trim down your path. In my case, that wasn't really an option, and it was a hassle to have to run a script every time I opened a command prompt. So I wrote a simple script that runs automatically when opening the command prompt, and appends the contents of a text file to your path.
There are also some contexts where having this script run breaks things (say, in a github or cygwin shell), so I also added a file that contains a list of paths that, if the command prompt is started in them, the path variable isn't changed via the startup script that normally updates the path.
#echo off
:: Modify these to the actual paths of these two files
set dontSetupFile=C:\Users\Yams\Dontsetup.txt
set pathFile=C:\Users\Yams\Path.txt
:: Retrieve the current path (for determining whether or not we should append to our path)
set curDir=%cd%
:: Be done if the current path is listed in the dontSetupFile
SetLocal EnableDelayedExpansion
for /F "delims=" %%i in (%dontSetupFile%) do (
if "%%i"=="%curDir%" GOTO AllDone
)
:: Append the pathFile to our current PATH
set pathAppend=
for /F "delims=" %%i in (%pathFile%) do (set pathAppend=!pathAppend!%%i)
set PATH=%PATH%;%pathAppend%
:: The only way to actually modify a command prompt's path via a batch file is by starting
:: up another command prompt window. So we will do this, however, if this script is
:: automatically called on startup of any command prompt window, it will infinately
:: recurse and bad things will happen.
:: If we already ran, we are done
if "%yams%"=="onion" GOTO AllDone
:: Otherwise, flag that we just ran, and then start up a new command prompt window
:: with this flag set
set yams=onion
cmd \K set PATH=%PATH%;
:: When that command prompt exits, it will load back up this command prompt window, and
:: then the user will need to exit out of this as well. This causes this window to
:: automatically exit once the cmd it just spawned is closed.
exit()
:: Path is set up, we are done!
:AllDone
#echo on
And Path.txt will look something like
C:\Program Files (x86)\Google\google_appengine;
C:\Program Files (x86)\ATI Technologies\ATI.ACE\Core-Static;
C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;
C:\Program Files\Microsoft SQL Server\110\Tools\Binn;
C:\Program Files\Microsoft DNX\Dnvm;
C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit;
While Dontsetup.txt will look something like
C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit
C:\Program Files (x86)\Git\cmd
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin
To make this run automatically on startup, open regedit, navigate to HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Command Processor, then right click on the right and press new -> Multi-String Value. Name it AutoRun. Set it's value to
C:\Users\Yams\setUpPath.bat
or wherever else you stored the batch file above.

Didn't try it, but will splitting PATH in parts work and joining them in final variable work?
Example initially let's say you have something like
PATH={LONGPATH1};{LONGPATH2};....{2048th char}....{LONGPATH_N-1};{LONGPATH_N}
Instead you create:
_PATH1 = {LONGPATH1};{LONGPATH2};....{2048 char}
_PATH2 = {2049th char}...{LONGPATH_N-1};{LONGPATH_N}
rem // may be more parts
PATH = %_PATH1%;%_PATH2%

Related

Change the order of executable commands on Windows

Sometimes I need to change the order of an executable command that only shares the name. Let me show you a simple example:
λ where find
C:\Windows\System32\find.exe
C:\Program Files\Git\usr\bin\find.exe
C:\cygwin64\bin\find.exe
On this case, the Windows's 'find' command is called instead of the other two (GNU findutils). My question is quite simple: which is the right way to change the order or set one of them as the first preference?
Go to the environment variables definition of Windows and copy the existing entry for PATH. Create a new variable named BASEPATH and put all entries into it that do not belong to the list of paths where find.exe can be found.
Now create a file called fwin.cmd and put it somewhere on the PATH. The content of that file will look like this:
#echo off
SET PATH=C:\windows\system32;%BASEPATH%
ECHO Set path to search tools like find in Windows own folder
Create two files fgit.cmd and fcyg.cmd and change the PATH accordingly.
From time to time additionally installed applications will change your PATH. If this is the case you will need to add the new entries to the BASEPATH.
Depending on which find.exe you want, open a command line shell of Windows and call the corresponding cmd file. The path set by the batch will be local to the open shell, once you close it the setting will be gone.
You could also address the wanted find.exe directly but this means more typing and is probably not what you want:
dir C:\ /S | C:\Windows\System32\find.exe foo
I solved this by going in the environment variable, search for all path where your exe is and move up and down depending on the preferred order.
Of course this will affect other exe !!!
For this example below I add to move up and down in the system variables PATH and mypath.
C:\Users\duser > where sort
C:\Windows\System32\sort.exe
C:\Program Files\Git\usr\bin\sort.exe
to get
C:\Users\duser > where sort
C:\Program Files\Git\usr\bin\sort.exe
C:\Windows\System32\sort.exe

How to run batch file from network share without "UNC path are not supported" message?

I am trying to run a batch file from a network share, but I keep getting the following message: "UNC path are not supported. Defaulting to Windows directory." The batch file is located on \\Server\Soft\WPX5\install.bat. While logged in as administrator, from my Windows 7 Desktop, I navigate to \\Server\Soft\WP15\ and double click on install.bat, that's when I get the "UNC path are not supported." message. I found some suggestions online stating that mapping drive will not work, but using a symbolic link will solve this issue, but the symbolic link didn't work for me. Below is my batch file content, I would appreciate any assistance that can help me accomplish what I am trying to do. Basically, I want to be able to run the batch file from \\Server\Soft\WP15\install.bat.
Batch file content
mklink /d %userprofile%\Desktop\WP15 \\server\soft\WP15
\\server\soft\WP15\setup.exe
robocopy.exe "\\server\soft\WP15\Custom" /copyall "C:\Program Files (x86)\WP\Custom Templates"
Regedit.exe /s \\server\soft\WPX5\Custom\Migrate.reg
Also, how do I remove the symbolic link after the install is completed?
PUSHD and POPD should help in your case.
#echo off
:: Create a temporary drive letter mapped to your UNC root location
:: and effectively CD to that location
pushd \\server\soft
:: Do your work
WP15\setup.exe
robocopy.exe "WP15\Custom" /copyall "C:\Program Files (x86)\WP\Custom Templates"
Regedit.exe /s WPX5\Custom\Migrate.reg
:: Remove the temporary drive letter and return to your original location
popd
Type PUSHD /? from the command line for more information.
I feel cls is the best answer. It hides the UNC message before anyone can see it. I combined it with a #pushd %~dp0 right after so that it would seem like opening the script and map the location in one step, thus preventing further UNC issues.
cls
#pushd %~dp0
:::::::::::::::::::
:: your script code here
:::::::::::::::::::
#popd
Notes:
pushd will change your working directory to the scripts location in the new mapped drive.
popd at the end, to clean up the mapped drive.
There's a registry setting to avoid this security check (use it at your own risks, though):
Under the registry path
HKEY_CURRENT_USER
\Software
\Microsoft
\Command Processor
add the value DisableUNCCheck REG_DWORD and set the value to 0 x 1
(Hex).
Note:
On Windows 10 version 1803, the setting seems to be located under HKLM:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor
Basically, you can't run it from a UNC path without seeing that message.
What I usually do is just put a CLS at the top of the script so I don't have to see that message. Then, specify the full path to files in the network share that you need to use.
I needed to be able to just Windows Explorer browse through the server share, then double-click launch the batch file. #dbenham led me to an easier solution for my scenario (without the popd worries):
:: Capture UNC or mapped-drive path script was launched from
set NetPath=%~dp0
:: Assumes that setup.exe is in the same UNC path
%NetPath%setup.exe
:: Note that NetPath has a trailing backslash ("\")
robocopy.exe "%NetPath%Custom" /copyall "C:\Program Files (x86)\WP\Custom Templates"
Regedit.exe /s %NetPath%..\WPX5\Custom\Migrate.reg
:: I am not sure if WPX5 was typo, so use ".." for parent directory
set NetPath=
pause
Instead of launching the batch directly from explorer - create a shortcut to the batch and set the starting directory in the properties of the shortcut to a local path like %TEMP% or something.
To delete the symbolic link, use the rmdir command.
I ran into the same issue recently working with a batch file on a network share drive in Windows 7.
Another way that worked for me was to map the server to a drive through Windows Explorer: Tools -> Map network drive. Give it a drive letter and folder path to \yourserver. Since I work with the network share often mapping to it makes it more convenient, and it resolved the “UNC path are not supported” error.
My situation is just a little different. I'm running a batch file on startup to distribute the latest version of internal business applications.
In this situation I'm using the Windows Registry Run Key with the following string
cmd /c copy \\serverName\SharedFolder\startup7.bat %USERPROFILE% & %USERPROFILE%\startup7.bat
This runs two commands on startup in the correct sequence. First copying the batch file locally to a directory the user has permission to. Then executing the same batch file. I can create a local directory c:\InternalApps and copy all of the files from the network.
This is probably too late to solve the original poster's question but it may help someone else.
This is the RegKey I used:
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor]
"DisableUNCCheck"=dword:00000001
My env windows10 2019 lts version and I add this two binray data ,fix this error
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Command Processor DisableUNCCheck value 1
Computer\HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\Command Processor
DisableUNCCheck value 1
This is a very old thread, but I still use Windows 7. :-)
There is one point that no one seems to have taken into account, which probably would help Windows 10 users also.
If Command Extensions are enabled, the PUSHD command accepts network paths in addition to the normal drive letter and path.
So the obvious - and simplest - answer might be to enable command extensions in the batch script, if you intend to use PUSHD. At the very least, this ought to reduce the problems you might have in using PUSHD wqith a network path.
I stumbled upon this question while searching for a solution to a specific problem. I needed to make a batch script that sits in a network folder (UNC path) with a Python script. The goal was to be able to double click on the batch script and have it run the Python script:
with the network folder containing the script as the working directory,
without modifications to the Python script (no command line parameters or hard-coded paths).
without creating another Python file.
The pushd and popd solutions were unsatisfactory. They work, but if the user were to get in the habit of forcefully terminating the script while it was running, they would end up with a bunch of mapped drives in My Computer since popd wasn't run.
I start by using cls to clear the UNC path error. I then assign the path containing the batch script to a variable. I slice the path to remove the trailing backslash (otherwise, Python throws a SyntaxError). Finally, I run a couple Python commands inside the batch file that change the working directory and execute the target script:
cls
#echo off
set pyfile=myscript.py
set batchdir=%~dp0
set wdir=%batchdir:~0,-1%
python -c "import os; import runpy; os.chdir(r""%wdir%""); runpy.run_path(r""%pyfile%"")"
pause
Editing Windows registries is not worth it and not safe, use Map network drive and load the network share as if it's loaded from one of your local drives.

Batch: Running exe, copying file to appdata, and put it in startup

For example, I have 2 exe's. Let's call them 1.exe and 2.exe, to keep it simple.
And I want to make a zip file, with 3 things in it, 1.exe, 2.exe and setup.bat.
First off, I want to know that the user is okay that we start the first exe (1.exe). So we type:
#echo off
cls
echo Are you sure you want to install 1.exe?
echo If not, click exit right now. If you are okay with it,
pause
Here comes the first question. So we want to start 1.exe. How do I start 1.exe, that is in the same folder as the bat file?
Okay, lets continue. When 1.exe is finished, I want to copy 2.exe, place it in %appdata%, and then add it to startup. And that's the second question. How do i do that.
So the questions are:
How do I start 1.exe, which is in the same map as setup.bat
How do I copy 2.exe which is in the same map as setup.bat to %appdata%
How do I properly add 2.exe which is in %appdata% now to startup?
Note: Just using C:\documents and settings\all users\desktop\1.exe isn't going to work. I want it to work in all sorts of languages, and in some languages the folders might be called different.
1.exe will run 1.exe, just like on the command line.
copy 2.exe %appdata% will copy 2.exe.
I don't know what question 3 means.
Define "work in all sorts of languages"? If you need to pass in an argument to the batch file, do so: http://commandwindows.com/batch.htm
You are right you should never hard code "Documents and Settings" or "Program Files" in a BAT file, because these folder names don't "work in all sorts of languages". You need to refer to them using special folder ids or environment variables.
In your case, you need to create a program shortcut (.LNK file) in the startup folder. There are two parts.
creating a shortcut. Unfortunately there is no way to create a shortcut using only windows commands. You need to rely on a third party tool, there are many free command line tools that may do it; or write your own.
locating the Startup folder and placing the shortcut there. There are two startup folders. The common startup and the user startup folder. Choose one. Then, you need to use either the %ALLUSERSPROFILE%\Start Menu\Programs\StartUp or the %USERPROFILE%\Start Menu\Programs\StartUp.
So putting all pieces together in your SETUP.BAT , it would look something like this...
#echo off
echo Are you sure you want to install 1.exe?
echo If not, click exit right now. If you are okay with it,
pause
1
copy 2.exe %appdata%
makelink %appdata%\2.exe %USERPROFILE%\Start Menu\Programs\StartUp\2.lnk
One suggestion. Avoid all this mess. It seems to me that you need to install a program. If so, I'd recommend you to try Inno Setup. http://www.jrsoftware.org/ .
Inno Setup is a free installer for Windows. First introduced in 1997, Inno Setup today rivals and even surpasses many commercial installers in feature set and stability.
...
Supports creation of a single EXE to install your program for easy online distribution. Disk spanning is also supported.
Standard Windows 2000/XP-style wizard interface.
Customizable setup types, e.g. Full, Minimal, Custom.
Complete uninstall capabilities.
Installation of files: Includes integrated support for "deflate", bzip2, and 7-Zip LZMA/LZMA2 file compression. The installer has the ability to compare file version info, replace in-use files, use shared file counting, register DLL/OCX's and type libraries, and install fonts.
Creation of shortcuts anywhere, including in the Start Menu and on the desktop.
Creation of registry and .INI entries.
Running other programs before, during or after install.
...
This should do what you want.
#echo off
cls
echo Are you sure you want to install 1.exe?
echo If not, click exit right now. If you are okay with it,
pause
start /wait 1.exe
xcopy 2.exe %appdata% /y
reg add HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Run /v "2" /d %appdata%\2.exe
The last line will make a reg entry instead of copying it to the startup folder which will not create a shortcut on the desktop and you don't need anything more than batch.

CMD: Bat to Exe Converter - Temp directory problem

i am using 'Bat to Exe Converter' to convert my batch files to exe format.
Now, i am running into some problems.
Whenever i convert something, and i set 'Working Directory' to 'Current Directory', and i start my exe in echo on mode, this is what i end up with to check if there is a specific file in the directory of my exe:
the actual command: if not exist "%~dp0\file.txt" goto :nofile
output: if not exist "C:\Users\MyUser\AppData\Local\Temp\4CBC\\file.txt" goto :nofile
Can anyone help me with this? I don't want it in the temp directory, i want it to be in the directory of my exe.
Thanks.
Without having Bat to Exe changed by the author, I think you have two options:
Remove the need for accessing %~dp0
Perhaps you can merge file.txt with the include option of Bat to Exe into the EXE file. If so, "file.txt" will automatically be unpacked in the current directory when running your compiled exe, and you can it access by %CD%\file.txt.
Get %~dp0 from outside and pass it to the exe as a command line parameter.
This can be done by a simple starter bat file that resides in the same directory as your compiled main batch file. This script schould contain the line
YourCompiled.Exe %~dp0% %%*
Your compiled exe then gets its directory from %1. So you cannot pack everything into one exe, but the main portion of it, perhaps that is sufficient for you.
Well, apparently your batch to exe converter simply packs the batch file and extracts it to a temporary directory prior to execution. Very simplistic, hard to get wrong (compared to actually understand the batch file) but it introduces errors such as the one you're describing.
Your best bet is probably to use another batch to exe converter; some of them are actually a little more sophisticated.
Generally, this is not a good idea. firstly, its prone to errors and instability of the converter on different cmd features. secondly, a determined hacker can still decode what you are doing with the batch. My suggestion, if you are so afraid of people looking into your batch,
1) let only the people who are authorized to use your batch to use it
2) give them the correct permissions.
OR, don't use batch at all
1) create a central interface such as a web interface, where all tasks to be done goes through that interface, like using an ATM machine where only buttons are allowed and all the available user options can be done by pushing buttons...etc..
2) authenticate your users through a central authentication system, eg Active Directory, or LDAP or a database.
This is an 2.5 yr old subject but there is an answer to this so I'm posting for anyone else that happens to find this in a search.
B2EC written by Fatih Kodak, has an option to "Submit current directory".
When this is used, you can reference %1 in your batch file to get the path of the EXE that was executed (instead of the path of the extracted BAT that is really being run).
Hovering over that option in the UI shows "Submit the current working directory as the last parameter". The "last parameter" in my use has always been %1 but you can test your code to be sure.
The latest version, 2.1.4 at time of writing, of Bat to Exe by Fatih Kodak creates an Environmental Variable at runtime that can be substituted in place of %~dp0 to reference the Exe's path. Therefore, you can simply replace %-dp0 with %b2eprogrampathname% in the original batch file.
You can use external folders with f2ko's batch to exe converter. Having
a separate folder for subroutines can neaten up a project folder.
To call mysubroutine that is located in mysubroutinesfolder\mysubroutine,
...
pushd mysubroutinesfolder
call mysubroutine
popd
...
The call can be made a one liner:
call xqt mysubroutine
where xqt.cmd is a program that does the call for you:
pushd mysubroutinesfolder
call %*
popd
exit /b
(the %* means "all of the arguments").
In this way your batch programs run as batch, and UNMODIFIED they will
compile with the bat to exe converter, creating a completely folder independent executable. Select "temporary directory",
and include all of the subroutines/executables in your mysubroutines folder
by "selecting them all" with your cursor as usual, then hit "copy".
Be sure to include the xqt.cmd program too; place it "outside" of your mysubroutines folder. Make sure that is is accessible by your main program. Remember to select x64 if you
are runnning on a x64 machine, or the executable will not find SYSTEM32
files. You can find f2k0's batch to exe converter at:
http://www.f2ko.de/programs.php?pid=b2e
Try this development environment for batch scripts, Batch Compiler . It has everything you need to develop a batch program.And compile into stable stand alone executable (Exe).
Friendly user interface.
Debugger, Check your code for syntax errors.
Powerful, versatile compiler.
Allows mouse input in batch files.
Use Windows Common Dialog Boxes.(BrowseFiles,BrowseFolders)
Draw graphics in batch files.
Reverse engineering proof encryption of source code.
Include Company name, Copyright info and Version info.
Make invisible(silent) executables.
Executables with administrator privileges.
Run & debug your script while editing.
Embed resources with executable.(music,images,files)
Advance Commands (BrowseFiles,LaunchSilent,MouseCMD)
Stand-alone executables.No dependencies needed.
Executables are woking on almost all windows operating systems.(98 to 10)
Quick download : http://bc.gotek.info/files/BatchCompiler159.zip
Cheers!
%cd% will give you the current directory:
if not exist "%CD%\file.txt" goto :nofile
Use %CD% instead of %~dp0.
EDIT:
B2EC is not a real converter. Creation location of equipped .cmd file was chosen to be %TEMP% and this is a good choice. Application just lacks 3rd option for working directory of the script - .exe file directory. I advise you to mail the author about adding this one.
Different paths for .exe and created .cmd lead to information loss, i.e. we are unable to know .exe directory and current directory at the same time without providing additional information to the script (e.g. using environment variable or passing it as first/last argument to the script). This script would need to handle it and we would end writing cmd scripts tailored for this converter, which is bad.
%~dp0 - script directory (%TEMP%/.../) - practically useless
%cd% - working directory (as set up in the converter) - currently there are only 2 options: current directory (working directory of .exe) and temporary directory (actually equal to %~dp0, but without trailing backslash)
I think it can be solved by patching cmd.exe instance in memory to change the script path, but that's B2EC developer's duty.
Side note: Normal executable files can be easily executed with specified 0th argument by providing appriopriate lpApplicationName and lpCommandLine to CreateProcess function. Command files are executed via cmd.exe, so 0th argument cannot be set this way.

How do I specify C:\Program Files without a space in it for programs that can't handle spaces in file paths?

A configuration file needs position of another file,
but that file is located in "C:\Program Files",
and the path with space in it is not recognized,
Is there another way to specify the location without space in it?
you should be able to use
"c:\Program Files" (note the quotes)
c:\PROGRA~1 (the short name notation)
Try c:\> dir /x (in dos shell)
This displays the short names
generated for non-8dot3 file names.
The format is that of /N with the
short name inserted before the long
name. If no short name is present,
blanks are displayed in its place.
Never hardcode this location. Use the environment variables %ProgramFiles% or %ProgramFiles(x86)%.
When specifying these, always quote because Microsoft may have put spaces or other special characters in them.
"%ProgramFiles%\theapp\app.exe"
"%ProgramFiles(x86)%\theapp\app.exe"
In addition, the directory might be expressed in a language you do not know. http://www.samlogic.net/articles/program-files-folder-different-languages.htm
>set|findstr /i /r ".*program.*="
CommonProgramFiles=C:\Program Files\Common Files
CommonProgramFiles(x86)=C:\Program Files (x86)\Common Files
CommonProgramW6432=C:\Program Files\Common Files
ProgramData=C:\ProgramData
ProgramFiles=C:\Program Files
ProgramFiles(x86)=C:\Program Files (x86)
ProgramW6432=C:\Program Files
Use these commands to find the values on a machine. DO NOT hardcode them into a program or .bat or .cmd file script. Use the variable.
set | findstr /R "^Program"
set | findstr /R "^Common"
Use the following notations:
For "C:\Program Files", use "C:\PROGRA~1"
For "C:\Program Files (x86)", use "C:\PROGRA~2"
Thanks #lit for your ideal answer in below comment:
Use the environment variables %ProgramFiles% and %ProgramFiles(x86)%
:
I think the reason those suggesting using the C:\PROGRA~1 name have received downvotes is because those names are seen as a legacy feature of Windows best forgotten, which may also be unstable, at least between different installations, although probably not on the same machine.
Also, as someone pointed out in a comment to another answer, Windows can be configured not to have the 8.3 legacy names in the filesystem at all.
There should be a way to use the full c:\program files path directly. Often, it involves encapulating the string in quotes. For instance, on the windows command line;
c:\program files\Internet Explorer\iexplore.exe
will not start Internet Explorer, but
"c:\program files\Internet Explorer\iexplore.exe"
will.
The Windows shell (assuming you're using CMD.exe) uses %ProgramFiles% to point to the Program Files folder, no matter where it is. Since the default Windows file opener accounts for environment variables like this, if the program was well-written, it should support this.
Also, it could be worth using relative addresses. If the program you're using is installed correctly, it should already be in the Program Files folder, so you could just refer to the configuration file as .\config_file.txt if its in the same directory as the program, or ..\other_program\config_file.txt if its in a directory different than the other program. This would apply not only on Windows but on almost every modern operating system, and will work properly if you have the "Start In" box properly set, or you run it directly from its folder.
No.
Sometimes you can quote the filename.
"C:\Program Files\Something"
Some programs will tolerate the quotes. Since you didn't provide any specific program, it's impossible to tell if quotes will work for you.
I think that the other posts have answered the question, but just some interesting for your information (from the command prompt):
dir c:\ /ad /x
This will provide a listing of only directories and also provide their "Short names".
You could try to use:
C:\PROGRA~1
As an alternative to the other answers, you can try symbolic links.
Create the symbolic link first and install the application based on the link. (Depending on the case, this may be way easier to do, for instance when the application has n mentions of the target folder throughout its code)
A symbolic link will create something similar to a shortcut to a folder, but seen as an actual folder by other applications.
This is how you do it:
Run cmd as administrator
User this command: mklink /D "C:\LinkToProgramFiles" "C:\Program Files"
And then, you start using "C:\LinkToProgramFiles" in the applications that can't handle spaces. (This link can be seen in Windows Explorer as a folder with the symbol of a shortcut)
Be very careful not to create circular links if you start playing too much with this.
Try surrounding the path in quotes. i.e "C:\Program Files\Appname\config.file"
You can use the following methods to specify C:\Program Files without a space in it for programs that can't handle spaces in file paths:
'Path to Continuum Reports Subdirectory - Note use DOS equivalent (no spaces)
RepPath = "c:\progra~1\continuum_reports\" or
RepPath = C:\Program Files\Continuum_Reports 'si es para 64 bits.
' Path to Continuum Reports Subdirectory - Note use DOS equivalent (no spaces)
RepPath = "c:\progra~2\continuum_reports\" 'or
RepPath = C:\Program Files (x86)\Continuum_Reports 'si es para 32 bits.
Either use the generated short name (C:\Progra~1) or surround the path with quotation marks.
You can just create a folder ProgramFiles at local D or local C to install those apps that can be install to a folder name which has a SPACES / Characters on it.

Resources