📄 slipstream.vbs
字号:
"has multiple catalogs or I was unable to find the correct catalog. " &_
"The patch cannot be slipstreamed as is since it is not clear which catalog to use." &_
"You must manually install it once you have " &_
"finished building out the system.",vbOK,"Unable to slipstream"
aPatchList(2,i) = false
else
'Even if it does not have a catalog we will try to slipstream it.
MsgBox "The Patch" & vbCrLf & vbCrLf & aPatchList(0,i) & vbCrLf & vbCrLf &_
"has no catalog. This means that I cannot completely slipstream it. " &_
"I will do my best, but you should verify that this patch is installed " &_
"once you are done building out the system.",vbOK,"Problem"
end if 'we found a catalog though
'If you find these patches cannot be slipstreamed, all you need to do is uncomment this line.
' aPatchList(2,i) = false
end if 'if(bFoundLegalCatalog) then
if(aPatchList(2,i) = true) then 'Our belief about this patch's slipstreamability might have changed recently
'Step 4: copy the hotfix binaries into the i386 directory. First we
'must enumerate all the files we care about, then detect whether they exist
'in the i386 directory, delete them if they do, and then copy the new ones.
'Is it possible to have a file in a hotfix that doesn't replace something
' that came in the OS? I suppose so.
'While we are doing this we are writing the values into the dosnet.inf array
Dim fldrDestDir, fldrSourceDir, fileSourceFiles
set fldrDestDir = fso.GetFolder(strInstallPath)
set fldrSourceDir = fso.GetFolder(strPatchDir)
set fileSourceFiles = fldrSourceDir.Files
'Create an array of file names that we don't care about within patches
Redim aNonPatchFiles(11)
aNonPatchFiles(0) = "update.exe"
aNonPatchFiles(1) = "update.inf"
aNonPatchFiles(2) = "spmsg.dll"
aNonPatchFiles(3) = "spcustom.dll"
aNonPatchFiles(4) = "spuninst.exe"
aNonPatchFiles(5) = "update.ver"
aNonPatchFiles(6) = "eula.txt"
aNonPatchFiles(7) = "advpack.dll"
aNonPatchFiles(8) = "w95inf16.dll"
aNonPatchFiles(9) = "w95inf32.dll"
aNonPatchFiles(10) = "empty.cat"
aNonPatchFiles(11) = "custdll.dll"
for each file in fileSourceFiles
'Start out by checking if this is a file we care about
Dim dud, j
dud = false 'Assume we do care.
'We don't care about debug files
if(StrComp(right(file.name,4),".dbg",vbTextCompare) = 0) then
dud = true
end if
for j = 0 to ubound(aNonPatchFiles)
if (StrComp(aNonPatchFiles(j),file.Name,vbTextCompare) = 0) then
dud = true
exit for
end if
next
if(dud = false) then
if(copyFile(strPatchDir & "\" & file.Name, strInstallPath, true) = false) then
continue = 6
continue=MsgBox("Unable to copy " & file.Name & " to " & strInstallPath &_
". This is a fatal error for patch " & aPatchList(0,i) & " and your slipstreamed " &_
"installation point may be corrupted. " & vbCrLf & VbCrLf & "Continue anyway?",vbYesNo,"ERROR")
if continue = 7 then
exit function
end if
end if 'copyFile
end if
next 'for each file in fileSourceFiles
'Check if there are any sub-folders. If so, copy them.
Dim fldrSubfolders, folder
Set fldrSubfolders = fldrSourceDir.Subfolders
for each folder in fldrSubfolders
'See if this folder exists in the fldrI386Dir
if (fso.FolderExists(fldrI386Dir.name & "\" & folder.name)) then
'Copy all the files
Dim files
Set files = folder.files
for each file in files
'Copy it
if( copyFile(file.Name, fldrI386Dir.Name & "\" & folder.Name, true) = false) then
continue = 6
continue=MsgBox("Unable to copy " & file.Name & " to " & fldrI386Dir.Name & "\" & folder.Name &_
". This is a fatal error for patch " & aPatchList(0,i) & " and your slipstreamed " &_
"installation point may be corrupted. " & vbCrLf & VbCrLf & "Continue anyway?",vbYesNo,"ERROR")
if continue = 7 then
exit function
end if
end if 'copyFile
next 'for each file in files
end if
next 'for each folder in fldrSubfolders
end if 'if(aPatchList(2,i) = true) then
else 'We already know this one is a non-starter
MsgBox "The Patch" & vbCrLf & aPatchList(0,i) & vbCrLf &_
"cannot be slipstreamed. You must manually install it once you have " &_
"finished building out the system.",vbOK,"Unable to slipstream"
end if 'if(aPatchList(2,i)) then
Next
movePatches = true
end function
'copyFile - This function takes a file that should be copied from the source directory, checks if it exists at the
'destination, deletes it if necessary, and then copies the new file into the right place. When that is done
'it appends the file name to the dosnet.inf file.
'Parameters:
' strSrcFile - full path including file name of the file to copy
' strDestDir - destination where the new file is going
' bAddToDosNet - boolean guiding whether this file needs to be added to the dosnet file
function copyFile(strSrcFile, strDestDir, bAddToDosNet)
'We need the short name
Dim strSrcFileName
strSrcFileName = right(strSrcFile,len(strSrcFile)-InStrRev(strSrcFile,"\"))
'Check if the file exists
if(fso.FileExists(strDestDir & "\" & strSrcFileName)) then
'If the file already exists, we need to check the dates on the files to avoid overwriting
'a newer file
Dim fileExisting, fileNew
set fileExisting = fso.GetFile(strDestDir & "\" & strSrcFileName)
set fileNew = fso.GetFile(strSrcFile)
'The last modified date is the best way to check whether a file is the most recent one.
'In some patches, the version number was never revved so that is unreliable (and in VBScript we can't
'easily get to it anyway). The creation date is when this copy of the file was created, and the when the file
'was actually modified.
if(fileExisting.DateLastModified > fileNew.DateLastModified) then
'DEBUG
'continue = 6
'continue=MsgBox("The existing version of " & strSrcFileName & " created on " & fileExisting.DateLastModified &_
' " is newer than the one in the patch created on " & fileNew.DateLastModified & ". Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
'DEBUG
'The existing file is newer. Let's leave it
copyFile = true
exit function
else 'if(fileExisting.DateLastModified > fileNew.DateLastModified) then
'Delete it
'DEBUG
'continue = 6
'continue=MsgBox("The new version of " & strSrcFileName & " created on " & fileNew.DateLastModified &_
' " is newer than the existing one created on " & fileExisting.DateLastModified & ". Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
'DEBUG
fso.DeleteFile strDestDir & "\" & strSrcFileName,true 'force delete it
end if 'if(fileExisting.DateLastModified > fileNew.DateLastModified) then
end if 'if(fso.FileExists(strDestDir & "\" & strSrcFileName)) then
'Check whether it exists with a slightly different name. It is possible that
'both are there, so we need to delete both. In this case, the version in the
'patch should be newer since a patch won't have any compressed files
Dim fileCompressedName
fileCompressedName = strDestDir & "\" & left(strSrcFileName,len(strSrcFileName) - 1) & "_"
if(fso.FileExists(fileCompressedName)) then
fso.DeleteFile fileCompressedName,true
end if 'if(fso.FileExists(fileCompressedName)) then
'Now copy it.
fso.CopyFile strSrcFile, strDestDir & "\", true
'This would be a good time to add the file to the dosnet.inf file.
if(bAddToDosNet = true) then
if (addFileToDOSNetINF(strDestDir,strSrcFileName) = false) then
continue = 6
continue=MsgBox("Error adding " & strSrcFileName & " to the dosnet.inf file. " &_
"The file is copied into the right place, but you will " &_
"manually add it to the dosnet.inf file as per KB 828930. Continue?",vbYesNo,"ERROR")
if continue = 7 then
copyFile = false
exit function
end if 'continue = 7 then
end if '(addFileToDOSNetINF(strInstallPath,strSrcFileName) = false) then
end if 'if(bAddToDosNet = true) then
copyFile = true
end function 'copyFile
'findPatchdirs - locates and returns the patch directory and the patch update directory that contains the catalog
'If the function completes successfully it returns true, otherwise false
'Paramters:
' aPatchList - The standard array of patches declared above
' iPatchNum - The integral of the patch we are looking for
' strPatchDir - OUT - The full path to the directory that holds the patch files themselves
' strPatchUpdateDir - OUT - The full path to the update directory that holds the catalog files
' strTargetOS - The target operating system
' strTargetSP - The target SP to patch
function findPatchDirs(aPatchList, iPatchNum, strPatchDir, strPatchUpdateDir, strTargetOS, strTargetSP)
'Set up a variable for the directory name we want
Dim strDesiredSPDir
strDesiredSPDir = strTargetSP 'We assume the patches are organized by the target SP
if(StrComp(strTargetOS,"WinXP",vbTextCompare) = 0) then
'XP Patches, according to KB328848 use the patches for the next SP. In other words, if you are slipstreaming
'SP1, you need the patches from the SP2 directory of a dual mode patch. The theory is that these
'patches will be included in the next service pack.
'Before we continue, let's make sure they did not start shipping XP patches with the server 2003 hotfix installer
if(fso.FolderExists(aPatchList(1,iPatchNum) & "\RTMGDR")) then 'This is a Windows Server 2003-style patch
MsgBox "You are attempting to slipstream Windows XP, but the patch " & aPatchList(1,iPatchNum) & ".exe appears built " &_
"for Windows Server 2003. That type of patch cannot be slipstreamed for Windows XP. Exiting.",vbOkOnly,"ERROR"
findPatchDirs = false
exit function
end if
Dim iSPNum
iSPNum = right(strTargetSP,1)
strDesiredSPDir = "SP" & (iSPNum + 1)
'DEBUG
'continue = 6
'continue=MsgBox("The target OS is XP and the patches are in the " & strDesiredSPDir & " directory. Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
'DEBUG
else
if(StrComp(strTargetOS,"Win2003",vbTextCompare) = 0) then
'Windows Server 2003 patches are different. They use the files from the GDR directory applying to the target SP
strDesiredSPDir = strTargetSP & "GDR"
'DEBUG
'continue = 6
'continue=MsgBox("The target OS is Server 2003 and the patches are in the " & strDesiredSPDir & " directory. Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
'DEBUG
end if 'Win2003
end if 'WinXP
Dim aSPDirs(), i
i=0
'Now try to find the directory with the patch files. For Server 2003 patches, this is easy
if(fso.FolderExists(aPatchList(1,iPatchNum) & "\" & strDesiredSPDir) = true) then
'Very cool, we have found our patch directory
'DEBUG
'continue = 6
'continue=MsgBox("Line: 542" & vbCrLf &_
' "Patch directory: " & strPatchDir & vbCrLf &_
' "Update Directory: " & strPatchUpdateDir & vbCrLf &_
' "strDesiredSpDir: " & strDesiredSPDir & vbCrLf &_
' "aPatchList: " & aPatchlist(1,iPatchNum) & "\" & strDesiredSPDir & vbCrLf &_
' "Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
strPatchDir = aPatchList(1,iPatchNum) & "\" & strDesiredSPDir
'I have not seen this happen, but I suppose the update directory could be under the SP directory
if(fso.FolderExists(strPatchDir & "\update")) then
strPatchUpdateDir = strPatchDir & "\update"
else
if(fso.FolderExists(aPatchList(1,iPatchNum) & "\update") = true) then
strPatchUpdateDir = aPatchList(1,iPatchNum) & "\update"
else
'The update directory must be in the root
strPatchUpdateDir = aPatchList(1,iPatchNum) & "\update"
end if
end if
'DEBUG
'continue = 6
'continue=MsgBox("Line: 566" & vbCrLf &_
' "Patch directory: " & strPatchDir & vbCrLf &_
' "Update Directory: " & strPatchUpdateDir & vbCrLf &_
' "strDesiredSpDir: " & strDesiredSPDir & vbCrLf &_
' "aPatchList: " & aPatchlist(1,iPatchNum) & "\" & strDesiredSPDir & vbCrLf &_
' "Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
'DEBUG
findPatchDirs = true
exit function
end if 'if(fso.FolderExists(aPatchList(1,iPatchNum) = strDesiredSPDir) = true) then
'If we are here, we didn't find based on the SP. It may be that this is one of those really flat patches
'Windows 2000 patches in particular have a very flat structure
if(fso.FolderExists(aPatchList(1,iPatchNum) & "\update")) then
strPatchDir = aPatchList(1,iPatchNum)
strPatchUpdateDir = aPatchList(1,iPatchNum) & "\update"
findPatchDirs = true
exit function
end if 'if(fso.FolderExists(aPatchList(1,i) & "\update")) then
'Frankly, the only other option is a truly flat patch, where everything is in the same directory:
'If we can't find them anywhere else, the patch files are in the patchDir
strPatchDir = aPatchList(1,iPatchNum)
strPatchUpdateDir = strPatchDir
'DEBUG
'continue = 6
'continue=MsgBox("Line: 604" & vbCrLf &_
' "Patch directory: " & strPatchDir & vbCrLf &_
' "Update Directory: " & strPatchUpdateDir & vbCrLf &_
' "strDesiredSpDir: " & strDesiredSPDir & vbCrLf &_
' "aPatchList: " & aPatchlist(1,iPatchNum) & "\" & strDesiredSPDir & vbCrLf &_
' "Continue?",vbYesNo,"INFO")
'if continue = 7 then
'exit function
'end if
findPatchDirs = true
end function
'This function creates the new svcpack.inf file. We get a file name and we are
'to add it to strInstallPath\svcpack.inf
'Parameters:
' strInstallPath - The full path to the slipstream files
' strCatalogFile - The name (not full path) of the catalog file
' strPatchExeName - The name (not the full path) of the unextracted patch executable
' strTargetOS - The target operating system
function writeSvcPackINF(strInstallPath,strCatalogFile,strPatchExeName,strTargetOS)
'First, delete it if it exists
if(fso.FileExists(strInstallPath & "\svcpack.in_")) then
fso.DeleteFile(strInstallPath & "\svcpack.in_")
end if
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -