I'm using Wise Package Studio 7 SP2 to create a transform for a bank app called BankerInsight. I need this app to create per user registry entries based on a printer that is attached to the local computer. This will be dynamic as each pc (over 4000 of them in all) have different local printers installed. The registry holds this data in the format of:

strPrintData & "Bin 1", strKeyValue & ": @ 4", "REG_SZ"

where strPrintData is a variable that is the print name and port (i.e. "MY HP LASERJET on" ).

Prior to packaging, I used a vbscript to write the values that the end user specified into the registry during the startup event through GPO. I'd like my package to include this internally. Here are my thoughts on how this should work. BTW - these devices are locked down so the current user can only write to their own reg. If a new/different user logs on and needs the printer configured, they would also get this process.

1. Install the software during startup GPO as assigned software.
2. After install, a repair option is triggered if the registry does not exist under HKCU hive. This is the default if there is not a printer already configured for this app.
3. Display a dialog that reads the registry subkeys at HKML\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers as each subkey contains the two values I need - Name and Port.
4. Write these values into a combobox on a dialog that would only appear if the HKCU reg is empty.
5. Write the values from the combobox into the registry something like this: I'm using properties.
[PRINTER_NAME] on [PRINTER_PORT] & "Bin 1", strKeyValue & ": @ 4", "REG_SZ"

there are actually about 20 more entries but they are all the same type of data and format.

I'm too new to this to understand how the dialogs work and how to get the data from the dialog into the registry under the condition that the registry is empty for the current user. Any help you can provide is greatly appreciated. I've been tinkering with this for a week now and have learned that I have a lot more learning to do.



I've made much progress in the last few hours. I now have a dialog with only a combo box in the MST. I added a line to call vbs from installation - I saw an article on the Altiris web site for working with combobox objects. The article said to add the vbs line right after MigrateFeatureState. When I do this, I see the dialog and it is populated. Here is the code that I use to get the printer values. Note: I had to append the two values for Port and Name into one property value to get them both from a single combobox.

Function Combo()
' This function initializes and then sets variables to set values for the four columns
' of the ComboBox table (Property, Order, Value and Text). Then a function is called to add
' theValu
' Initialize variables used for each column of the ComboBox table
Dim ComboProp
Dim ComboOrder
Dim ComboValue
Dim ComboText
Const HKEY_CURRENT_USER = &H80000001
Const HKEY_LOCAL_MACHINE = &H80000002

Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\default:StdRegProv")

strKeyPath = "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Print\Printers"
oReg.EnumKey HKEY_LOCAL_MACHINE, strKeyPath, arrSubKeys

For Each subkey In arrSubKeys
'Wscript.Echo subkey
' Set properties for each of the four columns
oReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath & "\" & subkey,"Name",strName
oReg.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath & "\" & subkey,"Port",strPort
ComboProp = "PRINTER_NAME"
ComboOrder = ComboOrder + 1
ComboValue = strName & " on " & strPort
ComboText = strName & " on " & strPort
' Call function to add this row of values to the ComboBox table
addToComboBox ComboProp, ComboOrder, ComboValue, ComboText

End Function

Function addToComboBox(ByVal ComboProp, ByVal ComboOrder, ByVal ComboValue, ByVal ComboText)
' This function takes values passed into it from the function call and uses these values to create
' and execute a view within the current session of the Windows Installer object. This view is based
' on a SQL query constructed using the values passed into the function. If you wish to get a deeper
' understanding of how this function works you should read up on the Windows Installer object
' model in the Windows Installer SDK.
' Initialize variables
Dim query
Dim view
' Construct query based on values passed into the function.
' NOTE: The ` character used is not a single quote, but rather a back quote. This character is typically
' found on the key used for the ~ symbol in the upper left of the keyboard.
query = "INSERT INTO `ComboBox` (`Property`, `Order`, `Value`, `Text`) VALUES ('" & ComboProp & "', " & ComboOrder & ", '" & ComboValue & "', '" & ComboText & "') TEMPORARY"

' This statement creates the view object based on our query
Set view = Session.Database.OpenView(query)
' This statement executes the view, which actually adds the row into the ComboBox table.
End Function

Ok, so here is the next problem or item I need an answer for.

The dialog shows last as it is the last item in the UI portion. I know nothing about the dialogs or MSI script portion of packaging so this is all trial and error and lots of reading. When the dialog is called last in MSI script, the registry does nto get the property value. I moved this to right under MigrateFeatureState and it works. The new problem / issue / complaint is that the dialog shows during the uninstall and also during a repair. I need it to only show as a self heal. I saw the self heal article but do not know enough abou twhat I am doing to correctly diagnose all the events in the dialog portion.
0 Comments   [ - ] Hide Comments


Please log in to comment

Rating comments in this legacy AppDeploy message board thread won't reorder them,
so that the conversation will remain readable.
Answer this question or Comment on this question for clarity


Ok sounds like an interesting setup. (you may be better served posting this in the "Wise Installer" forum as many of the developers in their work with creating dialogue installs everyday)

Now in relation to the order of the items in the combo box. If you want these sorted alphabetically you would need to add the items in the combo box into an array first.

Load the array then sort the entire thing once you have all of the data then call this

addToComboBox ComboProp, ComboOrder, ComboValue, ComboText

over each item in the array. If there is a specific item you want to default you would need to put that as the first entry in the array once you have the entire array content loaded.

Now in order to help you understand why the properties are and are not populated you should have a little backround of the Immediate versus Deferred phases.

During installation a couple of things take place. When the installer gets to the InstallInitialize action its starts the acquisition phase which checks all of the actions between InstallInitialize and InstallFinalize to see if the conditions evaluate to TRUE. Where the conditions are TRUE the items are written to an installation script for later execution. The exception to this rule is where an Immediate Custom action is encountered. Immediate custom actions are executed Immediately.

In short the immediate phase is more of a checking phase which determines if actions are required for the target platform and environment. Generally most dialogues are displayed during the Immediate phase as they can determine how the installation will perform. I expect the CA you use to write to the ComboBox table is an immediate action.

Once the InstallFinalize action is reached after the first parse of the InstallExecute / InstallUI tables the Execution phase starts. During this phase the script which was written previously by the Acquistion phase is executed. Oh I forgot to mention earlier a number of processes are launched. (client / server / user / system) hence the multiple MSIEXEC processes you will see.

As the EXECUTION phase runs all actions written to the script are processed and or executed. All standard actions run at this point deferred actions are processed checking for a Commit or Rollback attribute. If this is found a 2nd script is then generated for future running. If a deferred action is found without a commit or rollback attribute it is executed at this point. The EXECUTION phase is generally where the main installation happens. Also during the EXECUTION phase many of the properties which were available during the ACQUISITION phase are not available unless you use the CustomActionData property to retrieve them. (this is documented very well on Juice)

Once the InstallFinalize (the last item in the script) action is reached whilst running the EXECUTION / DEFERRED phase if any COMMIT or ROLLBACK deferred CA's were found the 2nd script generated when found will be executed.

Again once the InstallFinalize action is reached it then reverts back to the remaining items in the sequence tables. At this point you can again run Immediate CA's and have access to the entire SESSION object. (so you can get property values table stuff etc)

Sorry if I covered stuff you already knew here but I dont know of your level so I felt it necessary.

A question I should ask after all this is, have you thought of doing this with something like active setup as a plain more basic script. My reasoning for this is that you appear to be configuring this to run for first user installation scenario's.

Have you considered after the initial installation a new user may login to the machine and require these scripts to be run again.
Answered 09/16/2007 by: jmcfadyen
Fifth Degree Black Belt

Please log in to comment