views:

306

answers:

1

In WiX I have a vbScript for use in a Custom Action that will return ListItems of Network Printers. I want to use these ListItems to populate the ComboBox at Install Time because I won't know the printer names on the users system until after starting the installation.

Here is the vbScript. It currently outputs to a text file pending how to work with it to answer my question.

Const ForWriting = 2

Set objNetwork = CreateObject("Wscript.Network")

strName = objNetwork.UserName
strDomain = objNetwork.UserDomain
strUser = strDomain & "\" & strName

strText = ""

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where Local = FALSE")

For Each objPrinter in colPrinters
    strText = strText & "<ListItem Text=""" & objPrinter.Name &""" Value="""& objPrinter.Name &"""/>" & vbcrlf
Next

Set objFSO = CreateObject("Scripting.FileSystemObject")

Set objFile = objFSO.CreateTextFile _
    ("C:\Scripts\Printers.txt", ForWriting, True)

objFile.Write strText

objFile.Close

And this is the output :

<ListItem Text="\\xfiles\Canon iR3030 PCL6" Value="\\xfiles\Canon iR3030 PCL6"/>
<ListItem Text="\\xfiles\HP2110" Value="\\xfiles\HP2110"/>

I am hoping to be able to use this output as ListItems for my ComboBox.

<Control Type="ComboBox" Property="cboPrinters_Prop" Id="cboPrinters" Width="206" Height="16" X="19" Y="139" ComboList="yes">
   <ComboBox Property="cboPrinters_Prop">
      <ListItem Text="" Value=""/>
   </ComboBox>
</Control>

If there is a better way or I am approaching this all wrong(I keep trying to think like a developer) please feel free to correct me. I am thick skinned... :)

A: 

As I suspected toward the end of my original post there was a different way and I was going about it wrong. At least somewhat. Being new to WiX I didn't take into consideration the fact that the values should be added to the database. Given that I hadn't run across this yet in my experiences I got to learn something new.

So here's what I did to get the values to display in my ComboBox:

1.) Script above was modified to use the collection to send the appropriate values to the database table named ComboBox.


2.) Using Orca I added the ComboBox table. BTW it just holds the information for ListItems used in, wait for it... ComboBoxes.


3.) Added the appropriate Custom Action.


4.) Called it just before the form loads.

Here's the vb Script:

Const ERROR_SUCCESS = 0
Const ERROR_INSTALL_FAILURE = 1603
Const msiViewModifyInsertTemporary = 7

Function LogInfo(msg) 
    Dim rec
    Set rec = Session.Installer.CreateRecord(1) 
    rec.StringData(0) = msg
    LogInfo = Session.Message(&H04000000, rec)
End Function



Function GetNetworkPrinters()
Dim oView, oReccombo
Dim r

LogInfo "INSIDE GetNetworkPrinters"
Set objNetwork = CreateObject("Wscript.Network")

strName = objNetwork.UserName
strDomain = objNetwork.UserDomain
strUser = strDomain & "\" & strName

strText = ""

strComputer = "."

Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")

Set colPrinters = objWMIService.ExecQuery _
    ("Select * From Win32_Printer Where Local = FALSE")


Set oView = Session.Database.OpenView("SELECT * FROM `ComboBox`")
oView.Execute
r = 1
For Each objPrinter in colPrinters
r = r + 1

LogInfo "THE PRINTER NAME IS " & objPrinter.Name

Set oReccombo = Session.Installer.CreateRecord(4)
oReccombo.StringData(1) = "cboPrinters_Prop"
oReccombo.IntegerData(2) = r
oReccombo.StringData(3) = objPrinter.Name
oReccombo.StringData(4) = objPrinter.Name
LogInfo "Made it to the call to insert the record"
oView.Modify msiViewModifyInsertTemporary, oReccombo

Next
oView.Close

GetNetworkPrinters = ERROR_SUCCESS

Set oView = Nothing
End Function

Add a Binary entry:

<Binary Id="GetNetworkPrinters" SourceFile="*Enter the full path to the script here* \GetNetworkPrinters.vbs" />

Add the Custom Action:

<CustomAction Id="AddPrintersToComboBox" BinaryKey="GetNetworkPrinters" VBScriptCall="GetNetworkPrinters" Execute="immediate" Return="check" HideTarget="no" Impersonate="yes" />

Add the Call to the Custom Action in the InstallUISequence and the AdminUISequence:

<Custom Action="AddPrintersToComboBox" Before="MaintenanceForm"></Custom>

That is it... Now of course the script needs to be cleaned up to generate better log information and also needs better (some) error handling but it definitely works.

I hope this helps others...

David G