iis-6windows-installeriis-7.5http-errorinstallshield-2009

Setting multiple IIS Custom HTTP error messages on InstallShield 2009


How do I set the HTTP custom error messages on a website installed by InstallShield 2009?

It does look deceptively simple. There is an Internet Information Services view, where we can create website or virtual directory objects, and one of the tab for those objects looks like it may let us set custom HTTP Error messages.

It even works to reset 1 or 2 error message, but when I try to reset all the HTTP error message, it does fail.

Specifically, this is the ISIISCommon table on my InstallShield project (XML file format):

<table name="ISIISCommon">
    <col key="yes" def="s72">ISIISCommon</col>
    <col def="S72">ISIISCommon_Parent</col>
    <col def="L255">DisplayName</col>
    <col def="s50">RootDir</col>
    <col def="i4">Attributes</col>
    <col def="L255">DefDoc</col>
    <col def="I4">SessionTimeout</col>
    <col def="I4">ScriptTimeout</col>
    <col def="S255">AnonyUserName</col>
    <col def="S255">AnonyPasswrd</col>
    <col def="S0">CustomErrors</col>
    <col def="L255">AppName</col>
    <col def="S72">SSLCert</col>
    <col def="L72">AppPool_</col>
    <col def="S255">Aspversion</col>
    <col def="S255">SslPassword</col>
    <col def="S255">HostHeaderName</col>
    <row><td>ISIISCommonVRoot</td><td>ISIISCommonWebsite1</td><td>##ID_STRING121##</td><td>WEB</td><td>25873</td><td>Index.html</td><td>20</td><td>90</td><td/><td/><td>400,*,URL,CustomError.html;401,1,URL,CustomError.html;401,2,URL,CustomError.html;401,3,URL,CustomError.html;401,4,URL,CustomError.html;401,5,URL,CustomError.html;403,1,URL,CustomError.html;403,10,URL,CustomError.html;403,11,URL,CustomError.html;403,12,URL,CustomError.html;403,13,URL,CustomError.html;403,14,URL,CustomError.html;403,15,URL,CustomError.html;403,16,URL,CustomError.html;403,17,URL,CustomError.html;403,2,URL,CustomError.html;403,3,URL,CustomError.html;403,4,URL,CustomError.html;403,5,URL,CustomError.html;403,6,URL,CustomError.html;403,7,URL,CustomError.html;403,8,URL,CustomError.html;403,9,URL,CustomError.html;404,*,URL,CustomError.html;405,*,URL,CustomError.html;406,*,URL,CustomError.html;407,*,URL,CustomError.html;412,*,URL,CustomError.html;414,*,URL,CustomError.html;500,*,URL,CustomError.html;500,100,URL,CustomError.html;500,12,URL,CustomError.html;500,13,URL,CustomError.html;500,15,URL,CustomError.html;501,*,URL,CustomError.html;502,*,URL,CustomError.html</td><td>##ID_STRING127##</td><td/><td>##ID_STRING31##</td><td/><td/><td/></row>
</table>

As you may notice, I tried to set all of the HTTP errors on my virtual directory to be redirected to a CustomError.html page. Note also that I think storing this information inside a TD element, and not in its own TABLE, is faulty to a fault, especially on the InstallShield/Windows Installer world.

This doesn't work, on various levels.

First and foremost, here is the installation log,

    MSI (s) (60:14) [12:28:49:025]: Invoking remote custom action. DLL: C:\Windows\Installer\MSI72A0.tmp, Entrypoint: CreateIISVRoots
    InstallShield 12:28:49: User legacy object preference is the following: 1 . This is based on the value of the following property: IISPREFERLEGACYOBJECTS
    InstallShield 12:28:49: InitIISObject
    InstallShield 12:28:49: CreateAppPoolFunction
    InstallShield 12:28:49: OpenKeyLog, pszMDPath =/LM
    InstallShield 12:28:49: AddKey, pszMDPath = /W3SVC/AppPools/MyAppPool
    InstallShield 12:28:49: OpenKeyLog, pszMDPath =/LM/W3SVC/AppPools/MyAppPool
    InstallShield 12:28:49: getvaluelog
    InstallShield 12:28:49: SetVRtStrProperty for property '1002' with value 'IIsApplicationPool' and strSubPath '/'.
[zip]
    InstallShield 12:28:49: SetVRtStrProperty for property '6006' with value 'Index.html' and strSubPath '/'.
    InstallShield 12:28:49: SetData, pszMDPath = /
    InstallShield 12:28:49: SetVRtDelimMultiszProperty for property '6008' with value '400,*,URL,CustomError.html;401,1,URL,CustomError.html;401,2,URL,CustomError.html;401,3,URL,CustomError.html;401,4,URL,CustomError.html;401,5,URL,CustomError.html;403,1,URL,CustomError.html;403,10,URL,CustomError.html;403,11,URL,CustomError.html;403,12,URL,Cus'.
    **InstallShield 12:28:49: SetVRtMultiszProperty for property '6008' and value '400,*,URL,CustomError.html' with length '522'**.

By the look of it, it doesn't like that 522 characters are being used to describe the custom errors. In IIS, only the first 259 characters were consumed, so only an handful of custom errors were correctly set up, the last of one grossly incorrectly (the resulting custom error URL for 403.12 being "cus").

Is there any way to work around this limitation?


Solution

  • I renamed the CustomError page from CustomError.html to ce.htm. This saved some space, but was not enough. A bigger char buffer saver was the good old *. Instead of

    401,1,URL,CustomError.html;401,2,URL,CustomError.html;...;401,13,CustomError.html;401,2,URL,CustomError.html

    I end up using:

    401,*,FILE,ce.htm;

    And this how the virtual directory row looks now in the ISIISCommon table:

        <row><td>ISIISCommonVRoot</td><td>ISIISCommonWebsite1</td><td>##ID_STRING121##</td><td>WEB</td><td>25873</td><td>Index.html</td><td>20</td><td>90</td><td/><td/><td>400,*,FILE,ce.htm;401,*,FILE,ce.htm;403,*,FILE,ce.htm;404,*,FILE,ce.htm;405,*,FILE,ce.htm;406,*,FILE,ce.htm;407,*,FILE,ce.htm;412,*,FILE,ce.htm;414,*,FILE,ce.htm;500,*,FILE,ce.htm;501,*,FILE,ce.htm;502,*,FILE,ce.htm</td><td>##ID_STRING127##</td><td/><td>##ID_STRING31##</td><td/><td/><td/></row>
    

    This may not be suitable for all scenarios (what if someone would like to have different customer errors for 401.1 and 401.2?).

    Also, I had to make this change directly on the InstallShield XML project file, as the GUI wouldn't understand that (and still does, even do it load up the project, and build it correctly, the Custom Errors tab is a mess, I just discount the DEFAULT or suberror specialized entries, they are not there in the resulting MSI file, or this is what Orca says anyway).

    I also moved from URL to FILE as the latter seems more orthogonal to authentication.

    It would be great to read a better solution, and I still wonder why in such a world of tables, someone thought it was going to be a good idea to store a table like that.