views:

8

answers:

0

Hi,

I have a specific requirement. I am using a wix project and here I have a dialog box asking for the web application name and port number. After entering something when the user clicks on the next button I want to validate that the port number should not be used by some other application and if it does the setup should show a warning message to the user and asks him to enter a new port.

I have created the wix project and the validation part is done through C# project. I have created the C# project for custom actions project and associated it with the wix project. The main problem that I am facing is that now the installer get crashed when the user clicked the next button. I am not sure where is the problem?

Here is the code for the dialog box that is calling the custom actions dll

    <Control Id="Text18" Type="Text" X="13" Y="9" Width="201" Height="13" Text="!(loc.SharepointWebAppPortInfo)" TabSkip="no" Transparent="yes" />
    <Control Id="Text19" Type="Text" X="13" Y="21" Width="233" Height="25" Text="!(loc.FollowingInfoUsedToConfigureWebApplicationAndPort)" TabSkip="no" Transparent="yes" />
    <Control Id="Bitmap23" Type="Bitmap" X="0" Y="0" Width="382" Height="45" Text="WixUI_Bmp_Banner" TabSkip="yes" Disabled="yes" />
    <Control Id="Line7" Type="Line" X="0" Y="234" Width="382" Height="1" TabSkip="yes" Disabled="yes" />

    <Control Id="TextSharepointWebApplicationInfo" Type="Text" X="35" Y="63" Width="320" Height="70" Text="!(loc.SharepointWebApplicationInfo)" TabSkip="no" Transparent="yes" />
    <Control Id="TextWebApplicationName" Type="Text" X="35" Y="123" Width="110" Height="14" Text="!(loc.SharePointWebApplicationName)" RightAligned="yes" TabSkip="no" />
    <Control Id="EditWebApplicationName" Type="Edit" X="150" Y="120" Width="150" Height="15" Text="\0" Property="MTK_SHAREPOINT_WEB_APPLICATION" TabSkip="no" ToolTip="!(loc.SharePointWebApplicationNameHelp)" />

    <Control Id="TextPortNumber" Type="Text" X="35" Y="143" Width="100" Height="14" Text="!(loc.PortNumber)" RightAligned="yes" TabSkip="no" />
    <Control Id="EditPortNumber" Type="Edit" X="150" Y="140" Width="150" Height="15" Text="\0" Property="MTK_SHAREPOINT_PORT" TabSkip="no" ToolTip="!(loc.SharePointPortHelp)" />

    <Control Id="Back" Type="PushButton" X="189" Y="244" Width="56" Height="17" Text="!(loc.WixUIBack)" TabSkip="no" />
    <Control Id="Next" Type="PushButton" X="244" Y="244" Width="56" Height="17" Text="!(loc.WixUINext)" TabSkip="no" Default="yes">
      <!-- Verify the web application name and port number address -->



      <Publish Property="IdentifierRegExPattern" Value="[IdentifierWebApplicationNamePattern]">1</Publish>
      <Publish Property="Identifier" Value="[MTK_SHAREPOINT_WEB_APPLICATION]">1</Publish>
      <Publish Event="DoAction" Value="ValidateSharePointWebApplicationName">1</Publish>
      <Publish Property="IsValidWebApplicationName" Value="[IdentifierValid]">1</Publish>
      <Publish Event="SpawnDialog" Value="InvalidWebApplictionNameDlg">IsValidWebApplicationName=0</Publish>

      <Publish Property="IdentifierRegExPattern" Value="[IdentifierPortNumberPattern]">1</Publish>
      <Publish Property="Identifier" Value="[MTK_SHAREPOINT_PORT]">1</Publish>
      <Publish Event="DoAction" Value="ValidatePortNumber">1</Publish>
      <Publish Property="IsValidPortNumber" Value="[IdentifierValid]">1</Publish>
      <Publish Event="SpawnDialog" Value="InvalidPortNumberDlg">IsValidPortNumber=0</Publish>

      **<Publish Event="DoAction" Value="PortAvailabilityCheck">1</Publish>
      <Publish Property="WebAppExists" Value="[IdentifierValid]">1</Publish>
      <Publish Event="SpawnDialog" Value="InvalidPortNumberDlg">WebAppExists=0</Publish>**

    </Control>
    <Control Id="Cancel" Type="PushButton" X="309" Y="244" Width="56" Height="17" Text="!(loc.WixUICancel)" TabSkip="no" Cancel="yes">
      <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>
    </Control>
  </Dialog>
</UI>

<!-- 
* Checks for a valid string identifier.  
* Identifier: The identifier to validate
* IdentifierRegExPattern: The identifier to validate
* out property: IdentifierValid: 0 means the string is not valid; otherwise 1
-->
<Property Id="IsValidWebApplicationName" Value="1" Hidden="yes" />
<Property Id="IdentifierWebApplicationNamePattern">!(loc.IdentifierWebApplicationNamePattern)</Property>
<CustomAction Id="ValidateSharePointWebApplicationName" BinaryKey="ca.dll" DllEntry="IsValidString" />

<Property Id="IsValidPortNumber" Value="1" Hidden="yes" />
<Property Id="IdentifierPortNumberPattern">!(loc.IdentifierPortNumberPattern)</Property>
<CustomAction Id="ValidatePortNumber" BinaryKey="ca.dll" DllEntry="IsValidString" />

**<Property Id="WebAppExists" Value="1" Hidden="yes" />
<CustomAction Id="PortAvailabilityCheck" BinaryKey="WIX.IIS.Management.CA.dll" DllEntry="CheckIfPortAvailable" />**

The code for the custom actions project is something like this:

using System; using System.Collections.Generic; using Microsoft.Deployment.WindowsInstaller;

namespace WIX.IIS.Management { public class PortAvailabilityCheck { [CustomAction] public static ActionResult CheckIfPortAvailable(Session session) { try { session.Log("Begin PortAvailabilityCheck.CheckIfPortAvailable");

            string host = session["MTK_SHAREPOINT_WEB_APPLICATION"];
            string port = session["MTK_SHAREPOINT_PORT"];

            if(String.IsNullOrEmpty(host))
                throw new ArgumentException("session[MTK_SHAREPOINT_WEB_APPLICATION] cannot be null or empty");

            if(String.IsNullOrEmpty(port))
                throw new ArgumentException("session[MTK_SHAREPOINT_PORT] cannot be null or empty");

            List<WebSiteInfo> websites = IISHelper.GetListOfDirectories(host, String.Empty, IISHelper.IISVirsion.IIS6);

            bool portOccupied = false;

            foreach (WebSiteInfo wsi in websites)
            {
                if (String.Compare(wsi.PortNo.ToString(), port, StringComparison.OrdinalIgnoreCase) == 0)
                {
                    portOccupied = true;
                    break;
                }
            }

            if (!portOccupied)
                return ActionResult.Success;
            else
                return ActionResult.Failure;
        }
        catch (Exception ex)
        {
            session.Log("Exception PortAvailabilityCheck.CheckIfPortAvailable - {0}", ex.Message);
            return ActionResult.Failure;
        }
    }
}

}

There is a seperate file for loading these DLLs in the project. The code for that file is :

The code written in bold or enclosed in ** Code ** is the main thing. I have associated all for your reference.

I don't know what the issue is and where I am wrong?

Any help is highly appreciated.

Thanks, Vijay