Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

174 lines
7.4 KiB

  1. ' Windows Installer utility to report or update file versions, sizes, languages
  2. ' For use with Windows Scripting Host, CScript.exe or WScript.exe
  3. ' Copyright (c) 1999-2000, Microsoft Corporation
  4. ' Demonstrates the access to install engine and actions
  5. '
  6. Option Explicit
  7. ' FileSystemObject.CreateTextFile and FileSystemObject.OpenTextFile
  8. Const OpenAsASCII = 0
  9. Const OpenAsUnicode = -1
  10. ' FileSystemObject.CreateTextFile
  11. Const OverwriteIfExist = -1
  12. Const FailIfExist = 0
  13. ' FileSystemObject.OpenTextFile
  14. Const OpenAsDefault = -2
  15. Const CreateIfNotExist = -1
  16. Const FailIfNotExist = 0
  17. Const ForReading = 1
  18. Const ForWriting = 2
  19. Const ForAppending = 8
  20. Const msiOpenDatabaseModeReadOnly = 0
  21. Const msiOpenDatabaseModeTransact = 1
  22. Const msiViewModifyInsert = 1
  23. Const msiViewModifyUpdate = 2
  24. Const msiViewModifyAssign = 3
  25. Const msiViewModifyReplace = 4
  26. Const msiViewModifyDelete = 6
  27. Const msiUILevelNone = 2
  28. Const msiRunModeSourceShortNames = 9
  29. Const msidbFileAttributesNoncompressed = &h00002000
  30. Dim argCount:argCount = Wscript.Arguments.Count
  31. Dim iArg:iArg = 0
  32. If argCount > 0 Then If InStr(1, Wscript.Arguments(0), "?", vbTextCompare) > 0 Then argCount = 0
  33. If (argCount < 1) Then
  34. Wscript.Echo "Windows Installer utility to updata File table sizes and versions" &_
  35. vbNewLine & " The 1st argument is the path to MSI database, at the source file root" &_
  36. vbNewLine & " The 2nd argument can optionally specify separate source location from the MSI" &_
  37. vbNewLine & " The following options may be specified at any point on the command line" &_
  38. vbNewLine & " /U to update the MSI database with the file sizes, versions, and languages" &_
  39. vbNewLine & " Notes:" &_
  40. vbNewLine & " If source type set to compressed, all files will be opened at the root" &_
  41. vbNewLine & " Using CSCRIPT.EXE without the /U option, the file info will be displayed" &_
  42. vbNewLine &_
  43. vbNewLine & "Copyright (C) Microsoft Corporation, 1999-2000. All rights reserved."
  44. Wscript.Quit 1
  45. End If
  46. ' Get argument values, processing any option flags
  47. Dim updateMsi : updateMsi = False
  48. Dim sequenceFile : sequenceFile = False
  49. Dim databasePath : databasePath = NextArgument
  50. Dim sourceFolder : sourceFolder = NextArgument
  51. If Not IsEmpty(NextArgument) Then Fail "More than 2 arguments supplied" ' process any trailing options
  52. If Not IsEmpty(sourceFolder) And Right(sourceFolder, 1) <> "\" Then sourceFolder = sourceFolder & "\"
  53. Dim console : If UCase(Mid(Wscript.FullName, Len(Wscript.Path) + 2, 1)) = "C" Then console = True
  54. ' Connect to Windows Installer object
  55. On Error Resume Next
  56. Dim installer : Set installer = Nothing
  57. Set installer = Wscript.CreateObject("WindowsInstaller.Installer") : CheckError
  58. ' Check if multiple language package, and force use of primary language
  59. REM Set sumInfo = database.SummaryInformation(3) : CheckError
  60. ' Open database
  61. Dim database, openMode, view, record, updateMode, sumInfo
  62. If updateMsi Then openMode = msiOpenDatabaseModeTransact Else openMode = msiOpenDatabaseModeReadOnly
  63. Set database = installer.OpenDatabase(databasePath, openMode) : CheckError
  64. ' Create an install session and execute actions in order to perform directory resolution
  65. installer.UILevel = msiUILevelNone
  66. Dim session : Set session = installer.OpenPackage(database,1) : If Err <> 0 Then Fail "Database: " & databasePath & ". Invalid installer package format"
  67. Dim shortNames : shortNames = session.Mode(msiRunModeSourceShortNames) : CheckError
  68. If Not IsEmpty(sourceFolder) Then session.Property("OriginalDatabase") = sourceFolder : CheckError
  69. Dim stat : stat = session.DoAction("CostInitialize") : CheckError
  70. If stat <> 1 Then Fail "CostInitialize failed, returned " & stat
  71. ' Join File table to Component table in order to find directories
  72. Dim orderBy : If sequenceFile Then orderBy = "Directory_" Else orderBy = "Sequence"
  73. Set view = database.OpenView("SELECT File,FileName,Directory_,FileSize,Version,Language FROM File,Component WHERE Component_=Component ORDER BY " & orderBy) : CheckError
  74. view.Execute : CheckError
  75. ' Fetch each file and request the source path, then verify the source path, and get the file info if present
  76. Dim fileKey, fileName, folder, sourcePath, fileSize, version, language, delim, message, info
  77. Do
  78. Set record = view.Fetch : CheckError
  79. If record Is Nothing Then Exit Do
  80. REM fileKey = record.StringData(1)
  81. fileName = record.StringData(2)
  82. folder = record.StringData(3)
  83. REM fileSize = record.IntegerData(4)
  84. REM version = record.StringData(5)
  85. REM language = record.StringData(6)
  86. delim = InStr(1, fileName, "|", vbTextCompare)
  87. If delim <> 0 Then
  88. If shortNames Then fileName = Left(fileName, delim-1) Else fileName = Right(fileName, Len(fileName) - delim)
  89. End If
  90. sourcePath = session.SourcePath(folder) & fileName
  91. If installer.FileAttributes(sourcePath) = -1 Then
  92. message = message & vbNewLine & sourcePath
  93. Else
  94. fileSize = installer.FileSize(sourcePath) : CheckError
  95. version = Empty : version = installer.FileVersion(sourcePath, False) : Err.Clear ' early MSI implementation fails if no version
  96. language = Empty : language = installer.FileVersion(sourcePath, True) : Err.Clear ' early MSI implementation doesn't support language
  97. If language = version Then language = Empty ' Temp check for MSI.DLL version without language support
  98. If Err <> 0 Then version = Empty : Err.Clear
  99. If updateMsi Then
  100. record.IntegerData(4) = fileSize
  101. If Len(version) > 0 Then record.StringData(5) = version
  102. If Len(language) > 0 Then record.StringData(6) = language
  103. view.Modify msiViewModifyUpdate, record : CheckError
  104. ElseIf console Then
  105. info = fileName : If Len(info) < 12 Then info = info & Space(12 - Len(info))
  106. info = info & " size=" & fileSize : If Len(info) < 26 Then info = info & Space(26 - Len(info))
  107. If Len(version) > 0 Then info = info & " vers=" & version : If Len(info) < 45 Then info = info & Space(45 - Len(info))
  108. If Len(language) > 0 Then info = info & " lang=" & language
  109. Wscript.Echo info
  110. End If
  111. End If
  112. Loop
  113. REM Wscript.Echo "SourceDir = " & session.Property("SourceDir")
  114. If Not IsEmpty(message) Then Fail "Error, the following files were not available:" & message
  115. ' Update SummaryInformation
  116. If updateMsi Then
  117. Set sumInfo = database.SummaryInformation(3) : CheckError
  118. sumInfo.Property(11) = Now
  119. sumInfo.Property(13) = Now
  120. sumInfo.Persist
  121. End If
  122. ' Commit database in case updates performed
  123. database.Commit : CheckError
  124. Wscript.Quit 0
  125. ' Extract argument value from command line, processing any option flags
  126. Function NextArgument
  127. Dim arg
  128. Do ' loop to pull in option flags until an argument value is found
  129. If iArg >= argCount Then Exit Function
  130. arg = Wscript.Arguments(iArg)
  131. iArg = iArg + 1
  132. If (AscW(arg) <> AscW("/")) And (AscW(arg) <> AscW("-")) Then Exit Do
  133. Select Case UCase(Right(arg, Len(arg)-1))
  134. Case "U" : updateMsi = True
  135. Case Else: Wscript.Echo "Invalid option flag:", arg : Wscript.Quit 1
  136. End Select
  137. Loop
  138. NextArgument = arg
  139. End Function
  140. Sub CheckError
  141. Dim message, errRec
  142. If Err = 0 Then Exit Sub
  143. message = Err.Source & " " & Hex(Err) & ": " & Err.Description
  144. If Not installer Is Nothing Then
  145. Set errRec = installer.LastErrorRecord
  146. If Not errRec Is Nothing Then message = message & vbNewLine & errRec.FormatText
  147. End If
  148. Fail message
  149. End Sub
  150. Sub Fail(message)
  151. Wscript.Echo message
  152. Wscript.Quit 2
  153. End Sub