I want to call a batch file in my post build step in Visual Studio. Locally the batch file exists, just the command
call "$(SolutionDir)PostBuildSen.bat" "$(TargetDir)" "$(TargetName)"
correctly calls and executes the batch file.
However when I want to check if the batch file exists first (since others will use the same Post Build Event), I get the error
:VCEnd" exited with code 255.
The command is
if exists "$(SolutionDir)PostBuildSen.bat" call "$(SolutionDir)PostBuildSen.bat" "$(TargetDir)" "$(TargetName)"
The Diagnostic output tells me
2> Done executing task "Exec" -- FAILED.
How do you handle this?
The Solution Directory contains a folder with an underscore, i.e. \Dev_Main\ and I have read that for the batch file that is to be called at least that doesn't work. However I am not sure if that is the issue with folders as well and how to cope with it. Also, since the call command works, I am not sure this is the problem.
Furthermore, if I replace the call with cmd /C, the exit code is 1 and the (minmal) output tells me
1>The filename, directory name, or volume label syntax is incorrect.
Also, I will add this as a custom command to a CMakeLists file later on, so the solution needs to work with that.
Thanks to Hans Passant's comment, I solved the problem. The query for the file needs to be if exist rather than if exists.
Related
ok...Im a new member here and I can express how jolly I am...back to subject
I made a bat file, lets call it 1.bat and I used iexpress to make it an exe file, lets call it 1.exe.
So, in the batch file I added the command line to add a vbs file ( call it 1.vbs ) which is also included in the exe package (1.bat and 1.vbs are in 1.exe) but it installs 1.bat, so in the command I typed:
copy "1.vbs" "C:\Users\%username%\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup"
If I run the bat file it copies the vbs file to start up, but if I make the 1.exe file in iexpress by including 1.bat and 1.vbs and when I click the 1.exe file, it doesnt work, it doesn't copy the vbs file to startup, it says something about too many parameters.
I'm sorry if my post is too long or my question have been posted before, but I couldn't found any thread solves my issues, if there is, i'd be glad to be enlightened.
Thanks.
Never use "Batch to EXE" converter, they often do not work as expected. Simply use the batch script.
Just a note, this file actually only acts as a wrapper for your script, and the script itself actually gets executed in a temp folder created on execution (and deleted afterwards), so make sure you don't use any relative paths.
source
When running a batch file in IExpress, you need to call it like:
cmd /c 1.bat
If you don’t, variables like %username%, long file names, etc, will likely not work.
I suspect you are using short file names. Put in your bat dir then pause and you'll see it's 1~1.vbs or similar.
My goal is copying an .exe file from a bin folder of solution A to another solutions B resource folder on the post build event of solution A.
I created the necessary xcopy command and tried it out in powershell: It works perfectly.
Whenever I add any command to the actions in VS build fails with: "#command# exited with code 1", where #command# is, for example, the xcopy command.
I tried running VS as admin and currently I tried just running a .bat file that contains "#echo off #exit 0". That too leads to "#command# exited with code 1".
Have some example of what I tried out as VS post/pre-build command:
call "projdir\test.bat"
call projdir\test.bat
"projdir\test.bat"
projdir\test.bat... I tried projdir as "$(ProjectPath)" and manual path.
I put output to verbose and found the following:The command "C:\Users\Traubenfuchs\AppData\Local\Temp" is written incorrectly or couldn't be found. (That folder actually exists but I don't know what it wants to do it.)The same thing happens when I put an xcopy command in pre/post build.
Anyone knows what I am doing wrong?
Recently I met similar problem.
About your "hello world" post-build event :
try to call powershell directly
powershell -command "write-output 'hello world'; exit 0"
=================
My pre-build event looks like :
powershell -file scriptPath.ps1
My scriptPath.ps1 looks like :
<my epic powershell code>
...
exit 0
Note that without "exit 0" at the end I recieved return code 1 from my script.
We had this issue because of a "Software Restriction Policy" set up in a domain GPO. It appears that pre and post builds create a .cmd batch file in the temp folder. Here's what the logging showed me:
cmd.exe (PID = 8456) identified
C:\Users\brian\AppData\Local\Temp\tmp733425d2c0604973a90a0a175c13353e.exec.cmd
as Disallowed using default rule, Guid =
{11015445-d282-4f86-96a2-9e485f593302}
To fix this we modified the GPO that controlled the SRP so that it did not include .cmd files. After all, the goal of SRP is to block executable malware, not batch files. I may get some security blowback because of this. Hopefully someone knows a better way to fix this issue.
One possible issue is that you have to use $(ProjectDir) instead of $(ProjectPath)
When you use $(ProjectPath) it is actually: "C:\Users\....\Project\MyProject.csproj"
Versus $(ProjectDir) which is: "C:\Users\....\Project\"
Notice, that the first version is actually pointing to your project solution file... which would cause everything to fail.
Another is that that $(ProjectDir) automatically adds the trailing slash to the path. i.e. "$(ProjectDir)\test.bat" would actually translate to: "C:\Users\....\Project\\test.bat"
Also you have to make sure that you enclose all your file paths in double quotes
So the correct call would look like this:
call "$(ProjectDir)test.bat"
Other things to check out would be to make sure that the directory that the script is executing from is correct. See SO: visual studio 2012, postbuild event, bat file not creating new file (not executing)
Have you checked out the suggestions in this StackOverflow? Post Build exited with code 1
Edit
Try this:
echo Hello World
#exit 0
You need to end any commands with #exit 0 otherwise it doesn't think that it finished properly
Edit 2
Why do we use #exit 0 instead of exit 0? #Sunny has a good explanation of the At symbol - # here:
The # symbol tells the command processor to be less verbose; to only
show the output of the command without showing it being executed or
any prompts associated with the execution. When used it is prepended
to the beginning of the command, it is not necessary to leave a space
between the "#" and the command.
Essentially if you call xyz.bat by default every command in the .bat file is echoed back along with the actual output of the command. e.g.:
test.bat
echo Hello World
exit 0
Will output:
C:\>call test.bat
C:\>echo Hello World
Hello World
C:\>exit 0
C:\>
When we add a # in front of the commands, we only get the output of the commands themselves.
test2.bat
#echo Hello World
#exit 0
Will output:
C:\>call c.bat
Hello World
C:\>
#echo off is also a way to turn this off for the rest of the script. We typically do this simply to make the logs easier to read, as the text of the commands muddies the log output.
I run a batch file as an external tool (by adding it in Tools->External tools) in VS2010 (I've checked the "Use Output Window" option). This batch file performs compilation as in VS command prompt. The project that I'm working on has makefiles for various folders, so I use the mk command to build.
In the batch file, I set up the VS environment and then run the following commands:
cd $directoryWhichContainsFileToBuild
mk
cd main //This directory contains the executable that is to be built
mk
I see the output of the first mk in the Output window but after that it just hangs. I also tried to use an echo after the first mk but even that doesn't get printed in the output window (the ones before it can be seen).
Somewhere I read that there is an issue with VS 2010 output window where it hangs after showing some output, although I couldn't really be sure that that is what's the issue here.
Do I need to enable some other VS setting? Has anybody else encountered this issue?
Thanks.
Update: I unchecked the "Use Output Window" and "Close on exit" option, and I see an extra statement: "Press any key to continue". On doing that however, their is no further processing of the batch file.
Update2: Got it to work by prefixing mk with "call".
Thanks all who tried.
It is always good in batch files to specify executables with full path and file extension instead of just the file name. This avoids often lots of problems.
Here was just mk used instead of mk.bat. Therefore on every compile the command line processor cmd.exe searches for mk.* and then checks if any of the found files have an extension listed in environment variable PATHEXT. The order of file extensions separated by a semicolon in PATHEXT defines the order of execution in case of a directory contains multiple mk.* files.
If a command being specified in a batch file not being an internal command of cmd.exe without path, command line processor searches first for a file with given name in current working directory. This is often one more cause of error. What is the current working directory on execution of the batch file?
Next if no file to execute can be found in current working directory, the command line processor searches in all folders being listed in environment variable PATH separated by semicolons.
So specifying in batch files edited only rarely an external application or another batch file with full path, file name and file extension, in double quotes if necessary because of 1 or more spaces in path or file name, helps command line processor to more quickly execute that application or batch file and avoids problems because of executable not found (unknown command).
Sure, when typing commands in a command prompt window, nobody wants to enter the executables with full path, name and extension. But for batch files it is always good to be not lazy and type files to be executed with full path and extension.
TripeHound has given already the explanation why the observed behavior occurred here.
If a batch file is executed from another batch file without using command call, the command line processor continues batch execution in the other batch file and does never come back. In a C/C++ program this is like using goto with the difference that parameters can be passed to the batch file containing the further commands to be executed next.
But running from within a batch file another batch file with call results in continuation of execution below the line calling the other batch file once the other batch file reaches end, except command exit is used in the called batch file without parameter /B.
So the solution here is using:
cd /D "Directory\Which\Contains\File\To\Build"
call "Path\Containing\Batch\File\To\Build\mk.bat"
rem With mk.bat not changing current working directory change working
rem directory to the directory containing the executable to be built.
cd main
call "Path\Containing\Batch\File\To\Build\mk.bat"
BTW: exit exits command processor, exit /B exits just current batch file. I'll give you three guesses why the parameter is B and not a different letter. Yes, B is the first letter of batch.
Writing as a separate answer instead of an update in the question itself as many readers see the header and skim to the answer: got it to work by prefixing mk with "call". (#TripleHound has also posted the conceptual reason for it in the comment above.)
I've read this discussion but despite different attempts, I get an error (it varies depending on my approach).
The compilation itself works fine. Double-clicking on the "publish.bat" files executes it just fine too. It's the combo in VS10 that breaks.
This is what I've tested.
$(OutDir)\publish.bat
"$(OutDir)\publish.bat"
$(OutDir)publish.bat
"$(OutDir)publish.bat"
call $(OutDir)\publish.bat
call "$(OutDir)\publish.bat"
call $(OutDir)publish.bat
call "$(OutDir)publish.bat"
What am I missing?
I had a similar problem that I was just able to fix. For me the simple call "$(SolutionDir)\Setup\CreateInstaller.bat" worked, but I kept getting a The command "call {solution directory}\Setup\CreateInstaller.bat" exited with code {code}. Turns out my batch file was expecting to be run from the directory in which it lived. So, check that all the commands in the batch file are not using relative directories or commands as these may break.
Also, are you sure the $(OutDir) macro is what you want? In VS2010 at least, that is just equal to bin\Debug or bin\Release depending on which version you're building in. It seems unlikely that you really want that directory. I expect what you want is $(SolutionDir) or perhaps even $(TargetDir).
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.