2

I am creating an installer using wix. I need to install a service as user account given in installation process. But, before installing the service how can i validate that the user and the password are valid and also have the enough privilages to install the service. Is there any way to do that??

Following code in wix helps me to install service.

<ServiceInstall Id="AServiceInstall" DisplayName="myservice"     Name="myservice" ErrorControl="normal" Start="auto" Vital="yes" Type="ownProcess" Account="[ACCOUNT]" Password="[PASSWORD]">
            <ServiceDependency Id="x"></ServiceDependency>
          </ServiceInstall>
eeshwr
  • 258
  • 4
  • 20

2 Answers2

2

For validating complex user input I generally have to create a custom action to do it.

Here is an example dialog I have for validating the URL to a web service and making sure it is accessible:

<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Fragment>
    <CustomAction Id="ValidateProxyService" BinaryKey="XXX.CommServer.CustomActions.dll" DllEntry="ValidateProxyService" Return="check" />

    <UI>
      <Dialog Id="XxxInquiryServiceDlg" Width="370" Height="270" Title="CommService Setup">
        <Control Id="BannerBitmap" Type="Bitmap" X="0" Y="0" Width="370" Height="44" TabSkip="no" Text="!(loc.InstallDirDlgBannerBitmap)" />
        <Control Id="BannerLine" Type="Line" X="0" Y="44" Width="370" Height="0" />
        <Control Id="BottomLine" Type="Line" X="0" Y="234" Width="370" Height="2" />
        <Control Id="Description" Type="Text" X="25" Y="23" Width="280" Height="15" Transparent="yes" NoPrefix="yes" Text="Configure the settings for the xxx." />
        <Control Id="Title" Type="Text" X="15" Y="6" Width="210" Height="15" Transparent="yes" NoPrefix="yes" Text="{\WixUI_Font_Title}Configure xxx" />
        <Control Type="Text" Id="ProxyServiceLabel" Width="95" Height="10" X="11" Y="60" Text="XXX Proxy Service URL:" />
        <Control Type="Edit" Id="ProxyServiceTextBox" Width="244" Height="15" X="112" Y="58" Property="XXX_PROXY_SERVICE_URL" />
        <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)">
          <Publish Event="DoAction" Value="ValidateProxyService" Order="1">1</Publish>
        </Control>
        <Control Id="Back" Type="PushButton" X="180" Y="243" Width="56" Height="17" Text="!(loc.WixUIBack)" />        
        <Control Id="Cancel" Type="PushButton" X="304" Y="243" Width="56" Height="17" Cancel="yes" Text="!(loc.WixUICancel)">
          <Publish Event="SpawnDialog" Value="CancelDlg">1</Publish>          
        </Control>
      </Dialog>
    </UI>
  </Fragment>
</Wix>

Then the custom action I wrote:

[CustomAction]
public static ActionResult ValidateProxyService(Session session)
{
    try
    {
        string proxyServiceUrl = session["XXX_PROXY_SERVICE_URL"];
        string message;

        if (string.IsNullOrWhiteSpace(proxyServiceUrl))
        {
            session["XXX_PROXY_SERVICE_VALID"] = string.Empty;
            MessageBox.Show(
                "The proxy service URL is required.",
                "Error",
                MessageBoxButtons.OK,
                MessageBoxIcon.Error);
            return ActionResult.Success;
        }
        else if (!ValidateUrl(proxyServiceUrl, out message))
        {
            if (MessageBox.Show(
                message,
                "Error",
                MessageBoxButtons.OKCancel,
                MessageBoxIcon.Warning) == DialogResult.Cancel)
            {
                session["XXX_PROXY_SERVICE_VALID"] = string.Empty;
                return ActionResult.Success;
            }
        }

        session["XXX_PROXY_SERVICE_VALID"] = "1";
    }
    catch (Exception ex)
    {
        session.Log("An error occurred during ValidateProxyService: {0}", ex);
        return ActionResult.Failure;
    }

    return ActionResult.Success;
}

The general overview of what is going on is the dialog asks for a URL and puts it in the XXX_PROXY_SERVICE_URL property. When you press the Next button on the dialog it will run the custom action. The custom action then reads the XXX_PROXY_SERVICE_URL and tests if it is valid and tries to load the page. If it is invalid or fails it unsets the XXX_PROXY_SERVICE_VALID property.

In the main UI for the installer I have:

<Publish Dialog="XXXServiceDlg" Control="Next" Event="NewDialog" Value="OtherDlg" Order="2">XXX_PROXY_SERVICE_VALID</Publish>

So it will not proceed to the next page without the service being valid.

A few caveats:

  • I am just displaying a warning dialog and asking them if they want to continue (yes/no) even though the input is invalid, in situations where the service is not accessible now but they still need to complete the installation.
  • I really would like to handle the message dialog using WIX dialogs. Since I can't get the handle of the installer window, using the MessageBox class tends to pop under the installer under some circumstances still unknown to me. I also think it would be cleaner to handle all of the UI in WIX.
  • Certain useful things to validate require administrator access. Which creates annoying usability implications when generating an MSI. To run the UI part of an MSI as an administrator will require it to be launched via command line with administrator access or to generate a bootstrapper (.exe) that is either told to run as administrator by the user or configured to launch with administrator access.

Some of the blanks that need to be filled in:

  • All of the missing details to using custom actions in WIX.
  • The exact method of checking if a user's credentials are valid and what their permissions are.

Once you figure out those two things it shouldn't be too difficult to adapt the strategy above to validate any arbitrary user input.

Joel McBeth
  • 1,278
  • 16
  • 21
0

You may need to rephrase the question. The credentials you're talking about need enough privilege to run as a service - they are not used to install the service, as your question implies. The install itself will (or should!) ask for elevation on UAC systems and install the service for you.

The first part of validation is based on calling LogonUser(), something like this is a guide to the API usage.

http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184(v=vs.85).aspx

There's also some discussion here:

How to validate domain credentials?

Community
  • 1
  • 1
PhilDW
  • 20,260
  • 1
  • 18
  • 28