Search code examples
installationwixwindows-installerisapi

WIX: How can I register a new ISAPI Extension or Script Map on an existing Web App or Site?


I've seen the WebApplicationExtension element, but because it must be a child of WebApplication, it appears to require the creation of a new WebApplication. I don't want that.

I want to create the extension (or script map) on an existing website. On uninstall, the website should remain but the extension (script map entry) should be removed.

Anyone know how to do this in WIX?


If I get no good answers, I guess I will have to do it within script before InstallFinalize.


Solution

  • I couldn't figure out a way to do this in WIX, so I resorted to a custom action. I had been writing all my custom actions in Javascript. I find Javascript to be easy to use and robust for that purpose, despite what others have said.

    But I could not find a way to add a scriptmap from Javascript, because the IIS metabase update requires the use of a VBArray datatype, which is supported in VBScript, but not in Javascript. Whoops.

    So, here is the code, in VBScript.

    Function AddExtension_CA()
    
        VBSLogMessage("AddExtension_CA() ENTRY")
        Dim iis
        Set iis = GetObject("winmgmts://localhost/root/MicrosoftIISv2")
    
        dim siteName
        siteName = Session.Property("WEBSITE_NAME")
    
        VBSLogMessage "website name(" & siteName & ")"
    
        If (siteName <> "") Then
            Dim idir, dll
            idir = Session.Property("INSTALLDIR")
            dll = idir & "\MyIsapiExtension.dll"
    
            Dim query
            If (siteName <> "W3SVC") Then
                query = "SELECT * FROM IIsWebServerSetting WHERE Name = '" & siteName & "'"
            Else
                query = "SELECT * FROM IIsWebServiceSetting"
            End If
    
            Set results = iis.ExecQuery(query)
            Dim newMaps()   '' dynamically-sized Array
    
            '' two passes
            For t = 0 to 1
                Dim c
                c=0
                For Each item in results
                    '' in pass 1, count them. 
                    '' in pass 2, copy them.
                    For i = 0 to Ubound(item.ScriptMaps)
                        If UCase(item.ScriptMaps(i).Extensions) <> ".IIRF" Then
                            If t = 1 Then
                                Set newMaps(c) = item.ScriptMaps(i)
                            End if
                            c = c+1
                        End If
                    Next
    
                    If t = 0 Then
                        ReDim Preserve newMaps(c)
                    Else
                        VBSLogMessage("setting new filter")
    
                        Set newMaps(c) = iis.get("ScriptMap").SpawnInstance_()
                        newMaps(c).Extensions = ".iirf"
                        newMaps(c).ScriptProcessor= dll
                        newMaps(c).Flags = "1"
                        newMaps(c).IncludedVerbs = "GET,POST"
                        item.ScriptMaps = newMaps
                        item.Put_()
                    End If
                Next
            Next
    
            VBSLogMessage("Allowing the DLL as an Extension")
    
            dim IIsWebServiceObj
            Set IIsWebServiceObj = GetObject("IIS://localhost/W3SVC")
            IIsWebServiceObj.AddExtensionFile dll, True, "GroupId", True, "Description of the Extension"
            Set IIsWebServiceObj = Nothing
    
        End If
    
        Set iis = Nothing
    
        VBSLogMessage("AddExtension_CA() EXIT")
    
        AddExtension_CA = 1   ' MsiActionStatus.Ok
    
    End Function
    

    Here's the WIX code:

    <Fragment>
        <CustomAction Id="CA.AddExtension"
                  BinaryKey="B.VBScript"
                  VBScriptCall="AddExtension_CA"
                  Execute="immediate"
                  Return="check" />
    
        ....
    

    See also:
    AddExtensionFile.