
Resolving file paths within MSI databases can be a complex piece of coding. It involves linking files to components and components to the directory table. The complexity is due to the flexibility of Windows Installer in determining how directory table entries are referenced.
The directory table of Windows Installer databases uses chained entries to construct a resultant target path for directories. These directory chains can be altered by custom actions and DOS environment variables.
The script below is an example of how to resolve files from within an MSI to the actual paths from which the file can be expected to be installed.
Using the Script
The header of the script allows for specifying the path to an MSI, the path to the text based report that is to be generated and (if required) a Transform that can be used with the specified MSI. The script resolves files within an MSI to a true path and can be modified to also list file versions, file sizes or file hashes. These properties need to be set before the example can be used.
The script is part of an "MSI Check" utility that I wrote many years ago for creating Infopath based QA documents for Windows Installer packages. Feel free to download the entire set of scripts from the link mentioned.
[[vb]]
'****************************************
'Declare variables
'****************************************
Const HKEY_CURRENT_USER = &H80000001
const HKEY_LOCAL_MACHINE = &H80000002
'****************************************
' Set Reporing Properties
'****************************************
'Set the name and path of the MSI file that is to be queried
strMsiFile = "H:\vc_red.msi"
'If a transform is being used, specify that location
strTransformFile = ""
'Set the output report location
strReportlocation = "H:\MSIReport.xml"
'****************************************
' Set Objects
'****************************************
Set objShell = CreateObject("WScript.Shell")
set objFSO = CreateObject("scripting.FileSystemObject")
Set Installer = CreateObject("WindowsInstaller.installer")
set outfile = objFSO.OpenTextFile(strReportlocation, 8,True,-1) 'open for append
Set Database = Installer.OpenDatabase(strMsiFile, 0)
If Not strTransformFile ="" Then
Database.ApplyTransform strTransformFile, 0
End if
'****************************************
'Script
'****************************************
'we have to be sure that there is a File table within the MSI.
if DoesTableExist("File") = False then
message = message &"This database does not contain any files" &chr(13) &chr(10)
ScriptResult = "Pass"
cleanup
Wscript.quit
end if
'Methodology
'Correctly interpreting Directory structures is complex due to teh flexibility of Windows Installer
'Major complexities occur with:
' * Custom Actions being used to set directories via properties
' * Properties being used to specify directory names and locations
' * MS visual Studio packages that do not have INSTALLDIR references ' * CSDIL directory references
' * NO-OPS dirs that dont actually a directory name
'This is a long and confusing script - for ease of understanding it's broken into staged categories
'that occur sequentially:
' 1. Custom Actions - determine properties set by Custom Actions & verifying they are part of the InstallExecute Sequence
' 2. Directory Table - establishing a table in memory to link directories with actual names
' 3. CSIDL Dir & Longname Resolution - Resolving CSIDL directories and proper 32bit long names
' 4. Apply Custom Actions Changes - Resolving all changes made by Custom Actions to the Directory Table
' 5. Apply Custom Actions Changes #2 - mostly redundant code... more testing is required
' 6. Apply the Property table Changes
' 7. Link Directories - Create the full directory chains
' 8. Directories set as other Directory References - a really nasty thing to do but it's found.
' 9. Resolve DOS ENV directory References (DOS Environment variables used within Directories
' 10. Clean NO Ops Dir References
' 11. Property Hardcoding Resolution - probably redundant code... left for an opportunity to refine and test
'The difficulty of determining the Directory table is complete - the remaining tasks link files to directories
' 12. Link Files & Components via a Dictionary
' 13. Create a file array for resolving all files to respective directory paths
' 14. Bubble Sort resultant File Paths
'*************************
'Custom Actions
'*************************
'Lets find out how many custom actions are involved in setting directories
Type5lcount=0
if DoesTableExist("CustomAction") = True then
'We know there are custom actions but are there custom actions of type 51?
' Recursively list the entries within the Custom Actions Table
Set View = DataBase.OpenView("SELECT * FROM CustomAction")
View.execute
Set record = view.Fetch
While Not (record Is Nothing)
if Record.StringData(2)=51 or Record.StringData(2)=307 then
Type5lcount=Type5lcount+1
end if
Set record = view.Fetch
Wend
end if
'If Type 51 Custom Actions exist we'll need to create an array of their values
if Type5lcount > 0 then
redim Type5lArray(Type5lcount,3)
' Recursively list the entries within the Custom Actions Table 'And populate the created array
Type5lcount=0
Set View = DataBase.OpenView("SELECT * FROM CustomAction")
View.execute
Set record = view.Fetch
While Not (record Is Nothing)
if Record.StringData(2)=51 or Record.StringData(2)=307 then
Type5lArray(Type5lcount,1) = Record.StringData(3) 'Source
Type5lArray(Type5lcount,2) = Record.StringData(4) 'Target
Type5lcount=Type5lcount+1
end if
Set record = view.Fetch
wend
end if
'within out type51 array we have to recursively look for each property
'as MSI's are installed silently we dont want to include logic that does not occur under
'the InstallExecutesequence
if isarray(Type5lArray) then
for x = 0 to ubound(Type5lArray)
'msgbox "current = " &x &"action =" &Type5lArray(x,1)
Set view = DataBase.OpenView("SELECT * FROM InstallExecuteSequence WHERE Action ='" &Type5lArray(x,1) &"'")
View.execute
Set record = view.Fetch
if Not (record Is Nothing) then
Type5lArray(x,3) = 1
end if
next
end if
'Directory Table
Set View = DataBase.OpenView("SELECT * FROM Directory")
View.execute
Set record = view.Fetch
' Recursively list the entries within the Table DirectoryCount-0
While Not (record Is Nothing)
DirectoryCount=DirectoryCount+1
Set record = view.Fetch
wend
DirectoryCount=DirectoryCount-1
'we know the number of entries within the array ' we have to declare our array now
redim DirArray(DirectoryCount,7)
'We can now populate the array
DirectoryCount=0
Set record = view.Fetch
While Not (record Is Nothing)
DirArray(DirectoryCount,1)= Record.StringData(1) 'DirectoryName
DirArray(DirectoryCount,2)= Record.StringData(2) 'Directory parent
'Make an adjustment for TargetDir
If not Record.StringData(1) = "TARGETDIR" then
DirArray(DirectoryCount,3)= longname(Record.StringData(3)) 'DefaultDir
DirArray(DirectoryCount,5)= Record.StringData(2) 'Next Parent
DirArray(DirectoryCount,6)= longname(Record.StringData(3)) 'Readablename 'Only targetdir is resolved
DirArray(DirectoryCount,7)= longname(Record.StringData(3)) 'DefaultDirname - not to be altered
end if
If Record.StringData(2) = "" then
DirArray(DirectoryCount,4)= "1" 'IsResolved 'targetDir is itself resolved
end if
DirectoryCount=DirectoryCount+1
Set record = view.Fetch
wend
DirectoryCount=DirectoryCount-1 'troubleshoot
'CSIDL Dir & Longname Resolution
'SourceDir targetdir - DefaultDir name resolution
'Anything that contains a colon in the Default Dir column states that the source of the files for that
'directory come from a different folder structure. The Source is not what we are interested in
'so to resolve directory names correctly, we remove anything that comes after (and including) the colon
for x = 1 to ubound(dirarray)
if instr(DirArray(x,3),":") >0 then
DirArray(x,3) = left(DirArray(x,3),instr(DirArray(x,3),":") -1)
end if
next
For x = 0 to DirectoryCount
If DirArray(x,1)="TARGETDIR" then
'Packages without INSTALLDIR are resolved via TARGETDIR
if CATargetDir = Nul then
DirArray(x,6) = "C:\"
DirArray(x,3) = "C:\"
DirArray(x,4) = "1" 'IsResolved
else
DirArray(x,6) = CATargetDir
DirArray(x,3) = CATargetDir
DirArray(x,4) = "1" 'IsResolved
end if
end if
If DirArray(x,2)="TARGETDIR" then 'test to see if a CSIDL directory exists 'because of Merge modules we have to parse & split directory names at a period
TempDir=""
if instr(DirArray(x,1),".") >0 then
tempdirarray=split(DirArray(x,1),".")
TempDir =tempdirarray(0)
else
TempDir = DirArray(x,1)
end if
'The Tempdir variable will be set for checking resolution
'The parsed directory name must now be checked against the CSIDL list 'If CSIDL is not detected the original string is returned.
if not ResolveDirName( "[" &TempDir &"]") = "[" &TempDir &"]" then
DirArray(x,6) = ResolveDirName( "[" &TempDir &"]")
DirArray(x,3) = ResolveDirName( "[" &TempDir &"]")
DirArray(x,4) = 1 'Directory is resolved
end if
end if
next
'Apply Custom Actions Changes
For x = 0 to DirectoryCount
'we insert Logic for directories being hard set through Custom Actions
'This is done after other logic as the values for these directories are being
'Hard Set, regardless of MSI Rules
if Type5lCount > 0 then
for y = 0 to Type51Count
if DirArray(x,1) = Type5lArray(y,l) AND Type5lArray(y,3) = 1 then
'we have a directory being Hardcoded through Type 51 Custom Actions DirArray(x,2)= "" 'No directory parent if resolved by Custom Action
DirArray(x,4)= "1" 'IsResolved
varTemp=Type5lArray(y,2)
DirArray(x,3)= ResolveDirName(varTemp)
DirArray(x,6)= ResolveDirName(varTemp)
y = Type5lCount
end if
next
end if
next
'Custom Action properties can also be used as part of destination strings for directories
'Any Type 51 properties need to be set
For x = 0 to DirectoryCount
if Type5lCount > 0 then
for y = 0 to Type5lCount
DirArray(x,6) = Replace (DirArray(x,6),"[" & Type5lArray(y,l) &"]" , Type5lArray(y,2))
DirArray(x,3) = Replace (DirArray(x,3),"[" & Type5lArray(y,l) &"]" , Type5lArray(y,2))
next
end if
next
'Apply Custom Actions Changes #2
'just when you thought there couldn't possibly be any more to deal with 'We find more potental uses for Type 51 Custom Actions
for x= 0 to ubound(dirarray)
if instr(DirArray(x,6),"[") > 0 then 'we need to check the Type 51 Custom Actions
for y = 0 to Ubound(Type5lArray)
'would you believe we have to do this twice due to one really crappy pckage!
if instr(DirArray(x,6),"[" &Type5lArray(y,l) &"]") > 0 AND Type5lArray(y,3) = 1 then' this directory references a second directory\
DirArray(x,6) = Replace(DirArray(x,6),"[" &Type5lArray(y,l) &"]",Type5lArray(y,2) &"\",1,-1,VbTextCompare)
DirArray(x,3) = Replace(DirArray(x,3),"[" &Type5lArray(y,l) &"]",Type5lArray(y,2) &"\",1,-1,VbTextCompare)
end if
if instr(DirArray(x,6),"[" &Type5lArray(y,l) &"]") > 0 AND Type5lArray(y,3) = 1 then' this directory references a second directory\
DirArray(x,6) = Replace(DirArray(x,6),"[" &Type5lArray(y,l) &"]",Type5lArray(y,2) &"\",l,-l,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[" &Type5lArray(y,l) &"]",Type5lArray(y,2) &"\",l,-l,VbTextCompare)
end if
Next
end if
next
'oh the never ending variance of ways to set a directory 'This is very unusual
for x= 0 to ubound(dirarray)
tempstring=""
for y = 1 to 5
if tempstring ="" then
tempstring =DirArray(x,6)
else
end if
if instr(tempstring,"[") > 0 and instr(tempstring,"]") > 0 then
tempstring=right(tempstring,len(tempstring) - instr(tempstring,"[") + 1)
tempstringright=tempstring 'we'll save this for later
tempstring=left(tempstring,instr(tempstring,"]"))
'the tempstring is now a property - we need to compare that property to the directory table
'and to the Property table
if instr(ResolveDirName(tempstring),"c:\") > 0 then
DirArray(x,4) = 1 'Directory is resolved
DirArray(x,6) = Replace (DirArray(x,6),tempstring,ResolveDirName(tempstring) &"\",1,-1,vbTextcompare)
end if
'the ResolveDirname always references C:\
tempstring = right(tempstringright,len(tempstringright)-len(tempstring))
else
Y=5
end if
next
next
'Apply Property Table Changes
'We must also account for directories that are having their Paths directly set through the Property table
'we will run an sql query against the entries of the property table to see if they contain driver references
'if so, stamp their value against the directory table
'we have to be sure that there is a File table within the MSI.
Set View = DataBase.OpenView("SELECT * FROM Property")
View.execute
Set record = view.Fetch
While Not (record Is Nothing)
If instr(Record.StringData(2), ":\") > 0 then
'This particular property is being hardcoded - we need
For x = 0 to ubound(DirArray)
if Record.StringData(1) = DirArray(x,1) then 'the property is setting this directory location
DirArray(x,6) = Record.StringData(2)
DirArray(x,3) = Record.StringData(2)
DirArray(x,4) = 1 'Directory is resolved
x = ubound(DirArray)
end if
next
end if
Set record = view.Fetch
wend
'of course the Property table can be used to just set directory names - we should take them into account
Set view = DataBase.OpenView("SELECT * FROM Property")
view.execute
set record = view.Fetch
while Not (record Is Nothing)
'This particular property is being hardcoded - we need to check against our directory table
For x = 0 to ubound(DirArray)
if instr(DirArray(x,6), "[" &Record.stringData(1) &"]" ) > 0 then
DirArray(x,6) = Replace (DirArray(x,6),"[" &Record.StringData(1) &"]",Record.stringData(2),1,-1,vbTextcompare)
end if
next
set record = view.Fetch
wend
'*************************
'Link Directories
'*************************
'Our DirArray contains the names of every entry from the directory table
'we need to recursively reference these tables until we can resolve a full path 'A directory chain is fully resolved once the Directory Parent to a Directory chain is'set to TARGETDIR
'Code rework will be needed later to resolve this.
'troubleshoot
For x = 0 to ubound(DirArray)
' msgbox x &" of " &ubound(DirArray)'
' msgbox Ucase(DirArray(x,5))
' troubleshoot
'do this for each directory entry in our array
isresolved=0
noparent=0
do until isresolved = 1 or noparent=1
'make sure that every directory is resolved
'as a sanity check - if a drive reference exists dont ty to resolve any further
if instr(DirArray(x,6),":\") > 1 then
isresolved = 1
Exit DO
end if
'The fourth field in the table is set to 1 when the directory is resolved
if DirArray(x,4)= "1" then
isresolved = 1
Exit DO
else
'the directory is not resolved... we need to find the next parent within the array
For z = 0 to ubound(DirArray) 'Find the next parent of the problem directory
'troubleshoot
'msgbox DirArray(z,1)
if Ucase(DirArray(x,5)) = Ucase(DirArray(z,1)) then 'we have found the Next Parent
DirArray(x,5) = DirArray(z,5)
If DirArray(z,4) = "1" then
'the parent is resolved so we add it to the readable directory chain
DirArray(x,6)= DirArray(z,6) &"\" &DirArray(x,6)
'and indicate that our directory is now resolved as well.
DirArray(x,4) = "1"
isresolved =1
exit do
else
'add the parent directory to the chain & set the new parent to be that former grandparent
DirArray(x,6)= DirArray(z,3) &"\" &DirArray(x,6)
DirArray(x,5) = DirArray(z,5)
z = ubound(dirarray)
end if
end if
next
end if
loop
next
'Directories set as other Directory References
'There are situations where Custom Actions set a directory path to be that of another
'property in the Directory table... this shouldn't be done but a number
'of Microsoft packages do this.
'We do one more sweep of the table to see if Resolved directories are referencing another
'Directory property
For z = 0 to ubound(dirarray)
if instr(DirArray(z,6),"[")= 1 then 'we have an unresolved directory referencing a Property
for y = 0 to ubound(dirarray)
if instr(DirArray(z,6),"[" &DirArray(y,1) &"]") =1 then' this directory references a second directory
DirArray(z,6) = Replace(DirArray(z,6),"[" &DirArray(y,1) &"]",DirArray(y,6) &"\",1,-1,VbTextCompare)
y = DirectoryCount
end if
next
end if
next
'*************************
'Resolve DOS ENV directory References
'*************************
for x = 0 to ubound(DirArray)
'msgbox DirArray(x,6)
DirArray(x,6) = Replace(DirArray(x,6),"[%AllUsersProfile]","C:\Documents and Settings\All Users",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%AppData]","C:\Documents and Settings\Username\Application Data",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%CommonProgramFiles]","C:\Program Files\Common Files",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%ProgramFiles]","C:\Program Files",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%SystemDrive]","C:\",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%SystemRoot]","C:\Windows",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%Temp]","C:\Documents and Settings\username\Local Settings\Temp",1,-1,VbTextCompare)
DirArray(x,6) = Replace(DirArray(x,6),"[%UserProfile]","C:\Documents and Settings\Username",1,-1,VbTextCompare)
next
'Add trailing backslashes to directory references as per MSI standards
For x = 0 to ubound(dirarray)
if not instrrev(DirArray(x,6),"\") = len(DirArray(x,6)) then 'add a backslash
DirArray(x,6) = DirArray(x,6) &"\"
end if
next
'*************************
'Clean NO Ops Dir References
'*************************
For x = 0 to ubound(dirarray)
'The only other thing needed to be purged are double backslashes & no op dirs
do until instr(DirArray(x,6),"\.")=0
DirArray(x,6) = Replace(DirArray(x,6),"\.","\")
Loop
do until instr(DirArray(x,6),".\")=0
DirArray(x,6) = Replace(DirArray(x,6),".\","\")
Loop
do until instr(DirArray(x,6),"\\")=0
DirArray(x,6) = Replace(DirArray(x,6),"\\","\")
Loop
if instr(DirArray(x,6),"\") = 1 then
DirArray(x,6)= right(DirArray(x,6),len(DirArray(x,6))-1)
end if
Next
'*************************
'Property Hardcoding Resolution
'*************************
'We have to again look at the property table for hardcoded values 'let's create a dictionary to hold property values
Set View = DataBase.OpenView("SELECT * FROM Property")
View.execute
Set record = view.Fetch
while Not (record Is Nothing)
For x = 0 to ubound(dirarray) 'look at each directory we have
if instr(DirArray(x,6),"[" &Record.StringData(1) &"]") = 1 then 'we have a property that's been hard set.
'Finally check properties against all of our directory entries
DirArray(x,6) = Replace(DirArray(x,6),"[" &Record.StringData(1) &"]",Record.StringData(2),1,-1,VbTextCompare)
end if
next
Set record = view.Fetch
Wend
For x = 0 to ubound(dirarray)
'all directories should now be resolved to a drive or a property in the case of Appsearch
if instr(DirArray(x,6),":\") = 2 OR instr(DirArray(x,6),"[") = 1 then 'the directory is resolved
else
'we assume the Rootdrive will be C:\
DirArray(x,6) = "C:\" &DirArray(x,6)
end if
next
'Directory Resolution is complete... now we link files to Directories via the Component tabl references
'***********************
'Link Files & Components via a Dictionary
'***********************
'The first step is to take all the directory paths and link them to components 'The components can then link file names to give an absolute reference
'We will then have an array listing the fullfilename of every directory and 'file within the package
'We'll create an array of the file table where we can list the InternalMSlFilename with the
'Component and absoute path of the component
'Create a dictionary of File resolution
Set Directorylist = CreateObject("Scripting.Dictionary")
For x = 0 to DirectoryCount
Directorylist.Add DirArray(x,1) , DirArray(x,6)
Next
Dim FileComponent
Set FileComponent = CreateObject("Scripting.Dictionary")
Set View = DataBase.OpenView("SELECT * FROM Component")
View.execute
Set record = view.Fetch
While Not (record Is Nothing)
'Add to the dictionary the list of components - Directory locations
FileComponent.Add Record.StringData(1), Record.StringData(3) 'Component
Set record = view.Fetch
Wend
'***********************
'Create a file array for resolving all files to respective directory paths
'***********************
'Set a counter for the numberof files Filecount=0
Set View = DataBase.OpenView("SELECT * FROM File")
View.execute
Set record = view.Fetch
while Not (record Is Nothing)
Filecount=Filecount+1
Set record = view.Fetch
Wend
redim FileArray(Filecount-1,3)
' Recursively list the entries within the Custom Actions Table 'And populate the created array
Filecount=0
Set View = DataBase.OpenView("SELECT * FROM File")
View.execute
Set record = view.Fetch
while Not (record Is Nothing)
FileArray(Filecount,1)= Record.StringData(1) 'Internal MSI Filename
FileArray(Filecount,2)= Directorylist.Item(FileComponent.Item(Record.StringData(2))) & longname(Record.StringData(3)) 'taking component name & translating it to a directory reference
FileArray(Filecount,3)= longname(Record.StringData(3)) 'filename
Filecount=Filecount+1
Set record = view.Fetch
wend
'Bubble Sort resultant File Paths
'Up to this point, every check has been to determine where files get installed to
'Now we check to see if any of the files are a problem
'lets attempt to modify Bubble sort to order the array
'Bubble Sort... Thanks to Richard Lowe for the code
for i = uBound(FileArray) - 1 TO 0 Step -1
for j= 0 to i
if FileArray(j,2)>FileArray(j+1,2) then
temp= FileArray(j+1,2)
temp2= FileArray(j+1,1)
temp3= FileArray(j+1,2)
FileArray(j+1,2)=FileArray(j,2)
FileArray(j+1,1)=FileArray(j,1)
FileArray(j+1,3)=FileArray(j,3)
FileArray(j,2)=temp
FileArray(j,1)=temp2
FileArray(j,3)=temp3
end if
next
next
'validation Check
for x = 0 to ubound(FileArray)
message=message &FileArray(x,2) &chr(13) &chr(10)
next
ScriptResult = "Info"
'****************************************
'Cleanup
'****************************************
Results
Cleanup
'****************************************
'Functions and Subs
'****************************************
sub Results
outfile.writeline( "")
outfile.writeline( "" &Message &"")
outfile.writeline( "")
outfile.writeline( "")
outfile.close
end sub
function DoesTableExist(strTableName)
Set View = DataBase.Openview("SELECT * FROM _Tables")
view.execute
Set record = view.Fetch
tablefound=0
While Not (record Is Nothing) and tablefound=0
if Record.Stringdata(1) = strTableName then
tablefound=1
end if
Set record = view.Fetch
wend
if tablefound=0 then
DoesTableExist=False
else
DoesTableExist=True
end if
end function
function MakeSafe(tempstring)
tempstring = Replace (tempstring,">",">")
tempstring = Replace (tempstring,"","")
tempstring = Replace (tempstring,"&","&")
tempstring = Replace (tempstring,"'","'")
tempstring = Replace (tempstring,chr(34),""")
MakeSafe = tempstring
end function
sub Cleanup
'Set Objects to Nothing
Set objShell = Nothing
Set wshNetwork = Nothing
Set Installer = Nothing
Set View = Nothing
set Record = Nothing
End Sub
'********************************
'Routine for returning a 32bit filename
function longname(Tempvar)
Tempprefix=0
if instr(Tempvar,".:") =1 then
Tempvar = right(Tempvar,len(Tempvar)-2)
end if
if instr(Tempvar,":") >0 then
Tempvar = left(Tempvar,instr(Tempvar,":") -1)
end if
'Take care of null ops dirs
if Tempvar ="." then
longname = ""
end if
If instr(Tempvar,"|") then
'The string contains long and short names
Tempvar=right(tempvar, len(tempvar) - instr(tempvar,"|"))
If Tempprefix=1 then
Tempvar = ".:" &Tempvar
end if
end if
longname = Tempvar
End function
' ************* Routine for resolving CSIDL directory locations
Function ResolveDirName(TempDirVar)
dim ResolvedDirLocation
varOriginalReference = TempDirVar
if not instr(TempDirVar,"[") = 1 then
TempDirVar ="[" &TempDirVar &"]"
end if
ResolvedDirLocation=""
If TempDirVar = "[AppDataFolder]" then ResolvedDirLocation = "C:\Documents and Settings\Username\Application Data" end if
If TempDirVar = "[AllUsersFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All Users" end if
If TempDirVar = "[AllUsersProfile]" then ResolvedDirLocation = "C:\Documents and Settings\All Users" end if
If TempDirvar = "[AllUsersProfileFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All Users" end if
If TempDirvar = "[AdminTools]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Start Menu\Programs\Administrative Tools" end if
If TempDirvar = "[AdminToolsFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Start Menu\Programs\Administrative Tools" end if
If TempDirvar = "[Common64]" then ResolvedDirLocation = "C:\Program Files\Common Files" end if
If TempDirvar = "[Common64folder]" then ResolvedDirLocation = "C:\Program Files\Common Files" end if
If TempDirvar = "[CommonAppData]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Application Data" end if
If TempDirvar = "[CommonAppDataFolder]" then ResolvedDirLocation = "C:\Program Files\common Files" end if
If TempDirvar = "[Common]" then ResolvedDirLocation = "C:\Program Files\Common Files" end if
If TempDirvar = "[CommonFilesFolder]" then ResolvedDirLocation = "C:\Program Files\Common Files" end if
If TempDirvar = "[CommonFiles64Folder]" then ResolvedDirLocation = "C:\Program Files\common Files" end if
If TempDirvar = "[Desktop]" then ResolvedDirLocation = "C:\Documents and settings\Username\Desktop" end if
If TempDirvar = "[DesktopFolder] " then ResolvedDirLocation = "C:\Documents and settings\Username\Desktop" end if
If TempDirvar = "[Favorites]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Favorites" end if
If TempDirvar = "[FavoritesFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All User\Favorites" end if
If TempDirVar = "[Fonts]" then ResolvedDirLocation = "C:\WINDOWS\Fonts" end if
If TempDirVar = "[FontsFolder]" then ResolvedDirLocation = "C:\WINDOWS\ Fonts" end if
If TempDirvar = "[GlobalAssemblyCache]" then ResolvedDirLocation = "C:\WINDOWS\Assembly" end if
If TempDirvar = "[GAC]" then ResolvedDirLocation = "C:\WINDOWS\Assembly" end if
If TempDirvar = "[LocalAppData]" then ResolvedDirLocation = "C:\Documents and Settings\Username\Application Data" end if
If TempDirvar = "[LocalAppDataFolder]" then ResolvedDirLocation = "C:\Documents and Settings\Username\Local Settings\Application Data" end if
If TempDirvar = "[Personal Folder]" then ResolvedDirLocation = "C:\Documents and settings\Username\My Documents" end if
If TempDirVar = "[MyPictures]" then ResolvedDirLocation = "C:\Documents and Setti ngs\Username\My Documents\My Pictures" end if
If TempDirvar = "[MyPicturesFolder] " then ResolvedDirLocation = "C:\Documents and Settings\Username\My Documents\My Pictures" end if
If TempDirvar = "[Program Files]" then ResolvedDirLocation = "C:\Program Files" end if
If TempDirvar = "[ProgramFilesFolder]" then ResolvedDirLocation = "C:\Program Files" end if
If TempDirvar = "[Personal]" then ResolvedDirLocation = "C:\Documents and Setti ngs\username\My Documents" end if
If TempDirvar = "[Personal folder]" then ResolvedDirLocation = "C:\Documents and settings\username\My Documents" end if
If TempDirVar = "[PrimaryVolumePath]" then ResolvedDirLocation = "C:" end if
If TempDirvar = "[ProgramFiles64]" then ResolvedDirLocation = "C:\Program Files" end if
If TempDirvar = "[ProgramFiles64Folder]" then ResolvedDirLocation = "C:\Program Files" end if
If TempDirvar = "[Programs]" then ResolvedDirLocation = "C:\Documents and Setti ngs\Al 1 Users\Start Menu\Programs" end if
If TempDirvar = "[ProgramsFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Start Menu\Programs" end if
If TempDirVar = "[ProgramMenuFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Start Menu\Programs" end if
If TempDirvar = "[Recent]" then ResolvedDirLocation = "C:\Documents and settings\Username\Recent" end if
If TempDirvar = "[RecentFolder]" then ResolvedDirLocation = "C:\Documents and Settings\Username\Recent" end if
If TempDirvar = "[Start Menu]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Start Menu" end if
If TempDirvar = "[StartMenuFolder]" then ResolvedDirLocation = "C:\Documents and Settings\All Users\Start Menu" end if
If TempDirvar = "[SendTo]" then ResolvedDirLocation = "C:\Documents and settings\username\SendTo" end if
If TempDirVar = "[SendToFolder]" then ResolvedDirLocation = "C:\Documents and settings\username\SendTo" end if
If TempDirVar = "[ShellNew]" then ResolvedDirLocation = "C:\Windows\ShellNew" end if
If TempDirVar = "[ShellNewFolder]" then ResolvedDirLocation = "C:\Windows\ShellNew" end if
If TempDirVar = "[Startup]" then ResolvedDirLocation = "C:\Documents and settings\All users\Start menu\Programs\Startup" end if
If TempDirvar = "[StartUpfolder]" then ResolvedDirLocation = "C:\Documents and Settings\A11 Users\Start Menu\Programs\Startup" end if
If TempDirVar = "[systeml6folder]" then ResolvedDirLocation ="C:\Windows\System" end if
If TempDirVar = "[System32]" then ResolvedDirLocation = "C:\Windows\System32" end if
If TempDirVar = "[System32Folder]" then ResolvedDirLocation = "C:\Windows\System32" end if
If TempDirvar = "[System64]" then ResolvedDirLocation = "C:\Windows\System64" end if
If TempDirVar = "[system64folder]" then ResolvedDirLocation = "C:\Windows\System64" end if
If TempDirVar = "[System]" then ResolvedDirLocation = "C:\windows\System" end if
If TempDirVar = "[SystemFolder]" then ResolvedDirLocation = "C:\Windows\System32" end if
If TempDirvar = "[SYSTemp]" then ResolvedDirLocation = "C:\Documents and settings\username\Local Settings\Temp" end if
If TempDirVar = "[Temp]" then ResolvedDirLocation = "C:\Documents and Settings\username\Local Settings\Temp" end if
If TempDirVar = "[TempFolder]" then ResolvedDirLocation = "C:\Documents and settings\username\Local Settings\Temp" end if
If TempDirvar = "[TemplateFolder]" then ResolvedDirLocation = "C:\Windows\Templates" end if
If TempDirvar = "[UserProfile]" then ResolvedDirLocation = "c:\Documents and Settings\username" end if
If TempDirvar = "[UserProfileFolder]" then ResolvedDirLocation = "C:\Documents and Settings\Username" end if
If TempDirVar = "[WinRoot]" then ResolvedDirLocation = "C:" end if
If TempDirVar = "[Windowsvolume]" then ResolvedDirLocation = "C:" end if
If TempDirVar = "[windows]" then ResolvedDirLocation = "C:\Windows" end if
If TempDirvar = "[WindowsFolder]" then ResolvedDirLocation = "C:\Windows" end if
If TempDirvar = "[WWWROOT]" then ResolvedDirLocation = "C:\Inetpub\wwwroot" end if
If TempDirVar = "[NetHood]" then ResolvedDirLocation = "C:\Documents and settings\username\NetHood" end if
If TempDirVar = "[NetHoodFolder]" then ResolvedDirLocation = "C:\Documents and Settings\username\NetHood" end if
If TempDirVar = "[PrintHood]" then ResolvedDirLocation = "C:\Documents and Settings\username\PrintHood" end if
If TempDirvar = "[PrintHoodFolder]" then ResolvedDirLocation = "C:\Documents and settings\username\PrintHood" end if
if ResolvedDirLocation="" then
' msgbox "unresolved Dir=" &TempDirVar &chr(34)
ResolveDirName =varOriginalReference
else
ResolveDirName = ResolvedDirLocation
end if
End Function
'Routine for retrieving TARGETDIR resolution from MS Packages
Function CATargetDir()
if DoesTableExist("CustomAction") = True then
Set View = DataBase.OpenView("SELECT * FROM CustomAction WHERE Source = 'TARGETDIR'")
View.execute
Set record = view.Fetch
tablefound=0
While Not (record Is Nothing) AND tablefound=0
if Record.StringData(2) = 307 then
'This is a Microsoft package setting TargetDir
tablefound=1
CATargetDir = Record.StringData(4)
end if
Set record = view.Fetch
Wend
End if
end Function
sub troubleshoot()
displaymessage=""
for varx= 0 to ubound(DirArray)
displaymessage = displaymessage & DirArray(varx,1) & "," & DirArray(varx,2) &"," &DirArray(varx,3) &"," &DirArray(varx,4) &"," &DirArray(varx,5) &"," &DirArray(varx,6) &chr(10) &chr(13)
next
wscript.echo displaymessage
end sub
function DoesTableExist(strTableName)
Set View = DataBase.Openview("SELECT * FROM _Tables")
view.execute
Set record = view.Fetch
tablefound=0
While Not (record Is Nothing) and tablefound=0
if Record.Stringdata(1) = strTableName then
tablefound=1
end if
Set record = view.Fetch
wend
if tablefound=0 then
DoesTableExist=False
else
DoesTableExist=True
end if
end function
[[/vb]]
- Log in to post comments