Read an MST file with vbscript - vbscript

I'm trying to do a script that gets information out of some MSI and MST files and write it into a text file. I achieved reading the MSI files. However, I get the following message.
Msi API Error 80004005: OpenDatabase, DatabasePath, OpenMode
1:2219 2: 3:4:
I open the file like this
Set installer = Wscript.CreateObject("WindowsInstaller.Installer") : CheckError
Dim database : Set database = installer.OpenDatabase(FileName, msiOpenDatabaseModeReadOnly) : CheckError
It works just fine with MSI files. I believe MST files should be read in a different way.
How can a read an MST file using vbscript?

I haven't tried myself, but according to MSDN, to view a transform file (MST) you need to open your MSI database and then use the ApplyTransform method with the msiTransformErrorViewTransform parameter. This will give you a temporary _TransformView table, which you can query to get the desired information.
So, your code should look like this:
Const msiOpenDatabaseModeReadOnly = 0
Const msiTransformErrorViewTransform = 256
Dim installer, database
Set installer = CreateObject("WindowsInstaller.Installer") : CheckError
Set database = installer.OpenDatabase(MSIFileName, msiOpenDatabaseModeReadOnly) : CheckError
database.ApplyTransform MSTFileName, msiTransformErrorViewTransform : CheckError

Related

InstallShield - Using vbscript to write to registry

The following code is a peace of a script that is set up to be executed by InstallShield when installing my application: Custom Actions During Installation > After Register Product
Set wsShell = CreateObject("WScript.Shell")
wsShell.RegWrite "HKEY_LOCAL_MACHINE\SOFTWARE\My Program\FilePath", "{the file path}"
When I run the script from command line it runs as it should and writes to the registry. But when I try to use the setup file it shows no errors, but the registry value is not set.
Why is it not working?
I'm running it as administrator.
You can use this code to log information in you msi log, it might help you figure out what is happening
Function LogMSIInfo(msg,msgtype)
Dim rec
Set rec = Session.Installer.CreateRecord(1)
rec.StringData(0) = msg
LogMSIInfo = Session.Message(&H04000000, rec)
End Function

Open a file with notepad and save it, using vbscript

My problem is that I want to open a file in notepad and then save it from notepad, not manually but using vbscript (the reason I want this is to overcome some encoding issues). Until now I have found a relevant article which should solve my problem, but it doesn't work. It has this code:
Dim notepad, wndNotepad, strDesktop
Set notepad = Sys.Process("notepad")
Set wndNotepad = notepad.Window("Notepad")
' Open a file in Notepad
wndNotepad.MainMenu.Click("File|Open...")
notepad.Window("#32770", "Open").OpenFile "C:\Program Files\SmartBear\TestComplete 12\install.txt"
' Save the file to the desktop
strDesktop = WshShell.SpecialFolders("Desktop")
wndNotepad.MainMenu.Click "File|Save as..."
notepad.Window("#32770", "Save As").SaveFile strDesktop & "\install.txt"
The problem is that vbscript can't recognize the Sys in the second line (Sys.Process). I assume that in this line a process for notepad should be created (like here) and then something like an object of this process to be returned to the variable notepad (something I don't know if and how can be achived) in order to be used in the third line (notepad.Window("Notepad")).
If anyone has any idea how the code should be in order to work, I would really appreciate the help. Also any other suggestions on how to solve this problem (or any ideas about if it can actually be solved) are very welcome. Thank you for your time.
EDIT
As I said in the comments below, the above code needs the TestComplete software which is expensive. So if anyone has any idea for resolving my issue in another way (other software, other code, other programming language) I would be glad to learn it.
I think you need to copy a file from one path to another. Please refer the below code for copying Files,
Function CopyFile()
strSourceFile = "c:\.....\source.txt"
strDestFile = "c:\.....\dest.txt"
Set fso = CreateObject("Scripting.FileSystemObject")
'Check to see if the file is read-only
If Not fso.GetFile(DestinationFile).Attributes And 1 Then
'The file exists and is not read-only. Safe to replace the file.
fso.CopyFile strSourceFile, strDestFile, strOverWrite
Else
'The file exists and is read-only.
'Remove the read-only attribute
fso.GetFile(DestinationFile).Attributes = fso.GetFile(DestinationFile).Attributes - 1
'Replace the file
fso.CopyFile strSourceFile, strDestFile, strOverWrite
'Reapply the read-only attribute
fso.GetFile(DestinationFile).Attributes = fso.GetFile(DestinationFile).Attributes + 1
End If
End Function

Replace text within a file

Hello I've tried a lot of researching but cant find what I need and haven't been able to successfully piece this together myself.
Each of my users have a XML file within their profile that I would like to edit. The file contains a reference to their computer name and clientname, which are out of date each time they login to a new terminal. I need to replace these with the current computername and clientname. The bit I cannot figure out how to do is how to search the XML for the computername when I only know the first few characters, then replace it.
my XML will have any entry something like this
"InstalledPrinter name="\WHBCVDI0109\LabelPrinter650 (from IGEL-00E0C533943E)"
I need to search the file and replace the WHBCVDI0109 and the IGEL-00E0C533943E with the correct entries. My script successfully gets those entries I just dont know how to find and replace them in the file.
My script looks like this:
Const ForReading = 1
Const ForWriting = 2
Set oShell = CreateObject( "WScript.Shell" )
'Get Variables
user=oShell.ExpandEnvironmentStrings("%UserName%")
appdata=oShell.ExpandEnvironmentStrings("%appdata%")
strComputerName = oshell.ExpandEnvironmentStrings( "%COMPUTERNAME%" )
'Set XML location
strfile = appdata & "\Smart Label Printer\SlpUserConfig.xml"
'Open
Set objfso = CreateObject("Scripting.FileSystemObject")
Set filetxt = objfso.OpenTextFile(strfile, ForWriting)
strTemp = "HKEY_LOCAL_MACHINE\SOFTWARE\Citrix\ICA\Session\ClientName"
WScript.Echo "client name is : " & oShell.RegRead(strTemp)
An pointers would be much appreciated.
You shouldn't use the FileSystemObject and String/RegExp operations to edit an XML file. Using the canonical tool - msxml2.domdocument - is less error prone and scales much better.
See here for an example (edit text); or here for another one (edit attribute).
If you publish (the relevant parts of) your .XML file, I'm willing to add same demo code specific for your use case here.

Getting error 800a03ec while opening an Excel file

I have written following code to convert XLSX file to CSV format:
If WScript.Arguments.Count < 2 Then
WScript.Echo "Error! Please specify the source path and the destination. Usage: XlsToCsv SourcePath.xls Destination.csv"
Wscript.Quit
End If
Dim oExcel
Set oExcel = CreateObject("Excel.Application")
Dim oBook
Set oBook = oExcel.Workbooks.Open(Wscript.Arguments.Item(0))
oBook.SaveAs WScript.Arguments.Item(1), 6
oBook.Close False
oExcel.Quit
It was working fine when I was giving server path for XLSX file. But, when I am giving local machine path, it is giving me following error:
File could not be found. Check the spelling of the file name, and verify that file location is correct. If you are trying to open the file from list of most recently used files, make sure that file has not been renamed, moved or deleted
code: 800A03EC
Source: Microsoft Office Excel
In case anyone with a similar problem finds this, the error code seems to be a general Excel error which means that it could not open the file.
In my case I tried opening the same file manually and found that Excel wanted to repair a corrupted file. I had been allowed to save it with incorrect validations, but it wouldn't open programmatically. Opening it by hand meant that it could show me a dialog asking whether I wanted to fix it or not.
If you are still getting this error, I would do a simple echo on both your arguments to make sure they are doing exactly what they should be doing
wscript.echo "Arg(0): " & WScript.Arguments.Item(0) & " Arg(1): " & WScript.Arguments.Item(1)
Also if you are using cscript.exe to run it, it will by default be looking for the files in c:\windows\system32\ directory
In my case the corresponding message is "Unable to set the PaperSize property of the PageSetup class". That occurs when the standard printer is not capable of the page format of the Excel workbook/sheet.

Client-Side VBScript application, Incorrect Current Working Directory

I'm not understanding this behavior. Maybe someone can explain to me why my current working directory is not what I expect.
On my desktop, I have a folder called STKGui:
C:\Documents and Settings\Lauren\Desktop\STKGui
Located in that directory are the following files: gui.html, style.css, save.html, load.html Within STKGui there are also the following directories: Images, Scripts, and SaveData. Scripts contains various .vbs files, including gui.vbs.
I start with gui.html. I click a button which takes me to load.html. load.html uses scripts from Scripts\gui.vbs. One of the functions loads a database, and to do so I provide the location of the database: C:\Documents and Settings\Lauren\Desktop\STKGui\SaveData\SaveData.accdb Of course I want to use a relative file path instead of a fixed path. My initial attempt to load the database failed; it was trying to load from C:\Documents and Settings\Lauren\Desktop\SaveData\SaveData.accdb. So to troubleshoot I printed out the current working directory; much to my chagrin it was C:\Documents and Settings\Lauren\Desktop
I don't understand why my desktop is my current working directory. Shouldn't it be where the file is running from? I figured it would be either C:\Documents and Settings\Lauren\Desktop\STKGui (the location of load.html) OR C:\Documents and Settings\Lauren\Desktop\STKGui\Scripts (the location of gui.vbs which contains the function that's trying to load the database/printing debug messages of the current working directory).
Can someone explain why the current working directory is what it is, or better yet tell me how to get what I really want, which is the location of the files executing? (I don't care if it's the main STKGui folder or the scripts folder--as long as it's within the application's directory structure I can work with it!)
EDIT (7/14/10 4:02 pm EDT):
Various attempts at printing the current working directory or grabbing files based on what I -thought- was the relative path from my executing script have resulted in my desktop's path instead of the path of the executed script. I stumbled across this link: http://leereid.wordpress.com/2008/03/19/vbscript-current-directory-or-folder/ but none of the solutions are working for me, as I get run-time errors regarding the Wscript object. So while I don't know if any of the solutions on the aforementioned link will produce different results, if someone can help me get at least one of them working so I can find out that may be a step in the right direction.
One of the solutions, reproduced below:
Set oShell = CreateObject("WScript.Shell")
Set ofso = CreateObject("Scripting.FileSystemObject")
oShell.CurrentDirectory = ofso.GetParentFolderName(Wscript.ScriptFullName)
produces the following error:
Object required: 'Wscript' line: 659 char: 1
with line 659 being:
oShell.CurrentDirectory = ofso.GetParentFolderName(Wscript.ScriptFullName)
For Server-Side:
You should be using Server.MapPath() to get your "working directory". For instance, if you want to get the path to your database file in C:\Documents and Settings\Lauren\Desktop\STKGui\SaveData\SaveData.accdb, your app root being C:\Documents and Settings\Lauren\Desktop\STKGui, you would use Server.MapPath("SaveData\SaveData.accdb").
For Client-Side:
Upon closer examination and digging up some memories, I realized that MapPath is only available from the Server class. Instead, you need to create a file system object like this:
''get fs object
Set objFSO = CreateObject("Scripting.FileSystemObject")
''get actual file using path relative to calling vbs file
Set objFile = objFSO.GetFile("SaveData\SaveData.accdb")
''get path to the database
set sPathToDatabase = objFSO.GetAbsolutePathName(objFile)
In case it helps, here is a great resource for working with the file system in vbScript: http://www.activexperts.com/activmonitor/windowsmanagement/adminscripts/filesfolders/files/
This solution was NOT ideal, but what I ended up doing was parsing the url in my browser to get the directory.
guiPath = Mid(location.PathName, 2, len(location.PathName))
Set regExp = New RegExp
regExp.IgnoreCase = False
regExp.Global = True
regExp.Pattern = ".*/"
Set matchCollection = regExp.Execute(guiPath)
Set match = matchCollection(0)
guiPath = match.value
regExp.Pattern = "%20"
guiPath = regExp.Replace(guiPath, " ")
systemsDBPath = guiPath & "SaveData\SaveData.accdb"
Like I said, less than ideal. May not even work once I'm working with the application this will be running in. But I couldn't find a better way.

Resources