How can I rotate the Apache Access and Error logs on a Window 2000 box?
I include my batch file below as an answer.
Is there a way of doing this directly via the Apache config file? I'm currently using the following customlog command to generate daily logs.
CustomLog '|" "*Apache-Path/bin/rotatelogs.exe" "*Apache-Path/logs/backup/internet_access_%d-%m-%y.log" 86400' combined
Here's the DOS batch file, modified as annotated.
I run it weekly and it keeps 8 weeks of zipped backups.
You'll need to install 7 zip.
I haven't parametrised the paths, feel free to.
#echo off
:: Name - svrlogmng.bat
:: Description - Server Log File Manager
::
:: History
:: Date Authory Change
:: 22-May-2005 AGButler Original
:: 14-Jan-2008 AIMackenzie Changed net stops and paths where necessary
:: ========================================================
:: setup variables and parameters
:: ========================================================
:: generate date and time variables
for /f "tokens=2,3,4 delims=/ " %%i in ('date /T') do set trdt=%%k%%j%%i
for /f "tokens=1,2 delims=: " %%i in ('time /T') do set trtt=%%i%%j
set nftu=%trdt%%trtt%
:: set the Number Of Archives To Keep
set /a noatk=8
:: ========================================================
:: turn over log files
:: ========================================================
:: change to the apache log file directory
cd /D "D:\Program Files\Apache Software Foundation\Apache2.2\logs\"
:: stop Apache Service, Move log files and restart Apache Service
"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -k stop
echo %nftu% >> access.log
move "D:\Program Files\Apache Software Foundation\Apache2.2\logs\access.log" "D:\Program Files\Apache Software Foundation\Apache2.2\logs\%nftu%_access.log"
echo %nftu% >> error.log
move "D:\Program Files\Apache Software Foundation\Apache2.2\logs\error.log" "D:\Program Files\Apache Software Foundation\Apache2.2\logs\%nftu%_error.log"
"D:\Program Files\Apache Software Foundation\Apache2.2\bin\httpd.exe" -k start
:: ========================================================
:: zip todays Access and Error log files, then delete old logs
:: ========================================================
:: zip the files
"D:\Program Files\7-Zip\7z.exe" a -tzip %nftu%_logs.zip %nftu%_access.log %nftu%_error.log
:: del the files
del /Q %nftu%_*.log
:: ========================================================
:: rotate the zip files
:: ========================================================
:: make list of archive zip files
type NUL > arclist.dat
for /F "tokens=1,2 delims=[] " %%i in ('dir /B *_logs.zip ^| find /N "_logs.zip"') do echo %%i = %%j>> arclist.dat
:: count total number of files
for /F "tokens=1 delims=" %%i in ('type arclist.dat ^| find /C "_logs.zip"') do set tnof=%%i
:: setup for and create the deletion list
set /a negtk=%noatk%*-1
set /a tntd=%tnof% - %noatk%
type NUL>dellist.dat
for /L %%i in (%negtk%,1,%tntd%) do find " %%i = " arclist.dat >> dellist.dat
:: del the old files
for /F "tokens=3 delims= " %%i in ('find "_logs.zip" dellist.dat') do del /Q %%i
:: remove temp files
del /Q arclist.dat
del /Q dellist.dat
I've a little bit extend the the bat-script. You can use it for english and german dates. You will need 7za.exe at the same directory like script. The log-dir and -files for rotation are explicitly settable.
#echo off
SETLOCAL ENABLEEXTENSIONS ENABLEDELAYEDEXPANSION
:: ========================================================
:: setup variables and parameters
:: ========================================================
:: USE Service Display Name, Services are space-separated -> Syntax: "Display Name 1" "Display Name 2"
SET ROTATE_SERVICES="Apache2.2"
:: setting LOG-directory, log-files in this directory should be rotate
SET ROTATE_LOGDIR=F:\xampp\apache\logs
:: files which should rotate (space separated)
SET ROTATE_FILES=access.log error.log ssl_request.log
:: SET the Number Of Archives To Keep
SET /a keptarchives=5
:: SET delimiter for date format (english "/", german ".")
SET DATEDEL=.
:: ========================================================
:: DO NOT CHANGE ANYTHING
:: ========================================================
:: Check for existing Log-directory
IF NOT EXIST "%ROTATE_LOGDIR%" (
CALL :LOG Please check your paths to Log Directory
PAUSE
GOTO :EOF
)
:: Check for existing Log-files
FOR %%d IN (%ROTATE_FILES%) DO (
IF NOT EXIST "%ROTATE_LOGDIR%\%%d" (
CALL :LOG File %ROTATE_LOGDIR%\%ROTATE_LOGFILES% does not exist!
PAUSE
GOTO :EOF
)
)
:: generate date and time variables for execution
FOR /f "tokens=1,2,3 delims=%DATEDEL% " %%i IN ('date /T') DO SET execdate=%%k%%j%%i
FOR /f "tokens=1,2 delims=: " %%i IN ('time /T') DO SET exectime=%%i%%j
SET fullexectime=%execdate%_%exectime%
:: ========================================================
:: ========================================================
:: Operations
:: ========================================================
FOR %%d IN (%ROTATE_SERVICES%) DO (
NET STOP %%d
)
FOR %%d IN (%ROTATE_FILES%) DO (
cd /d %ROTATE_LOGDIR%
IF NOT EXIST OLD (MKDIR OLD)
move %%d %ROTATE_LOGDIR%\OLD\%fullexectime%_%%d
)
FOR %%d IN (%ROTATE_SERVICES%) DO (
NET START %%d
)
:: ========================================================
:: ZIP - LOGFILES
:: ========================================================
cd /d %ROTATE_LOGDIR%\OLD
CALL "%~dp0\7za.exe" a %ROTATE_LOGDIR%\OLD\%fullexectime%_log.zip %ROTATE_LOGDIR%\OLD\%fullexectime%_*.log
IF %ERRORLEVEL% NEQ 0 (
CALL :LOG Error while compressing log-file. Log will not deleted and not rotated. Check your OLD-directory!
PAUSE
GOTO :EOF
)
del /Q %fullexectime%_*.log
:: ========================================================
:: ROTATE - ZIPPED LOGFILES
:: ========================================================
:: make list of archive zip files
type NUL > arclist.dat
for /F "tokens=1,2 delims=[] " %%i in ('dir /B *_log.zip ^| find /N "_log.zip"') do echo %%i = %%j>> arclist.dat
:: count total number of files
for /F "tokens=1 delims=" %%i in ('type arclist.dat ^| find /C "_log.zip"') do set tnof=%%i
:: setup for and create the deletion list
set /a negtk=%keptarchives%*-1
set /a tntd=%tnof% - %keptarchives%
type NUL>dellist.dat
for /L %%i in (%negtk%,1,%tntd%) do find " %%i = " arclist.dat >> dellist.dat
:: del the old files
for /F "tokens=3 delims= " %%i in ('find "_log.zip" dellist.dat') do del /Q %%i
:: remove temp files
del /Q arclist.dat
del /Q dellist.dat
GOTO :EOF
:LOG
SET MSG=[%DATE%, %TIME: =0%] %*
ECHO.%MSG%
SET MSG=
GOTO :EOF
pause
I wrote a vbs for a Windows 2003 box once. It uses zip.exe for compression (found at info-zip.org) and rotates apache logs and php logs. Logs are rotated when larger than MAX_SIZE. It deletes the oldest logs if log count passes MAX_ROTATIONS.
Please provide feedback on the script.
option explicit
const DEBUG_MODE = false
const MAX_ROTATIONS = 10
const MAX_SIZE = 2097152 ' 2MB
const WEB_LOGS = "c:\path\to\site\logs"
const PHP_LOG = "c:\path\to\phplog"
const APACHE_LOGS = "C:\path\to\Apache2\logs"
const APACHE_SERVICE ="Apache2.2" ' Name of the apache service for restart
const ZIP_APP = "c:\path\to\zip.exe"
const LOGROTATE_LOG = "c:\tmp\logrotate.log"
dim aLogs
aLogs = Array("\error.log","\transfer.log","\sec.log","\phperror.log")
dim oFSO
set oFSO = CreateObject("Scripting.FileSystemObject")
if (not DEBUG_MODE) then
dim oLogFile
set oLogFile = oFSO.CreateTextFile(LOGROTATE_LOG, 2, True)
end if
dim bHasRotated
bHasRotated = false
Print "Starting log rotation"
Print "====================="
ManageWebLogs()
ManageApacheLogs()
ManagePhpLog()
if (bHasRotated = true) then
Print "====================="
RestartService APACHE_SERVICE
end if
Print "====================="
Print "Log rotation finished"
if (not DEBUG_MODE) then
oLogFile.Close
set oLogFile = nothing
end if
set oFSO = nothing
'*****************************************************************************
' Loop through all the subfolders in the weblog directory
sub ManageWebLogs()
dim oLogDirs
set oLogDirs = oFSO.GetFolder(WEB_LOGS)
dim oLogDir
for each oLogDir in oLogDirs.SubFolders
Print "In " & oLogDir.Name
RotateLogs(oLogDir)
next
set oLogDir = nothing
end sub
'*****************************************************************************
' Loop through the log files in the Apache logs directory
sub ManageApacheLogs()
dim oLogDir
set oLogDir = oFSO.GetFolder(APACHE_LOGS)
Print "In " & oLogDir.Name
RotateLogs(oLogDir)
set oLogDir = nothing
end sub
'*****************************************************************************
' Loop through the log files in the Apache logs directory
sub ManagePhpLog()
dim oLogDir
set oLogDir = oFSO.GetFolder(PHP_LOG)
Print "In " & oLogDir.Name
RotateLogs(oLogDir)
set oLogDir = nothing
end sub
'*****************************************************************************
' Traverse through each of the log file types and check if they need rotation
sub RotateLogs(ByVal oFolder)
dim sLog
dim oLog
for each sLog in aLogs
if oFSO.FileExists(oFolder.Path & sLog) then
set oLog = oFSO.GetFile(oFolder.Path & sLog)
if (oLog.Size > MAX_SIZE) then
RotateLog oFolder.Path & sLog
ArchiveLog oFolder.Path & sLog
bHasRotated = true
end if
end if
next
set oLog = nothing
end sub
'*****************************************************************************
' Rotates the given log, by incrementing the file name
sub RotateLog(ByVal sLog)
dim i
dim sOldFile, sNewFile
for i = MAX_ROTATIONS to 1 step -1
sOldFile = sLog & "." & i & ".zip"
sNewFile = sLog & "." & (i+1) & ".zip"
if oFSO.FileExists(sOldFile) and i = MAX_ROTATIONS then
' Delete zipfile
Print "-- Deleting " & sOldFile
oFSO.DeleteFile(sOldFile)
elseif oFSO.FileExists(sOldFile) then
' Rename zipfile
Print "-- Renaming " & sOldFile & " to " & sNewFile
oFSO.MoveFile sOldFile, sNewFile
end if
next
end sub
'*****************************************************************************
' Zips the current log
sub ArchiveLog(ByVal sLog)
Dim oShell
Set oShell = CreateObject("WScript.Shell")
dim sZipFile
sZipFile = sLog & ".1.zip"
Print "-- Archiving " & sLog & " to " & sZipFile
oShell.Run "cmd /c " & ZIP_APP & " -jq " & sZipFile & " " & sLog, 0, true
oFSO.DeleteFile(sLog)
set oShell = nothing
end sub
' ****************************************************************************
' Restarts a given service (in our case Apache)
private sub RestartService( _
ByVal sService _
)
Dim oShell
Set oShell = CreateObject("WScript.Shell")
' Service stopped with 'Net' command
oShell.Run "cmd /c net stop " & sService, 0, true
Print sService & " service stopped"
' Service started with 'Net' command
oShell.Run "cmd /c net start " & sService, 0, true
Print sService & " service restarted"
set oShell = nothing
end sub
'*****************************************************************************
' Echoes out the given message if in debug mode
sub Print(ByVal sMsg)
if (DEBUG_MODE) then
wscript.echo sMsg
else
oLogFile.WriteLine sMsg
end if
end sub
As stated I don't think this is strictly a programming question, but AFAIK there is no built-in functionality in Apache to support log rotation. There's a standard utility on unix systems called logrotate, so that functionality would be redundant on those systems.
If you rephrase your question to ask how you can write a batch file to handle Apache log rotation on Windows 2000, then answer yourself with your batch file source, that might be helpful to others.
Related
Sorry, there is my updated question.
I want to echo all the subfolders and all the files with a specific extension that are inside those subfolders. I would like to echo them like this :
Subfolder 1 :
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder1\File1.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder1\File2.mjb"
Subfolder 2 :
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder2\File1.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder2\File2.mjb"
Subfolder 3 :
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder3\File1.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Subfolder3\File2.mjb"
At the moment, I only manage to echo all the files. So there is two things to see :
How can I echo both of this things.
How can I echo specific file only.
There is my actual code :
setlocal enableDelayedExpansion
set ext=".mjb"
for /f "delims=" %%F in ('dir /b /s /a-d "%_FolderName%"^| findstr /vile "!ext!"') do echo "%%F"
And this is my actual result (I'm trying this in a test_env) :
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier1.qds"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier2.txt"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier4.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier5.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Fichier6.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier1.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier2.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier3.mjb"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein1\Plein1\Fichier4.wmf"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier1.txt"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier4.pdf"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier5.iso"
"C:\Users\546802\Desktop\outil_5s\env_test\Plein2\Fichier6.mjb"
#ECHO Off
setlocal ENABLEDELAYEDEXPANSION
SET "_FolderName=u:\Users\546802\Desktop\outil_5s\env_test"
set "ext=mjb"
SET "currentdir="
for /f "delims=" %%b in ('dir /b /s /a-d "%_FolderName%\*.%ext%"') do (
IF "!currentdir!" neq "%%~dpb" (
SET "currentdir=%%~dpb"
FOR %%c IN ("%%~dpb.") DO ECHO %%~nxc :
SET "files_dir=%%~dpb"
SET "files_dir=!files_dir:%_FolderName%\=!"
ECHO !files_dir:~0,-1! :
)
echo "%%b"
)
GOTO :EOF
Somewhat unclear what you want to do.
Your code performs a findstr with the /v option, so it will select all lines that do not match the mask provided, but the mask provided is resolved to "".mjb"" because you are assigning the quotes within the set statement, then re-quoting it.
It's not clear what header you are asking for where the filename is ...5s\env_test\Plein1\Fichier2.mjb - which may have the same name as ...5s\env_test\Plein1\Plein1\Fichier2.mjb. Is it the direct parent name (plein1 for both instances) or should there be a distinction?
The dir statement above selects all of the .mjb files which appears to be your goal.
currentdir keeps trac of the last parent directory found. If it changes, I've shown two possibilities. The first potential header shown is simply the parent directory name.
The second is calculated by removing the starting directory name from the absolute pathname of the file.
Note that I changed metavariables because F can be confused with ~f (the full-filename modifier operator) and that my testing was performed on drive u: (my RAMdrive)
Thanks for your answer Magoo. Here is the exact thing of what I wanted exactly.
for /F "Tokens=1 Delims=" %%I in ('cscript //nologo explo_fichier.vbs') do set _FolderName=%%I
setlocal enableDelayedExpansion
set "ext=mjb"
set "currentdir="
for /f "delims=" %%b in ('dir /b /s /a-d "%_FolderName%\*.%ext%"') do (
if "!currentdir!" neq "%%~dpb" (
set "currentdir=%%~dpb"
for %%c IN ("%%~dpb.") do echo %%~nxc :
)
echo "%%b"
)
I have a script that opens me the file explorer so I can choose which folder I want to test :
explo_fichier.vbs
Const MY_COMPUTER = &H11&
Const WINDOW_HANDLE = 0
Const OPTIONS = 0
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.Namespace(MY_COMPUTER)
Set objFolderItem = objFolder.Self
strPath = objFolderItem.Path
Set objShell = CreateObject("Shell.Application")
Set objFolder = objShell.BrowseForFolder _
(WINDOW_HANDLE, "Select a folder:", OPTIONS, strPath)
If objFolder Is Nothing Then
Wscript.Quit
End If
Set objFolderItem = objFolder.Self
objPath = objFolderItem.Path
Wscript.Echo objPath
The goal of that is to get those informations so I can zip recursively all this files in a folder with the name of the parent folder. So my first step was getting those informations and now I will use a VBS script that zips everything as I want.
I'm looking for a batch file that allows me to search for files, created within a certain timeframe (e.g. 2013-01-01 till 2013-01-20), with a specific name pattern (e.g. *foo.xml) that contain a certain string (e.g. "mySearchString").
I tried some stuff using the forfiles but it does not allow me to set a date period - it only allows me to search for files before or after a certain date.
Anybody out there to help me with this?
Thanks in advance
Kai
Change the set "searchterm=apple" to your search term
Alter these line to the dates you need
set oldest=2006-06-01
set newest=2006-12-31
Change the filespec in this line: "c:\files\*.txt"
#echo off
:: based upon code by Todd Vargo 2007
setlocal
set "searchterm=apple"
:: Set date range below in yyyy-mm-dd format or your local format.
set oldest=2006-06-01
set newest=2006-12-31
:: =================
set tmp1="%temp%.\dir.out"
:: Set any legal filespec desired below.
dir "c:\files\*.txt" /a-d/s/b >%tmp1%
:: ==================
set vbs="%temp%.\tmp.vbs"
type nul>%vbs%
call :vbs echo >>%vbs%
cscript /nologo %vbs% >"%temp%\filelist.tmp"
del %vbs%
del %tmp1%
for /f "usebackq delims=" %%a in ("%temp%\filelist.tmp") do (
findstr /i /c:"%searchterm%" "%%a" >nul && echo found "%searchterm%" in "%%a"
)
del "%temp%\filelist.tmp" 2>nul
pause
goto :eof
:vbs
%1 d1 = #%oldest%#
%1 d2 = #%newest%#
%1 Const ForReading = 1, ForWriting = 2
%1 'Wscript.Echo DateDiff("d", d1, d2)
%1 Set fso = CreateObject("Scripting.FileSystemObject")
%1 Set f = fso.OpenTextFile(%tmp1%, ForReading)
%1 count = 0
%1 Do Until f.AtEndOfStream
%1 s = f.ReadLine
%1 Set f1 = fso.GetFile(s)
%1 If d1 ^< DateValue(f1.DateCreated) and _
%1 DateValue(f1.DateCreated) ^< d2 Then
%1 Wscript.Echo f1.Path
%1 count = count + 1
%1 End If
%1 Loop
%1 ' Wscript.Echo " Total Files Listed:", count
There are two files which get uploded in D:\CW-Data\edw location every day between 1am to 1:15 am.
My requirement is to auto send us the email wih the file name when both the files are received.
I tried writing a cript which troughs the lastfile which arrives, but i am not getting the expected result. Please help me out:
My script was
set srcDir=D:\Mitul\Quantum AWR Report_23Apr_3am_2pm
set lastmod=
pushd %srcDir%
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
echo %lastmod%
This is a general purpose script for sending an email.
Original thread at https://groups.google.com/forum/?fromgroups=#!msg/alt.msdos.batch.nt/l_8K11YzS0A/WfbVBoJe-l8J
:: Allows ssl and port 465
:: email.cmd ::::::::::::::::::::::::::::::::::::::::::::::::::::
:: Tom Lavedas, Mod 2.14 to eliminate temporary VBS script file
:: Works with IE5+ (and maybe earlier versions as well)
#echo off
setlocal
:Use command line arguments, if supplied
if [%1] EQU [] goto :Continue
set "Arg=%1"
set "Arg=%Arg::==%"
set "Arg=%Arg:/=%"
set "%Arg%"
shift
goto :Use
:Continue
:: defaults
if not defined From set "From=userid#gmail.com"
if not defined To set "To=you#somemail.com"
if not defined Subj set Subj="email test %date% %time%"
if not defined Body set Body="Did it work? %date% %time%"
if not defined Serv set "Serv=smtp.gmail.com"
if not defined Auth set "Auth=userid#gmail.com"
if not defined Pass set "Pass=password"
if not defined fileattach set "fileattach="
if not defined Port set "Port=465"
if not defined SSL set "SSL=True"
if not defined Timeout set "Timeout=25"
call :send %From% %To% %Subj% %Body% %Serv% %Auth% %Pass% %fileattach%
if %errorlevel% NEQ 0 echo Error: %ErrorLevel%
if %0==%~f0 pause
exit /b %ErrorLevel%
:send
set "cdoSchema=http://schemas.microsoft.com/cdo/configuration"
set arguments="%~1+%~2+%~3+%~4+%~5+%~6+%~7+%~f8"
set VBS=resizeTo 1,1:moveTo 1, 3000:
set VBS=%VBS%set ws=createobject("wscript.shell"):
set VBS=%VBS%with createobject("scripting.filesystemobject")
set VBS=%VBS%Execute ws.ExpandEnvironmentStrings(
set VBS=%VBS%.GetStandardStream(0).readALL):end with:
set "VBS=about:<script type=text/vbs>%VBS%:close</script>"
set "Match=VBScript start"
for /f "delims=[]" %%N in (
'find /n "### %Match% ###" ^<"%~f0"'
) do set "N=%%N"
for /f "tokens=1,2 delims=#" %%A in (
'more +%N% "%~f0" ^| mshta.exe "%VBS%"'
) do #echo %%B & exit /b %%A
exit /b 1 % Error in previous statement %
' ### VBScript start ###
set StdOut=.GetStandardStream(1)
args = Split(%arguments%, "+")
with CreateObject("CDO.Message")
.From = args(0)
.To = args(1)
.Subject = args(2)
.Textbody = args(3)
if args(7) <> "" then .AddAttachment args(7)
with .Configuration.Fields
.Item ("%cdoSchema%/sendusing") = 2 ' not local, smtp
.Item ("%cdoSchema%/smtpserver") = args(4)
.Item ("%cdoSchema%/smtpserverport") = %Port%
.Item ("%cdoSchema%/smtpauthenticate") = 1 ' cdobasic
.Item ("%cdoSchema%/sendusername") = args(5)
.Item ("%cdoSchema%/sendpassword") = args(6)
.Item ("%cdoSchema%/smtpusessl") = %SSL%
.Item ("%cdoSchema%/smtpconnectiontimeout") = %Timeout%
.Update
end with ' Configuration.Fields
On Error Resume Next
.Send
end with ' CDO.Message
if Err.Number = 0 then
sRes = "0#Mail sent without error"
else
sRes = Hex(Err.Number) + "#" + Err.Description
end if
stdout.writeline sRes
' ### VBScript end ### - Must be the end of the batch file
#echo off
setlocal
set srcDir=D:\CW-Data\edw
set file1=whateverthenameofthefirstfileis
set file2=whateverthenameofthesecondfileis
:loop
set /a count=0
for /f %%a in ('dir /b "%srcdir%\%file1%" "%srcdir%\%file2%" 2^>NUL') do set /a count+=1
IF NOT %count%==2 timeout /t 5 >nul&GOTO loop
echo send the email
This will wait for the two files to arrive. If either is missing, timeout 5 seconds and try again.
Don't have enough details to provide more.
Addendum:
If your edition of windows doesn't include timeout, try
IF NOT %count%==2 ping -n 5 127.0.0.1 >nul&GOTO loop
I have a windows.bat file which is actually my custom installer. When everything is installed i finally need to create one desktop shortcut icon, which has icon, and link to execute my Java jar. I successfully made one but its using VBS, what i am trying to do now is avoid using VBS but do it completely using BATCH file only. But how do i make this following in BATCH file?
Example:
1) Create an empty file vbs.vbs and paste this code to desktop
set WshShell = WScript.CreateObject("WScript.Shell" )
strDesktop = WshShell.SpecialFolders("AllUsersDesktop" )
set oShellLink = WshShell.CreateShortcut(strDesktop & "\StackOverflow shortcut.lnk")
oShellLink.TargetPath = "c:\application folder\application.exe"
oShellLink.WindowStyle = 1
oShellLink.IconLocation = "c:\application folder\application.ico"
oShellLink.Description = "Shortcut Script"
oShellLink.WorkingDirectory = "c:\application folder"
oShellLink.Save
2) Double click the the vbs.vbs file and instantly it creates a shortcut file
in the desktop tested in Windows XP works
But how do i skip the VBS process and do it completely from my BATCH script?
(Is there any way using RUNDLL32.EXE APPWIZ.CPL,NewLinkHere (Dest))
This was asked and answered before here:
creating a shortcut for a exe from a batch file
One of the provided answers (not the accepted one) has this link:
http://www.robvanderwoude.com/amb_shortcutsnt.php
The relevant script is:
#echo off & setlocal
::For Windows NT 4.0 users only!!!
::Creates LNK and PIF files from the command line.
::Author: Walter Zackery
if not %1[==[ if exist %1 goto start
echo You must pass the path of a file or folder to the
echo batch file as a shortcut target.
if not %1[==[ echo %1 is not an existing file or folder
(pause & endlocal & goto:eof)
:start
(set hkey=HKEY_CURRENT_USER\Software\Microsoft\Windows)
(set hkey=%hkey%\CurrentVersion\Explorer\Shell Folders)
(set inf=rundll32 setupapi,InstallHinfSection DefaultInstall)
start/w regedit /e %temp%\#57#.tmp "%hkey%"
for /f "tokens=*" %%? in (
'dir/b/a %1? 2^>nul') do (set name=%%~nx?)
for /f "tokens=2* delims==" %%? in (
'findstr/b /i """desktop"""= %temp%\#57#.tmp') do (set d=%%?)
for /f "tokens=2* delims==" %%? in (
'findstr/b /i """programs"""= %temp%\#57#.tmp') do (set p=%%?)
(set d=%d:\\=\%) & (set p=%p:\\=\%)
if not %2[==[ if exist %~fs2\nul (set d=%~fs2)
if not %2[==[ if exist %~fs2nul (set d=%~fs2)
set x=if exist %2\nul
if not %2[==[ if not %d%==%2 %x% if "%~p2"=="\" set d=%2
echo %d%|find ":\" >nul||(set d=%d%\)
(set file=""""""%1"""""")
for /f "tokens=1 delims=:" %%? in ("%file:"=%") do set drive=%%?
(set progman=setup.ini, progman.groups,,)
echo > %temp%\#k#.inf [version]
echo >>%temp%\#k#.inf signature=$chicago$
echo >>%temp%\#k#.inf [DefaultInstall]
echo >>%temp%\#k#.inf UpdateInis=Addlink
echo >>%temp%\#k#.inf [Addlink]
echo >>%temp%\#k#.inf %progman% ""group200="}new{"""
echo >>%temp%\#k#.inf setup.ini, group200,, """%name%"",%file%
start/w %inf% 132 %temp%\#k#.inf
del %temp%\#k#.inf %temp%\#57#.tmp
move %p%\"}new{\*.*" %d% >nul 2>&1
rd %p%\}new{ 2>nul
move %p%\}new{.lnk %d%\"drive %drive%.lnk" >nul 2>&1
endlocal
Not sure if that will fly all the way into Win7 and 8
In the end I decided to write the correct script, because no solution works for me
You will need two fileLocal Settings\
first
createSCUT.bat
#echo on
set VBS=createSCUT.vbs
set SRC_LNK="shortcut1.lnk"
set ARG1_APPLCT="C:\Program Files\Google\Chrome\Application\chrome.exe"
set ARG2_APPARG="--profile-directory=QuteQProfile 25QuteQ"
set ARG3_WRKDRC="C:\Program Files\Google\Chrome\Application"
set ARG4_ICOLCT="%USERPROFILE%\Local Settings\Application Data\Google\Chrome\User Data\Profile 28\Google Profile.ico"
cscript %VBS% %SRC_LNK% %ARG1_APPLCT% %ARG2_APPARG% %ARG3_WRKDRC% %ARG4_ICOLCT%
and second
createSCUT.vbs
Set objWSHShell = WScript.CreateObject("WScript.Shell")
set objWSHShell = CreateObject("WScript.Shell")
set objFso = CreateObject("Scripting.FileSystemObject")
If WScript.arguments.count = 5 then
WScript.Echo "usage: makeshortcut.vbs shortcutPath targetPath arguments workingDir IconLocation"
sShortcut = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(0))
set objSC = objWSHShell.CreateShortcut(sShortcut)
sTargetPath = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(1))
sArguments = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(2))
sWorkingDirectory = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(3))
sIconLocation = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(4))
objSC.TargetPath = sTargetPath
rem http://www.bigresource.com/VB-simple-replace-function-5bAN30qRDU.html#
objSC.Arguments = Replace(sArguments, "QuteQ", Chr(34))
rem http://msdn.microsoft.com/en-us/library/f63200h0(v=vs.90).aspx http://msdn.microsoft.com/en-us/library/267k4fw5(v=vs.90).aspx
objSC.WorkingDirectory = sWorkingDirectory
objSC.Description = "Love Peace Bliss"
rem 1 restore 3 max 7 min
objSC.WindowStyle = "3"
rem objSC.Hotkey = "Ctrl+Alt+e";
objSC.IconLocation = sIconLocation
objSC.Save
WScript.Quit
end If
If WScript.arguments.count = 4 then
WScript.Echo "usage: makeshortcut.vbs shortcutPath targetPath arguments workingDir "
sShortcut = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(0))
set objSC = objWSHShell.CreateShortcut(sShortcut)
sTargetPath = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(1))
sArguments = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(2))
sWorkingDirectory = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(3))
objSC.TargetPath = sTargetPath
objSC.Arguments = Replace(sArguments, "QuteQ", Chr(34))
objSC.WorkingDirectory = sWorkingDirectory
objSC.Description = "Love Peace Bliss"
objSC.WindowStyle = "3"
objSC.Save
WScript.Quit
end If
If WScript.arguments.count = 2 then
WScript.Echo "usage: makeshortcut.vbs shortcutPath targetPath"
sShortcut = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(0))
set objSC = objWSHShell.CreateShortcut(sShortcut)
sTargetPath = objWSHShell.ExpandEnvironmentStrings(WScript.Arguments.Item(1))
sWorkingDirectory = objFso.GetAbsolutePathName(sShortcut)
objSC.TargetPath = sTargetPath
objSC.WorkingDirectory = sWorkingDirectory
objSC.Save
WScript.Quit
end If
Damsel in distress needing help with a batch-script.
I have a bunch of files that one system creates. Either in one of 2 directories, or in the directory above that.
The naming is apparently not very important, so It's a bit random.
2 questions for you batch-geniuses out there.
a) How can I append date/time of creation to the end of the filename with a batch-script?
b) How can I append a random filename (so I make the files unique) with a batch-script?
Thanks in advance, dudes and dudettes.
Yours sincerely, the Maclovin!
I have decided in my wisdom to not give a sh*t about the date of creation. I gather it follows the file anyway. What I want to do instead, is to append todays date/time to the file.
This is what I have:
SetLocal EnableDelayedExpansion
set kvitt1="c:\a"
set kvitt2="c:\b"
set tmpDir="c:\temp"
set LASTMOD=
set DATO=%DATE%
set KLOKKE=%TIME%
pause
REM lets go to this directory, and scan for files, and copy to the temp
pushd %kvitt1%
:ONE
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :TWO
COPY "%Lastmod%" %tmpDir%
pause
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
popd
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
REM Let's go to the next directory, and scan for files to copy to the temp
:TWO
REM Gå til ny nettverksstasjon
pushd %kvitt2%
for /f "tokens=*" %%a in ('dir /b /od 2^>NUL') do set lastmod=%%a
if "%lastmod%"=="" echo Could not locate files.&goto :EOF
COPY "%LASTMOD%" %tmpDir%
pause
#ping 127.0.0.1 -n 2 -w 1000 > nul
#ping 127.0.0.1 -n %1% -w 1000> nul
popd
REM we have copied the files we need, lets skip to the temp directory for renaming and filenaming
pushd %tmpDir%
echo %tmpDir%
pause
REM this is clearly not doing much.
REM gåsetegn foran tmpDir fordi det kan finnes filer med mellomrom. dir/b lister opp filene i mappen, og lagrer det i filelist.txt
dir /b "%tmpDir%" >>filelist.txt
pause
REM går igjennom alle linjene i fillist.txt. %%i inneholder filnavnet
pause
REM for /f %%i in (filelist.txt) do
REM (
REM This is clearly not working
for /F "tokens=2,3,4 delims=/ " %%a in ('date /t') do set filedate=%%a-%%b-%%c
ren %filedate%_"%%T" "%T"
REM ren "%%T" %!random%"%%~nT.kvi")
pause
Try this for a:
ECHO Making the copy...
COPY C:\file.txt c:\file_%time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%.txt
PAUSE
CLS
EXIT
The time parsing is done by (leave out the ECHO if using it within naming a file):
ECHO %time:~0,2%%time:~3,2%%time:~6,2%_%date:~-10,2%%date:~-7,2%%date:~-4,4%
I got this from http://www.ozzu.com/mswindows-forum/can-batch-files-use-date-for-filename-creation-t75600.html where theres a bit more details about it.
As for b, the time here records up to seconds so appending the time will make it unique unless your doing more than 1 per second.
EDIT: This gets only the current date. For the batch rename to file date try this instead:
for /f "delims=|" %%f in ('dir /b C:\temp') do call :runsub %%f
goto EOF
:runsub
set t=%~t1
set t=%t::=%
set t=%t: =%
set t=%t:/=%
set renameto=%~n1-%t%%~x1
Copy %1 %renameto%
:EOF
PAUSE
You can change C:\temp to the path you want to change the files in. Let me know if theres any changes you need.
you are better off using vbscript (or powershell if you have) , rather than batch. this is because date manipulation in batch is dependent on regional settings of your computer. You will have to use tricks like going into the registry and stuff as workaround.
Here's a vbscript you can adapt to your needs.
Set objFS = CreateObject( "Scripting.FileSystemObject" )
strFolder = WScript.Arguments(0)
Set objFolder = objFS.GetFolder(strFolder)
t = Now
strDate = Year(t) & Month(t) & Day(t) & Hour(t) & Minute(t) & Second(t)
' by random number
Randomize
upperbound = 99999
lowerbound = 55555
For Each strFile In objFolder.Files
strExtension = objFS.GetExtensionName( strFile )
strName = objFS.GetBaseName( strFile)
rand = Int((upperbound - lowerbound + 1) * Rnd + lowerbound) 'gen random number
' uncomment to use date
' strFile.Name = strName & strDate & "." & strExtension
' uncomment to use random number of your choosing
' strFile.Name = strName & rand & "." & strExtension
Next