Different behavior of cmd on Win7 and XP - windows

I am trying to run following code through cmd.
"C:\Program Files\Beyond Compare 2\BC2.exe" #"C:\New Folder\Myscript.txt" "C:\New Folder\A.txt" "C:\New Folder\B.txt"
This will actually open Beyond Compare and compare two text files.
The problem is ,when i run this code on cmd[Version 6.1.7601] it runs correctly but when i run it on version 5.1.2600 , it shows a fatal error :- Could not find C:/New .
I understand the error is due to space in the name(New Folder) , but why is it running fine on Win 7 .Does two versions of cmd have some difference in the way they accept arguments ?
Content of Myscript.txt :-
file-report layout:side-by-side &
options:display-all &
output-to:%3 output-options:html-color,wrap-word %1 %2

I can't explain why it is not working, but I have some potential solutions
1) Run with the current directory at the location of the files
Since the space is in the folder name, and all files are in the same location, you can avoid the folder name by simply changing directory to that folder and using a relative path.
pushd "c:\new folder"
"C:\Program Files\Beyond Compare 2\BC2.exe" #Myscript.txt A.txt B.txt
Of course this will not work if your files are in different locations, or if the file names have spaces (assuming spaces are really the problem)
2) Use the short 8.3 names
I hate the short 8.3 names because of the many bugs associated with them. But sometimes they can be useful.
You can get the short name of a file or folder by using DIR /X. Or you could use the following in a batch script to programmatically get the short paths.
for %%A in ("C:\New Folder\Myscript.txt") do (
for %%B in ("C:\New Folder\A.txt") do (
for %%C in ("C:\New Folder\B.txt") do (
"C:\Program Files\Beyond Compare 2\BC2.exe" #"%%~fsA" "%%~fsB" "%%~fsC"
)
)
)
Of course the above will not do any good if short 8.3 names are disabled on your volume.

If i understood correctly Raymond's comment ,the parsing is done by Beyond Compare not cmd.
I tried to use
file-report layout:side-by-side &
options:display-all &
output-to:"%3" output-options:html-color,wrap-word "%1" "%2"
and it worked fine on XP but shows error on windows 7 .It seems the beyond compare behaves differently for different OS.

Related

Post-Build Event Works With one Project But Not the Other

I have 2 projects for which I am trying to create a generic Post-Build event batch file.
Here is the command in Visual Studio:
Post-Build event
if $(ConfigurationName) == Release ("$(ProjectDir)PostBuildRelease.bat" "$(TargetDir)" #(VersionNumber) "$(TargetFileName)" "$(TargetName)")
So I am calling the file PostBuildRelease.bat with 4 parameters:
Bin\Release Directory
Project Version
File Name With Extension
File Name Without Extension
Project 1
This works perfectly with this batch script:
CMD
SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET "productionpath=Z:\Unused\Apps\LyncVdiChecker\"
MOVE %productionpath%%3 %productionpath%"_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 %productionpath%
Where the assembly is copied to Z:\Unused\Apps\LyncVdiChecker\ and the existing version copied to _archive in the same folder. The archived version also has the date and version number replace the file extension.
Project 2
This batch script also works perfectly (it does the same thing but in a different folder and for a different project):
CMD
SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET "productionpath=Z:\Unused\Apps\IT Support App\"
MOVE "Z:\Unused\Apps\IT Support App\"%3 "Z:\Unused\Apps\IT Support App\_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 "Z:\Unused\Apps\IT Support App"
However, if I try using the same script from Project1 (the more generic version) in Project2, I get errors, even though the 2 scripts are equivalent:
Errors
The command "if Release == Release ("C:\Users\Seb.Kotze\Source\Repos\Applications\ITSelfHelp\ITHelp\PostBuildRelease.bat" "C:\Users\Seb.Kotze\Source\Repos\Applications\ITSelfHelp\ITHelp\bin\Release\" 2.0.6100.20905 "IT Self Help.exe" "IT Self Help")" exited with code 4.
Output Window:
The syntax of the command is incorrect.
Invalid number of parameters
This error is rather unhelpful, so I tried commenting out the 2 lines MOVE and XCOPY and build again:
Removed MOVE
Same error as above.
Output window:
Invalid number of parameters
Remove XCOPY
No Visual Studio Error, but this appears in the output window:
The syntax of the command is incorrect.
Parameter Output
When I echo out the parameters being used in Project2, everything seems to be in order:
"Path\to\Bin\Release"
2.0.6100.21082
"IT Self Help.exe"
"IT Self Help"
Z:\Unused\Apps\IT Support App\
How can I debug this issue? How is it possible that my script runs fine without any issues, but when run against a different project none of the commands are recognised? Any help with this is much appreciated!
You should normalize all your arguments, so they don't contain outer quotes.
Then you can use them in a reliable way.
The syntax set "variable=%~1" avoids outer quotes in the variable itself.
set "TargetDir=%~1"
set "VersionNumber=%~2"
set "TargetFileName=%~3"
set "TargetName=%~4"
SET "productionpath=Z:\IT Support App\"
set "dateStamp=%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"
MOVE "Z:\IT App\%TargetFileName%" "Z:\IT App\_archive\%TargetName%.%dateStamp%-%VersionNumber%"
XCOPY "%TargetFileName%" "Z:\IT App"
The problem is that the script is messing with the double quotes resulting in invalid paths and invalid number of arguments passed. When dealing with paths built dynamically, it's best to strip any existing " from the parts, and after the path is complete, surround it in ".
Dealing with batch arguments is explained on MSDN. Same thing for variables can be found on SS64.
I've played a bit with the file, and I was able to run it (from command line). The changes you should make in your (Project1) file:
SET productionpath="Z:\Unused\Apps\LyncVdiChecker\"
MOVE "%productionpath:"=%%~3" "%productionpath:"=%_archive\%~4.%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%-%~2"
XCOPY "%~3" "%productionpath:"=%"
I moved the " from the productionpath line to the beginning of its contents. That way will work with paths that contain SPACE s.
In the MOVE and XCOPY lines, I did what I explained above: even if the syntax is not that clear, it's more robust (the last "%productionpath:"=%" could be simple written as %productionpath%, but I left it in the the 1st form for consistency).
Note: You could remove the CMD command at the beginning of your batch, since it starts a new cmd instance(process) that doesn't end.
I found a solution to this, but I am still not sure what the cause was.
I suspect it has something to do with either one of:
Spaces in productionpath causing the command parameter declaration to escape
Quotes around one or more of the parameters creating a non-existent file path
After trying out a few changes to the script, I found that changing the productionpath declaration to SET productionpath="Z:\Unused\Apps\IT Support App\" solved the issue:
CMD
SET parameter=%1 REM Full path to new bin\release\
SET parameter=%2 REM Full Version Number
SET parameter=%3 REM File name + extension
SET parameter=%4 REM File name - extension
SET productionpath="Z:\Unused\Apps\IT Support App\"
MOVE "Z:\Unused\Apps\IT Support App\"%3 "Z:\Unused\Apps\IT Support App\_archive\"%4"."%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"-"%2
XCOPY %3 "Z:\Unused\Apps\IT Support App"
Making the same change to the Project1 script did not cause that to break either, so this seems safe.
Update
After reading some of the other answers, I amended the script once again to the following:
CMD
SET "TargetDir=%~1"
SET "VersionNumber=%~2"
SET "TargetFileName=%~3"
SET "TargetName=%~4"
SET "ProductionPath=Z:\Unused\Apps\IT Support App\"
SET "ArchivePath=%ProductionPath%_archive\"
SET "DateStamp=%DATE:~0,2%%DATE:~3,2%%DATE:~6,4%"
MOVE "%ProductionPath%%TargetFileName%" "%ArchivePath%%TargetName%.%DateStamp%-%VersionNumber%"
XCOPY "%TargetFileName%" "%ProductionPath%"
Notice the "normalisation" of the paramaters - this removes all quotation marks from their values.
Also now using named parameters.

Windows batch - concatenate multiple text files into one

I need to create a script, which concatenates multiple text files into one.
I know it's simple to use
type *.txt > merged.txt
But the requirement is to "concatenate files from same day into file day_YYYY-DD-MM.txt" I am a Linux user and Windows batch is hell for me. It's Windows XP.
Windows type command works similarly to UNIX cat.
Example 1: Merge with file names (This will merge file1.csv & file2.csv to create concat.csv)
type file1.csv file2.csv > concat.csv
Example 2: Merge files with pattern (This will merge all files with csv extension and create concat.csv)
When using asterisk(*) to concatenate all files. Please DON'T use same extension for target file(Eg. .csv). There should be some difference in pattern else target file will also be considered in concatenation
type *.csv > concat_csv.txt
At its most basic, concatenating files from a batch file is done with 'copy'.
copy file1.txt + file2.txt + file3.txt concattedfile.txt
In Win 7, navigate to the directory where your text files are. On the command prompt use:
copy *.txt combined.txt
Where combined.txt is the name of the newly created text file.
Place all files need to copied in a separate folder, for ease place them in c drive.
Open Command Prompt - windows>type cmd>select command prompt.
You can see the default directory pointing - Ex : C:[Folder_Name]>.
Change the directory to point to the folder which you have placed files to be copied, using ' cd [Folder_Name] ' command.
After pointing to directory - type 'dir' which shows all the files present in folder, just to make sure everything at place.
Now type : 'copy *.txt [newfile_name].txt' and press enter.
Done!
All the text in individual files will be copied to [newfile_name].txt
I am reiterating some of the other points already made, but including a 3rd example that helps when you have files across folders that you want to concatenate.
Example 1 (files in the same folder):
copy file1.txt+file2.txt+file3.txt file123.txt
Example 2 (files in same folder):
type *.txt > combined.txt
Example 3 (files exist across multiple folders, assumes newfileoutput.txt doesn't exist):
for /D %f in (folderName) DO type %f/filename.txt >> .\newfileoutput.txt
We can use normal CAT command to merge files..
D:> cat *.csv > outputs.csv
cat "input files" > "output files"
This works in PowerShell, which is the Windows preferred shell in current Windows versions, therefore it works. It is also the only version of the answers above to work with large files, where 'type' or 'copy' fails.
Try this:
#echo off
set yyyy=%date:~6,4%
set mm=%date:~3,2%
set dd=%date:~0,2%
set /p temp= "Enter the name of text file: "
FOR /F "tokens=* delims=" %%x in (texto1.txt, texto2.txt, texto3.txt) DO echo %%x >> day_%temp%.txt
This code ask you to set the name of the file after "day_" where you can input the date.
If you want to name your file like the actual date you can do this:
FOR /F "tokens=* delims=" %%x in (texto1.txt, texto2.txt, texto3.txt) DO echo %%x >> day_%yyyy%-%mm%-%dd%.txt
You can do it using type:
type"C:\<Directory containing files>\*.txt"> merged.txt
all the files in the directory will be appendeded to the file merged.txt.
copy is definitely much faster than type - but it sometimes (with large files?) adds a SUB character at the end of the file. So, strictly speaking, it does not simply concatenate the files in the same way as cat in Unix.
So, the correct answer is to use cat - either in something like Git Bash (where it has the same syntax as in Unix), or PowerShell (where it does not).

Search for specific directory names within subdirectories and copy files (Windows batch)

need some help with this one
I have a directory that contains subdirectories from various applications so let's say directory is c:\home and each application has a subdirectory called the application name so we will have
c:\home\app1
c:\home\app2
etc.
These applications write large log files and they then get recreated every hour but into a different directory, called according t date and time like dd/mm/yyyy/hr and this is created within the actual subdirectory and a log file with the exact same name will be within each directory for each app. so we will end up with this
c:\home\app1\1015201410\app1.log
c:\home\app1\1015201411\app1.log
c:\home\app1\1015201412\app1.log
c:\home\app2\1015201410\app2.log
c:\home\app2\1015201411\app2.log
c:\home\app2\1015201412\app2.log
I want to list through the directories every hour and collect the latest log from each application, in other words in this instance I want to collect the following 2 only as they are the latest (end time 12 shows it is the 12th hour)
c:\home\app1\1015201412\app1.log
c:\home\app4\1015201412\app2.log
Now getting the file one by one is easy enough but the script is going to become too long and needs to be edited on a regular base to allow for new applications added to the directories.
I am able to do the copying, formatting the time/date section etc. I just need to find a way to search through the home directories for all subdirectories containing the latest timedate and then copy a file from it elsewhere.
So I tried this. Note timedateformat has been predefined:
for /D %%d in (c:\home\*\%timedateformat%\*) do (
for %%f in (%%d\.log) do (
xcopy %%f C:\destination\
)
)
but this obviously does not like the * part and therefore I will get no result.
Please if anyone is able to assist, I would greatly appreciate.
for /d %%F in ("c:\home\*") do xcopy "%%F\%timedateformat%\*.log" "c:\destination\"

Windows batch file: rename files (possibly in multiple folders) based on input file (of target filenames)

I am a Batch-newbie, so please accept my apologies and Thanks in advance !
This "tool" is to automate the slimming down of Windows (XP) by disabling certain system driver, DLL and EXE files. Instead of outright deletion, I wish to rename-in-place, thus "removing" them from the OS, but not losing sight of where they belong (should any need to be "restored"). Renaming is accomplished by appending a new suffix to the existing filename (eg: "wdmaud.drv.group_1") The renaming suffix should be another input variable.
The target-list is approx. 1100 files long (divided into various groups/phases), so manual renaming is out of the question. Each group will be processed in a separate run of the batch file, varying the target-list input file for each execution.
Target-list is plain text file, one filename per line (no other data in the files). Number of entries per group varies. Target list will look like this:
-- example start --
netapi.dll
netcfgx.dll
netdde.exe
netevent.dll
neth.dll
netid.dll
netrap.dll
nic1394.sys
-- example end --
Filenames may be in UPPER, lower, or MiXeD case. The files may be present in more than one folder in the C:\Windows hierarchy - or may not be present at all. If a file is not found anywhere in the system, it's name should be written to a text file, one-entry-per-line.
The specific folders of interest are:
C:\WINDOWS\
C:\WINDOWS\system\
C:\WINDOWS\system32\
C:\WINDOWS\system32\dllcache
C:\WINDOWS\system32\drivers
The renaming will be done by connecting the target OS drive to another XP computer, so locked system files should not be a problem.
Any help you can offer will be greatly appreciated.
a double FOR loop may help you.. this is a very simple example, just to get you started
for /f "tokens=*" %%f in (%targetlist%) do (
for /f "tokens=*" %%d in (%dirlist%) do (
if exist "%%d\%%f" echo %%f found in %%d
)
)
see HELP FOR.

Why does xcopy not copy files when using these parameters?

I have a simple xcopy script that I'm running from the command line that reads a CSV file of directories and file names. I've used a very similar script with no problems before. Here is the script:
Z:\HOME\>for /f "delims=, tokens=1,2,3,4" %i in (Z:\HOME\MissingImages.csv) do
echo f | xcopy "Y:\%j\%k\%l" "C:\Horizon\%j\%k\%l" >> Z:\HOME\MissingImagesLog.txt
However, it is not copying any of the files over
Here is an entry from the log file:
Does C:\Horizon\K\00\6bef500f.IMG specify a file name
or directory name on the target
(F = file, D = directory)? f
0 File(s) copied
It's finding the images because if I change the root directory to something else the script will just populate the log file with 0 File(s) copied for all entries, so the files are there and can be seen...
Also, the Z:\ drive is on a network and not local, but again I have used a very similar script across a network without problems (it just takes longer).
I've tried different options like /i, /s, etc. but I can't seem to get it to copy any files over.
xcopy will also report 0 File(s) copied if you use forward slashes "/" in paths instead of backslashes "\", though ONLY if you've enclosed the path in quotes.
This fails with "0 File(s) copied"
xcopy "pathname1/file" pathname2\file
This fails with "Invalid number of parameters"
xcopy pathname1/file pathname2\file
This works just fine
xcopy pathname1\file pathname2\file
It asks because it doesn't know whether you want to copy to directory (to be created) or you provide the full target pathname.
This will ask:
xcopy pathname1\file.from pathname2\file.to
However, adding slash will tell that you copy to directory:
xcopy pathname1\file.from pathname2\to\
But I haven't found the way to tell explicitly that I want to copy and rename file, except
echo Y | xcopy pathname1\file.from pathname2\file.to
I played a bit with your case (with for, do and xcopy) and found out that even if it asks Does SOMEFILE specify a file name or directory name on the target (F = file, D = directory)? it is provided with f from echo and it's copied successfully. Thus, it's not a problem with file/directory specifying, but with copying through network itself.
Well, that's annoying; I found the issue. It looks like when I generated my CSV file, it put a space at the end of each line, so xcopy was looking for files that had a space after the extension.
The thing that was throwing me off was that it was finding the files, but couldn't copy them, making me think it was a network or xcopy issue.
I just ran a sed script to remove the eol spaces and the xcopy script is now working as expected.

Resources