I have a very annoying problem regarding dotfuscator and paths with spaces. I have a .bat file that is called via post-build event with the following syntax:
call "$(SolutionDir)..\Build\dotf.bat" $(SolutionDir) $(ConfigurationName) $(TargetPath) $(TargetDir).
The .bat file looks like this:
SET DOTFPATH="%1..\Tools\DotfuscatorProEdition4.13.0\dotfuscator.exe"
SET DEBUG=%2
SET TARGETFILE=%3
SET OUTPUT=%4
if "%DEBUG%" == "Release" (
%DOTFPATH% /q /in:"%TARGETFILE%" /out:"%OUTPUT%"
) ELSE (
echo DOTFUSCATOR: Skipped due to debugmode
)
The .bat file recieves the arguments and generates a command like this:
"C:\some\path\to\dotfuscator.exe" /q /in:C:\a\path\toproject\Mydll.dll /out:C:\a\path\toproject\
the .bat file works great locally. But on the buildserver the solution and project paths have whitespaces, like this:
"C:\some\path\to\dotfuscator.exe" /q /in:C:\a\path\to project\Mydll.dll /out:C:\a\path\to project\
which ofcourse messes up the arguments. So, i tried to enclose the paths with quotationmarks like this:
"C:\some\path\to\dotfuscator.exe" /q /in:"C:\a\path\to project\Mydll.dll" /out:"C:\a\path\to project\"
This fixes the .bat file and the argument parsing, but dotfuscator itself is now failing miserably!
Dotfuscator now complains about "Illegal characters in path". How do i fix this?
If the path contains spaces then the parameters passed to the bat file should already be protected with quotes. So you're probably creating /in:""c:\some path"" which won't work. First try removing the quotes on your dotfuscator line in the bat file.
Alternatively, try changing to the directory and back instead of trying to work out dotfuscator. You'd need to change the 3rd parameter also from targetpath to targetfile
SET DOTFPATH="%1..\Tools\DotfuscatorProEdition4.13.0\dotfuscator.exe"
SET DEBUG=%2
SET TARGETFILE=%3
SET OUTPUT=%4
if "%DEBUG%" == "Release" (
pushd %OUTPUT%
%DOTFPATH% /q /in:%TARGETFILE% /out:.
popd
) ELSE (
echo DOTFUSCATOR: Skipped due to debugmode
)
Related
Windows .Bat file behave differently when executed from command window and by double clicking on the bat file. This is my file:
ECHO ON
del activity_ftp.log
cd D:\My_Test
IF EXIST united_ops*.csv (
for %%i in (united_ops*.csv) do (
set size=0
set /A size=%%~zi
echo %%i,%size%,397312,624640 > D:\My_Test\activity_ftp.log
)
)
When I run this by opening command window and calling it,
There are some issues in your code.
cd d:\My_test will only work if you are on D:, you could use cd /d or pushd here.
echo ...%size% doesn't work, as it's expands when the for block is parsed not when it's executed.
The if exist seems to be redundant, as the for %%i in ( united_ops*.csv) only expands if any file exists.
ECHO ON
setlocal EnableDelayedExpansion
del activity_ftp.log
pushd D:\My_Test
for %%i in (united_ops*.csv) do (
set size=0
set /A size=%%~zi
echo %%i,!size!,397312,624640 > D:\My_Test\activity_ftp.log
)
Building on jeb's answer.
1) Your FOR loop may iterate through many files that match your pattern. But you use the overwrite mode of file redirection. Each found file will over-write the output for the prior file. Your final output file will never have more than one line. You could change to the append mode using >>, but there is a better way. It is faster to enclose the entire loop in parentheses and redirect once in overwrite mode using >.
2) You are setting size to 0, then setting it to the file size, and then you don't use it after the line is echoed. I suspect you don't need the variable at all, so you don't need delayed expansion.
3) The file you delete at the top does not include the path information, so it may not be deleting from the correct folder. Even if it were, it is unnecessary since you are redirecting in overwrite mode anyway.
4) Instead of changing the current directory you could include the path in the FOR statement.
ECHO ON
>"D:\My_Test\activity_ftp.log" (
for %%i in ("d:\My_Test\united_ops*.csv") do (
echo %%~nxi,%%~zi,397312,624640
)
)
I want to copy all the *.jar files to another directory i wrote the below script
echo Enter path to ILM_HOME:
set /p ILM_HOME=
echo Deployment in progress
copy WEB-INF/lib/*.jar "%ILM_HOME%"/webapp/WEB-INF/lib
I use C:\Documents and Settings\asimon\Desktop\test as my input
It gives me syntax of the command is incorrect
I think the problem is Documents and Settings I even put "%ILM_HOME%" and I don't need c:\Docume~1\asimon\Desktop\test any other solution?
Update
This is working
#echo off
echo
echo Enter path to ILM_HOME:
set /p ILM_HOME=
IF EXIST "%ILM_HOME%\stopApplimation.bat" (
echo Deployment in progress
xcopy WEB-INF\lib\*.jar "%ILM_HOME%\webapp\WEB-INF\lib"
CALL "%ILM_HOME%\stopApplimation.bat"
CALL "%ILM_HOME%\startApplimation.bat"
) ELSE (
echo %ILM_HOME% path is incorrect.
)
also any linux solution is also helpfull with .sh for the below 2 statements
"%ILM_HOME%/stopApplimation.bat"
"%ILM_HOME%/startApplimation.bat"
for linux, how can i replace the above 2 statements?
$ILM_HOME/stopApplimation.sh
$ILM_HOME/startApplimation.sh
Did you try
xcopy WEB-INF\lib\*.jar "%ILM_HOME%\webapp\WEB-INF\lib"?
EDITED:
In your batch use CALL "%ILM_HOME%\stopApplimation.bat"
Windows x64 versions contain folders named with parenthesis like "\Program Files (x86)" and this breaks a batch file I use. An example of a problem line:
for %%c in (%path%) do if exist "%%c\xyz.exe" set xyz=OK
i.e. when it reaches ")" in "(x86)" it puts out an error message and exits...
Any ideas on how to fix this?
This is a rather large batch file, and atm I don't have the time to rewrite it in a better language...
Many thanks :)
Doesn't directly answer your question, but if you are trying to do what I thinking you are trying (which is make sure a file exists in the path) you can use something like the following in a batch file.
#echo off
for %%i in (xyz.exe) do set xyz=%%~$PATH:i
if "%xyz%" == "" Goto NotFound
Echo "Found"
Goto TheEnd
:NotFound
Echo "Not found"
:TheEnd
Normally quoting should work, but in this case you want to iterate over all elements seperated by ;.
But you can replace the ; to a " " combination, so the brackets are quoted and you can iterate over the elements.
sample: path=C:\temp;C:\windows;C:\Program Files (x86)
The for-loop will search in
"C:\temp" "C:\windows" "C:\Program Files (x86)"
As code it looks like
setlocal EnableDelayedExpansion
set "searchPath=!path:;=" "!"
for %%c in ("!searchPath!") do (
if exist "%%~c\xyz.exe" set xyz=OK
)
You can use the short names of the folder for this purpose. This is how you do it.
Open command promt in Windows.
Go to C drive (or the drive in which you have the Program Folder)
Type the following and
c:\> dir /x <Hit Enter>
This will return the short forms of all folders.
You will notice now that "\Program Files (x86)" will be represented as "PROGRA~2" (or an equivalent short name).
This is what I use to prevent any errors while creating Batch scripts.
For more options see here.
http://www.computerhope.com/dirhlp.htm
Exlpanation for "dir /x"
"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."
I am looking for the shortest amount of code possible that will get the first line of a text file and set it to a variable in Windows.
There are lots of examples of this kind of thing in other threads on this StackExchange site but I am not looking for how to loop through and display all lines in a file. What I want is to just simply get the first line.
set /p var= <Text.txt
echo %var%
Referenced from: http://forums.techguy.org/software-development/551867-batch-file-read-line-text.html
Ironically the poster is able to get the first line but wanted to loop through the whole file!
This is just a slightly shorter version:
set/pz=<file
echo %z%
If delayed expansion has been enabled before (Setlocal EnableDelayedExpansion or cmd started with /V:ON option) then there's a shorter (one-liner) version
set /pz=<filename.txt&echo !z!
I couldn't get this to work under Windows 7; the variable was simply not set. But here's a slightly longer solution:
for /F "delims=" %%i in (Text.txt) do (
set Z=%%i
goto BREAK1
)
:BREAK1
echo %Z%
I had to change the line of file for a text file inside Program Files(x86) directory. After trying a lot of solutions, the following solution worked for me:
Steps:
Use type command piped with findstrto get a file with the desired data
Delete the original file
Use type command to move the content back to the file with the original file name
Delete the new file
Example:
#echo off
set originalFile="C:\Program Files (x86)\<Target File Path>\<Target File Name>"
set newFile="C:\Program Files (x86)\<Target File Path>\<Target newFile Name>"
if exist %originalFile% (
type %originalFile% | findstr /v T4VSHost >> %newFile%
del %originalFile% /F /Q
type %newFile% >> %originalFile%
del %newFile% /F /Q
)
#echo on
Note:
When I tried writing the change back to the original file in step 1, the result was a an empty file.
Note the string I am matching is T4VSHost, which occurs in the file at path C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\Extensions\Microsoft\Entity Framework Tools\Templates\Includes\EF6.Utility.CS.ttinclude
just FYI...
I tried it and didn't work. But I realized finally that I had to reproduce the text file (originally the text file is generated by a powershell script) so when I did this and it works.
:: output to different file
Type Text.txt > text2.txt
Then apply the same code (change text.txt to text2.txt)
set /p var= <Text2.txt
echo %var%
If I use the original one, I would either get garbage in %var%, not sure if the text file has not <CR> or what. Anyway, by reproducing the text file, it seems working fine.
I'm looking for a simple way to test if an executable exists in the PATH environment variable from a Windows batch file.
Usage of external tools not provided by the OS is not allowed. The minimal Windows version required is Windows XP.
Windows Vista and later versions ship with a program called where.exe that searches for programs in the path. It works like this:
D:\>where notepad
C:\Windows\System32\notepad.exe
C:\Windows\notepad.exe
D:\>where where
C:\Windows\System32\where.exe
For use in a batch file you can use the /q switch, which just sets ERRORLEVEL and doesn't produce any output.
where /q myapplication
IF ERRORLEVEL 1 (
ECHO The application is missing. Ensure it is installed and placed in your PATH.
EXIT /B
) ELSE (
ECHO Application exists. Let's go!
)
Or a simple (but less readable) shorthand version that prints the message and exits your app:
where /q myapplication || ECHO Cound not find app. && EXIT /B
for %%X in (myExecutable.exe) do (set FOUND=%%~$PATH:X)
if defined FOUND ...
If you need this for different extensions, just iterate over PATHEXT:
set FOUND=
for %%e in (%PATHEXT%) do (
for %%X in (myExecutable%%e) do (
if not defined FOUND (
set FOUND=%%~$PATH:X
)
)
)
Could be that where also exists already on legacy Windows versions, but I don't have access to one, so I cannot tell. On my machine the following also works:
where myExecutable
and returns with a non-zero exit code if it couldn't be found. In a batch you probably also want to redirect output to NUL, though.
Keep in mind
Parsing in batch (.bat) files and on the command line differs (because batch files have %0–%9), so you have to double the % there. On the command line this isn't necessary, so for variables are just %X.
Here is a simple solution that attempts to run the application and handles any error afterwards.
file.exe /? 2> NUL
IF NOT %ERRORLEVEL%==9009 ECHO file.exe exists in path
Error code 9009 usually means file not found.
The only downside is that file.exe is actually executed if found (which in some cases is not desiderable).
This can be accomplished via parameter substitution.
%~$PATH:1
This returns the full path of the executable filename in %1, else an empty string.
This does not work with user-defined variables. So if the executable filename is not a parameter to your script, then you need a subroutine. For example:
call :s_which app.exe
if not "%_path%" == "" (
"%_path%"
)
goto :eof
:s_which
setlocal
endlocal & set _path=%~$PATH:1
goto :eof
See http://ss64.com/nt/syntax-args.html
For those looking for a PowerShell option. You can use the Get-Command cmdlet passing two items. First give the current dir location with .\ prefixed, then give just the exe name.
(Get-Command ".\notepad", "notepad" -ErrorAction Ignore -CommandType Application) -ne $null
That will return true if found local or in system wide paths.
#echo off
set found=
set prog=cmd.exe
for %%i in (%path%) do if exist %%i\%prog% set found=%%i
echo "%found%"
if "%found%"=="" ....
Sometimes this simple solution works, where you check to see if the output matches what you expect. The first line runs the command and grabs the last line of standard output.
FOR /F "tokens=*" %%i in (' "xcopy /? 2> nul" ') do SET xcopyoutput=%%i
if "%xcopyoutput%"=="" echo xcopy not in path.
Use command : powershell Test-Path "exe which you looking for"
It will return True if its present, otherwise False.