batch script to delete and replace files in multiple locations - batch-file

What I am looking to do is create a batch file to replace teh cert8.db file in a users application data folder as well as insert a line of text into one of the prefs.js file. Normally this would be easy, the issue is that there is a good chance some of my users have multiple firefox profiles so I would like to have a script to to replace all cert8.db files in the firefox/profiles folder and insert 1 line of next into all prefs.js files in the firefox/profiles folder.
Can this be done? I am willing to use vb if possible.

You could do something like this:
Set fso = CreateObject("Scripting.FileSystemObject")
profilesFolder = "C:\Users"
firefoxProfiles = "AppData\Roaming\Mozilla\Firefox\Profiles"
For Each fldr In fso.GetFolder(profilesFolder)
profilePath = fso.BuildPath(fldr.Path, firefoxAppdata)
If fso.FolderExists(profilePath) Then
For Each profile In fso.GetFolder(profilePath)
certdb = fso.BuildPath(profile, "cert8.db")
prefs = fso.BuildPath(profile, "prefs.js")
If fso.FileExists(certdb) Then
'replace cert8.db
End If
If fso.FileExists(prefs) Then
'modify prefs.js
End If
Next
End If
Next
The code for replacing the DB file and modifying the preferences depends on where the replacement DB comes from and what you want to add or update in the preferences.

FOR /D %%i IN (C:\Users\*.*) Do FOR /D %%j IN (%%i\AppData\Roaming\Mozilla\Firefox\Profiles\*.*) Do (
CALL :ReplaceDB "%%j\cert8.db"
CALL :ChangeJS "%%j\prefs.js"
)
:ReplaceDB
IF NOT EXIST %1 GOTO :EOF
MOVE /Y %1 "%~1.old"
COPY C:\firefox\cert8.db %1
GOTO :EOF
:ChangeJS
IF NOT EXIST %1 GOTO :EOF
ECHO user_pref("network.proxy.autoconfig_url", "pac.pe.lan/pac/proxy.pac") >> %1
GOTO :EOF
EDIT: Added second FOR to search profiles.
EDIT: Added code for replacing DB and appending line to JS.

Related

Batch script to read input text file and build output command

I have a batch file that will run csc using a file as input. I want to modify it to read references from a file, and add them to the line that is executed when the script runs.
I've tried a few different things but can't seem to get it work. The references are added with /r: and then each reference path has semi-colon as a separator.
Ideally, I'd like to just have a reference on a new line in the text file. The ref.txt file is in the same directory as the input file, and I'm not sure if it was looking in this directory or not. I also want to make it attempt to run without the ref.txt file, so I added the exists line to do this. I've never used batch scripting before, so maybe someone else knows how to do this better than me. I think that the first line needs to match the start line, which I tried to do in other attempts, but it wasn't working.
The script works in Notepad++, and was from this answer. I think now that the run command also needs to be modified.
This is the run command in Notepad++:
C:\bin\csc.bat "$(CURRENT_DIRECTORY)\$(NAME_PART).exe" "$(FULL_CURRENT_PATH)"
This is the version from that answer:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /out:%1 %2
#echo off
if errorlevel 1 (
pause
exit
)
start %1 %1
This is an attempt to use references:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc /out:%1 %2
#echo off
if errorlevel 1 (
pause
exit
)
if not exist ref.txt GOTO :write
set a = /r:
set refs = type ref.txt
start %1 %a% and %refs% and %1
exit
write
start %1 %1
The refs.txt file contains file paths like this:
C:\windows\some_path\some_file.dll;C:\windows\some_path\another_file.dll;
An example command from Microsoft is:
csc /t:exe /r:MyCodeLibrary.dll;NewLib.dll *.cs
IIUR you are trying to apply the refs to the compiled exe not to csc itself.
You need to adapt the path to the ref.txt file
:: Q:\Test\2019\01\25\SO_54360791.cmd
#echo off & Setlocal EnableDelayedExpansion
Set CSC="C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe"
Set Ref=".\ref.txt"
if exist %Ref% (
<%Ref% Set /p "refs="
set "refs=/r:!refs!"
) else set "refs="
%CSC% %refs% /out:%1 %2
if errorlevel 1 (
pause
exit
)
sample (echoed) output
> SO_54360791.cmd new.exe source.cs
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe" /r:C:\windows\some_path\some_file.dll;C:\windows\some_path\another_file.dll; /out:new.exe source.cs
I'm not sure if the trailing semicolon in your sample ref.txt will work.
EDIT: Variant with ref.txt file containing quoted pathes with trailing semiclon
:: Q:\Test\2019\01\25\SO_54360791.cmd
#echo off & Setlocal EnableDelayedExpansion
Set CSC="C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe"
Set Ref=".\ref.txt"
Set "refs="
if not exist %Ref% goto :cont
set "refs=/r:"
for /f "usebackq delims=" %%A in (%Ref%) Do set "refs=!refs!%%A"
:cont
echo %CSC% %refs% /out:%1 %2
if errorlevel 1 (
pause
exit
)
goto :Eof
sample (echoed) output
> SO_54360791.cmd new.exe source.cs
"C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe" /r:"C:\windows\some_path\some_file.dll";"C:\windows\some_path\another_file.dll"; /out:new.exe source.cs

windows .bat script to search for files that existed in the same directory previously

I need to write a script that looks for same files that existed previously in the same directory. This script will be run as a scheduled job so it doesn't need to have the rerun functionality built in to it:
Look for files in a given directory.
If no files exist then return 0 and exit.
If files exist then store them and exit..
When script runs again (through a scheduler), look for files in the same directory and if any file names match with any files that were previously stored then print the file names that matched and return a non-zero exit code (1).
If there was no match then release the previously stored file names and store the new file names. Return 0 and exit.
Is it possible to achieve the above? I have no scripting backgrounds so any help will be beneficial.
#ECHO Off
SETLOCAL
SET "targetdir=U:\destdir"
SET "savedir=U:\"
SET /a returnlevel=0
DIR /b "%targetdir%">"%savedir%\newlist.txt"
IF NOT exist "%savedir%\oldlist.txt" GOTO noold
:: Now compare
FINDSTR /i /l /x /c:":" /g:"%savedir%\oldlist.txt" "%savedir%\newlist.txt"
if ERRORLEVEL 1 (SET /a returnlevel=0) ELSE (SET /a returnlevel=1)
:noold
MOVE /y "%savedir%\newlist.txt" "%savedir%\oldlist.txt" >NUL 2>nul
EXIT /b %returnlevel%
GOTO :EOF
You would need to change the settings of targetdir and savedir to suit your circumstances.

Need to insert a blank page at end of over 1000 word documents

I have an issue when trying to print over 1000 microsoft word 2010 documents.
I have been given these files and they are all in the same folder, i have a macro that will print them all, however i have now been told that the documents need to be printed in reverse order. As they are duplex, the printers are printing them duplex 5-4, 3-2, 1 and i need to print them 5, 4-3, 2-1. I have been told the only way i can do this is if i insert a blank page at the end of each document. I obviously don't want to do this manually.
Can someone help me with this, Need help.
Thanks
NOT TESTED
Create this file in the directory with the documents and save it as a .bat (this is a hybrid bat/vbscript file ) .And then call it:
:sub echo(str) :end sub
echo off
:::''' batch part ''':::
'>nul 2>&1|| copy /Y %windir%\System32\doskey.exe '.exe >nul
'& echo/
'& tskkill winword >nul 2>&1
'& for %%f in (*.doc *.docx) do cscript /nologo /E:vbscript %~dpfnx0 "%%~dpfnxf"
'& del '.exe" & exit /b
''' end of batch part '''
Const wdPageBreak = 7
Set WordApp = CreateObject("Word.Application")
WordApp.Visible = FALSE
'Open the doc
Set objWord = WordApp.Documents.Open(WScript.Arguments.Item(0))
Set objSelection = WordApp.Selection
objSelection.InsertBreak(wdPageBreak)
objSelection.TypeText ""
WordDoc.Close()
WScript.Quit
Sources of wisdom:
http://technet.microsoft.com/en-us/library/ee692875.aspx
http://technet.microsoft.com/en-us/library/ee692855.aspx

How can I set Path by browsing popup?

I have below script, in this there are two path one is Target path (only one) and another source path (variables).
About below script function: I'll run this once in a month and it'll go the souce path (10 path) and copy lates file then copy&rename to target path (common for all the files).
note : file which is copyed form the respacted source should be rename as per script like:
file from "F:\Financial\Data\Reports\AccruntPnLMTD" should be rename as "PNL.csv"
#echo off
setlocal
set DateFolder=04.2013
set TargetFolder=F:\Financial\Data\%DateFolder%\Final Reports
:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD" "%TargetFolder%\PNL.csv"
:: copy the newest file from AccountPnlMTD and rename it to AC.csv
call :copyAndRename "F:\Financial\Data\Reports\AccountPnlMTD" "%TargetFolder%\AC.csv"
:: copy the newest file from ExpensesMTD and rename it to EXPMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\ExpensesMTD" "%TargetFolder%\EXPMTD.csv"
:: copy the newest file from ExpensesYTD and rename it to EXPYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\ExpensesYTD" "%TargetFolder%\EXPYTD.csv"
:: copy the newest file from AccrualPnLYTD and rename it to PNLYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\AccrualPnLYTD" "%TargetFolder%\PNLYTD.csv"
:: copy the newest file from AccountYTD and rename it to ACYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\AccountYTD" "%TargetFolder%\ACYTD.csv"
:: copy the newest file from BalanceMTD and rename it to BSMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\BalanceMTD" "%TargetFolder%\BSMTD.csv"
:: copy the newest file from BalanceYTD and rename it to BSYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\BalanceYTD" "%TargetFolder%\BSYTD.csv"
:: copy the newest file from FinancialStmtMTD and rename it to FSMTD.csv
call :copyAndRename "F:\Financial\Data\Reports\FinancialStmtMTD" "%TargetFolder%\FSMTD.csv"
:: copy the newest file from FinancialStmtYTD and rename it to FSYTD.csv
call :copyAndRename "F:\Financial\Data\Reports\FinancialStmtYTD" "%TargetFolder%\FSYTD.csv"
:: Done
goto :eof
:copyAndRename
set SourceFolder=%~1
set TargetFile=%~2
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set "NewestFile=%%F"
:: copy and rename it to the target
copy "%SourceFolder%\%NewestFile%" "%TargetFile%"
:: Done with this subroutine
goto :eof
I want's to give both path after run the script (popup should ask for the path)
Excuse me. Your question is not clear. I assume that you want to copy and rename the 10 given files but not with the fixed paths given in the program, but with variable paths given when the program run. If this is correct, the program must get first the Target path (only one) and then the source path for each one of the files.
The Batch file below is a preliminary version that achieve previous process. If this solution is what you want, then the "browsing popup" part for the paths may be added instead of the simple "set /P folder=Enter folder:" commands. Or perhaps this version is enough for you?
EDIT: I modified the solution below in order to include these new requests:
I have variable target path for diffrent clients like for client a
path wil be F:\Financial\ClientA\Data\%DateFolder%\Final Reports..&
for client B "F:\Financial\ClientB\Data\%DateFolder%\Final Reports"
same goes in source path like Client A path
"F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path
will be F:\Financial\Data\Reports\Client B\AccruntPnLMTD..file folder
names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each
clients
LAST EDIT: The Batch file below has been modified for the last time in accordance with the last paragraph in this answer: Browse the existent folders in the disk and pick one.
#if (#CodeSection == #Batch) #then
#echo off
setlocal
rem Activate the browsing pop-up and ask for TargetFolder
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0" "Select the Target folder"') do (
set TargetFolder=%%a
)
rem Activate the browsing pop-up and ask for SourceFolder
for /F "delims=" %%a in ('CScript //nologo //E:JScript "%~F0" "Select the Source folder"') do (
set ClientSourceFolder=%%a
)
rem Process the list of "sourceFolder=fileName" pairs
for %%a in ("AccruntPnLMTD=PNL" "AccountPnlMTD=AC" "ExpensesMTD=EXPMTD" "ExpensesYTD=EXPYTD" "AccrualPnLYTD=PNLYTD"
"AccountYTD=ACYTD" "BalanceMTD=BSMTD" "BalanceYTD=BSYTD" "FinancialStmtMTD=FSMTD" "FinancialStmtYTD=FSYTD"
) do (
rem copy the newest file from sourceFolder and rename it to fileName.csv
for /F "tokens=1,2 delims==" %%b in (%%a) do (
call :copyAndRename "%%b" "%%c"
)
)
:: Done
goto :eof
:copyAndRename
set SourceFolder=%ClientSourceFolder%\%~1
set TargetFile=%TargetFolder%\%~2.csv
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%SourceFolder%"') do set
"NewestFile=%%F"
:: copy and rename it to the target
copy "%SourceFolder%\%NewestFile%" "%TargetFile%"
:: Done with this subroutine
goto :eof
#end
// JScript section
// Creates a dialog box that enables the user to select a folder.
// http://msdn.microsoft.com/en-us/library/windows/desktop/bb774065(v=vs.85).aspx
var shl = new ActiveXObject("Shell.Application");
var folder = shl.BrowseForFolder(0, WScript.Arguments(0), 0, 0);
WScript.Stdout.WriteLine(folder ? folder.self.path : "");
In this new solution you may SELECT the desired client via the parameter of the Batch file. For example, if the Batch file is called example.bat, use this command for ClientA:
example.bat ClientA
You must note that BROWSING FOR A FOLDER is an interactive operation that present a pop-up window with all existent folders and allows you to choose one of them.
EDIT: Some explanations added
It seems that there is a confusion here. In your question you show as examples of target and source folders these ones:
set TargetFolder=F:\Financial\Data\%DateFolder%\Final Reports
:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "F:\Financial\Data\Reports\AccruntPnLMTD"
However, in posterior comments you said:
I have variable target path for diffrent clients like for client a path wil be
F:\Financial\ClientA\Data\%DateFolder%\Final Reports..& for client B
F:\Financial\ClientB\Data\%DateFolder%\Final Reports
same goes in source path like Client A path
F:\Financial\Data\Reports\Client A\AccruntPnLMTD ; for client B Path will be
F:\Financial\Data\Reports\Client B\AccruntPnLMTD..
file folder names (AccruntPnLMTD,AccruntPnLMTD..etc) will reman same for each clients
You must realize that two previous forms are entirely different: in the first one the folder path is constant, but in the second one the folder path must be changed for each client. A Batch file solution is always designed with fixed requirements. This point is not clear in your answer nor in your comments, so I assumed certain details in order to write a Batch solution. I think there are two ways to solve this problem, depending of what the problem is:
1- Select the appropriate folders for each client: in this case I assumed that path folders have this form:
Target Folder is formed by "F:\Financial\" followed by a variable part that select each client, followed by "\Data\%DateFolder%\Final Reports".
Source path is formed by "F:\Financial\Data\Reports\" followed by a variable part that select each client, followed by each one of the 10 different folders (AccruntPnLMTD,AccruntPnLMTD..etc).
If this is the problem, then my solution above solve it. You just need to place the desired folder name as parameter of the Batch file. For example, if the name of the folder for client a is "ClientA", execute this command:
nameOfTheBatchFile ClientA
If the name of the folder for client B is "ClientB", execute this command:
nameOfTheBatchFile ClientB
If the name of the folder have spaces, enclose it in quotes; for example, for "Any other client" execute this command:
nameOfTheBatchFile "Any other client"
However, your posterior comments and insistence on using terms like "browsing popup", "asking for the path", etc. makes me think that the previously explained problem is not the one you want to solve. There is another possibility:
2- Browse the existent folders in the disk and pick one: in this case when the program run it present a "browsing popup" window that give access to all folders in the disk and allows you to select anyone of them. Note that the browsing window can NOT restrict the browse for any particular name format; if you want that the selected folder have certain characteristics, like the data placed after "Data\" part be today's date in "MM.YYYY" format or any other restriction, this checking must be done after the user choose a folder, so the program will indicate that the selected folder was invalid and popup the browsing window again.
I encourage you to clearly explain your requirements. Please, modify your original question so anyone can understand the problem after read it and don't require to review all the comments in all answers.
This is untested - it merges your code with the popup routine and asks for the source folder once, where all the folders are expected to be.
#echo off
setlocal
set DateFolder=04.2013
:: set the source and target folders
call :getpath
set "TargetFolder=%TargetFolder%\%DateFolder%\Final Reports"
:: copy the newest file from AccruntPnLMTD and rename it to PNL.csv
call :copyAndRename "AccruntPnLMTD" "%TargetFolder%\PNL.csv"
:: copy the newest file from AccountPnlMTD and rename it to AC.csv
call :copyAndRename "AccountPnlMTD" "%TargetFolder%\AC.csv"
:: copy the newest file from ExpensesMTD and rename it to EXPMTD.csv
call :copyAndRename "ExpensesMTD" "%TargetFolder%\EXPMTD.csv"
:: copy the newest file from ExpensesYTD and rename it to EXPYTD.csv
call :copyAndRename "ExpensesYTD" "%TargetFolder%\EXPYTD.csv"
:: copy the newest file from AccrualPnLYTD and rename it to PNLYTD.csv
call :copyAndRename "AccrualPnLYTD" "%TargetFolder%\PNLYTD.csv"
:: copy the newest file from AccountYTD and rename it to ACYTD.csv
call :copyAndRename "AccountYTD" "%TargetFolder%\ACYTD.csv"
:: copy the newest file from BalanceMTD and rename it to BSMTD.csv
call :copyAndRename "BalanceMTD" "%TargetFolder%\BSMTD.csv"
:: copy the newest file from BalanceYTD and rename it to BSYTD.csv
call :copyAndRename "BalanceYTD" "%TargetFolder%\BSYTD.csv"
:: copy the newest file from FinancialStmtMTD and rename it to FSMTD.csv
call :copyAndRename "FinancialStmtMTD" "%TargetFolder%\FSMTD.csv"
:: copy the newest file from FinancialStmtYTD and rename it to FSYTD.csv
call :copyAndRename "FinancialStmtYTD" "%TargetFolder%\FSYTD.csv"
:: Done
goto :eof
:copyAndRename
set "FileFolder=%SourceFolder%\%~1"
set "TargetFile=%~2"
echo copying "%FileFolder%"
:: Find the newest file in the source folder
for /f "tokens=*" %%F in ('dir /b /od /a-d "%FileFolder%"') do set "NewestFile=%%F"
:: copy and rename it to the target
copy "%FileFolder%\%NewestFile%" "%TargetFile%" >nul
:: Done with this subroutine
goto :eof
:getsourcepath
Call :BrowseFolder "Choose Source folder" "C:\Program Files\"
Set "SourceFolder=%Result%"
Call :BrowseFolder "Choose Target folder" "C:\Users\"
Set TargetFolder=%Result%
REM echo %SourceFolder%
REM echo %TargetFolder%
:: Done
goto :eof
:BrowseFolder
set Result=
set input="%~1" & set default="%~2"
:: Temporary files
set vbs=%temp%\_.vbs
set tmp=%temp%\_.cmd
:: Build VBScript file
findstr "'%skip%VBS" "%~f0" > "%vbs%"
:: Run the script with WSH and set Path as Env variable %Result%
for /f "delims=" %%a in ('cscript /nologo "%vbs%" ') do set "Result=%%a"
DEL %VBS%
set vbs= & set tmp= & set input= & set default=
goto :EOF
set WshShell=WScript.CreateObject("WScript.Shell") 'VBS
set shell=WScript.CreateObject("Shell.Application") 'VBS
sInput=WshShell.ExpandEnvironmentStrings("%input%") 'VBS
sDefault=WshShell.ExpandEnvironmentStrings("%default%") 'VBS
sInput = Replace(sInput, chr(34), "") 'VBS
sDefault = replace(sDefault,chr(34),"") 'VBS
set folder=shell.BrowseForFolder(0,sInput,0,sDefault) 'VBS
if typename(folder)="Nothing" Then 'VBS
wscript.echo "set Result=Dialog Cancelled" 'VBS
WScript.Quit(1) 'VBS
end if 'VBS
set folderItems=folder.Items() 'VBS
set folderItem=folderItems.Item() 'VBS
pathname=folderItem.Path 'VBS
wscript.echo pathname 'VBS

Batch script to move XML files to the corresponding folder - folder name is written in the XML

I am new to batch scripting so any help is very appreciated.
I have to create a batch that moves XML files to corresponding folders - the folders name is written in the XML files.
The folders name is a number that is between tags:
<DeliveryLocationNumber>123456789</DeliveryLocationNumber>
and in this case the XML-would have to be moved to the folder C:\docs\123456789
Also there are many XML docs so I think that this should be done with some sort FOR function.
Thanks in advance
#ECHO OFF
SETLOCAL
FOR %%f IN (*.xml) DO (
(SET destdir=)
FOR /f "tokens=2delims=<>" %%i IN (
'find "</DeliveryLocationNumber>" ^<%%f'
) DO SET destdir=%%i
IF DEFINED destdir CALL :moveme %%f
)
GOTO :eof
:moveme
ECHO MD c:\docs\%destdir% 2>NUL
ECHO MOVE %1 c:\docs\%destdir%\
GOTO :eof
simply delete the ECHO keywords in the :moveme routine to actually create the destination directory and move the file. The ECHO ensures that the proposed actions are merely reported to the screen, not actioned.
What's happening is:
For each .XML file:
Force the value of DESTDIR to be deleted
Examine each line containing </DeliveryLocationinNumber>
Parse that line into tokens delimited by > or <
select the second token and assign it to DESTDIR
If DESTDIR was set (ie. a Delivery... line was found)
then CALL the routine :moveme passing the filename in %%f as parameter #1
The :moveme routine then can use the value of DESTDIR and %1 (the first parameter delivered to :moveme) to build the appropriate MD (make directory) [the 2>NUL suppresses any potential error message - like the directory already exists] and MOVE statements

Resources