0
votes

I have a custom action to check the SQL Connection. Now, it should work with a Control Button, but that's not working.

Custom action works nicely without the button: Here the wxs-File:

<?xml version="1.0" encoding="UTF-8"?>

<Property Id="SERVERNAME" Value="MSSQL2008R2" />
<Property Id="DATABASENAME" Value="MyDatabase" />
<Property Id="USERNAME" Value="admin" />
<Property Id="PASSWORD" Value="mypassword" />

<Binary Id="CA_SQLTestDLL" SourceFile="$(var.CA_SQLConnectionTest.TargetDir)CA_SQLConnectionTest.CA.dll" />
<CustomAction Id="SQL_Test"
              BinaryKey="CA_SQLTestDLL"
              DllEntry="ConnectionTest"
              Execute="deferred"
              Return="check" />
<SetProperty Id="SQL_Test" Value="SERVERNAME=[SERVERNAME];DATABASENAME=[DATABASENAME];USERNAME=[USERNAME];PASSWORD=[PASSWORD]" Sequence="execute" Before="SQL_Test" />

<InstallExecuteSequence>
  <Custom Action="SQL_Test" After="InstallInitialize" />
</InstallExecuteSequence>


<UI>
  <Dialog Id="SQLServerConnectionTestDlg" Width="370" Height="270" Title="SQL Server connection test">
    <Control Id="Next" Type="PushButton" X="236" Y="243" Width="56" Height="17" Default="yes" Text="!(loc.WixUINext)" />
    <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>

Here is my CustomAction class:

Imports System.Data
Imports System.Data.SqlClient
Public Class CustomActions
<CustomAction()> _
Public Shared Function ConnectionTest(ByVal session As Session) As ActionResult
session.Log("############## Begin CUSTOMACTION ##############")
Dim userName As String
Dim password As String
Dim serverName As String
Dim dataBase As String

serverName = session.CustomActionData("SERVERNAME")
dataBase = session.CustomActionData("DATABASENAME")
userName = session.CustomActionData("USERNAME")
password = session.CustomActionData("PASSWORD")

Dim SqlConn As New SqlConnection
Dim SqlConnStr As String = "Data Source=" + serverName + ";Database=" + dataBase + ";Persist Security Info=True;User ID=" + userName + ";Password=" + password

If SqlConn.State = ConnectionState.Closed Then
  SqlConn.ConnectionString = SqlConnStr
  Try
    SqlConn.Open()
  Catch ex As Exception
    Return ActionResult.Failure
  End Try
End If
session.Log("### SUCCESSFULL ###")
Return ActionResult.Success
  End Function

End Class

install.log :

Calling custom action CA_SQLConnectionTest!CA_SQLConnectionTest.CustomActions.ConnectionTest
############## Begin CUSTOMACTION ##############
### SUCCESSFULL ###

Now, I'd like to start the custom action with a button. So i have to change Execute="deferred" to Execute="immediate" and add a button:

        <Control Id="TestConn" Type="PushButton" X="265" Y="205" Width="70" Height="18" Text="&amp;Test Connection">
      <Publish Event="DoAction" Value="SQL_Test">1</Publish>
      <Publish Property="ERRORMSG" Value="ConnectionTest">ACCEPTED = "1"</Publish>
      <Publish Event="SpawnDialog" Value="InvalidDBConnDlg">ACCEPTED = "0"</Publish>
    </Control>

      <Dialog Id="InvalidDBConnDlg" Width="260" Height="120" Title="MyTester">
    <Control Id="OK" Type="PushButton" X="102" Y="90" Width="56" Height="17" Default="yes" Cancel="yes" Text="OK">
      <Publish Event="EndDialog" Value="Exit" />
    </Control>
    <Control Id="Text" Type="Text" X="48" Y="22" Width="194" Height="60" Text="FAILED" />
    <Control Id="Icon" Type="Icon" X="15" Y="15" Width="24" Height="24" ToolTip="Information icon" FixedSize="yes" IconSize="32" Text="WixUI_Ico_Info" />
  </Dialog>

Now, when i push the button will the setup cancled and i have a fatal error in the log-File:

Action 16:43:20: SQL_Test. 
Action start 16:43:20: SQL_Test.
MSI (c) (5C:5C) [16:43:20:236]: Invoking remote custom action. DLL: C:\Users\LOC~1.CRE\AppData\Local\Temp\MSIC08C.tmp, Entrypoint: ConnectionTest
Action ended 16:43:20: SQL_Test. Return value 3.
MSI (c) (5C:20) [16:43:20:404]: Note: 1: 2205 2:  3: Error 
MSI (c) (5C:20) [16:43:20:404]: Note: 1: 2228 2:  3: Error 4: SELECT `Message` FROM `Error` WHERE `Error` = 2896 
DEBUG: Error 2896:  Executing action SQL_Test failed.
The installer has encountered an unexpected error installing this package. This may indicate a problem with this package. The error code is 2896. The arguments are: SQL_Test, , 
Action ended 16:43:20: WelcomeDlg. Return value 3.
MSI (c) (5C:54) [16:43:20:405]: Doing action: FatalError
MSI (c) (5C:54) [16:43:20:405]: Note: 1: 2205 2:  3: ActionText 
Action 16:43:20: FatalError. 
Action start 16:43:20: FatalError.
Action 16:43:20: FatalError. Dialog created
Action ended 16:43:23: FatalError. Return value 2.
Action ended 16:43:23: INSTALL. Return value 3.
MSI (c) (5C:54) [16:43:23:488]: Destroying RemoteAPI object.
MSI (c) (5C:50) [16:43:23:488]: Custom Action Manager thread ending

Config useLegacyV2RuntimeActivationPolicy is "true"

I use WIX3.10 in Visual Studio 2013

I am not sure what I am doing wrong. But i think it's a problem with the InstallExecuteSequence.

I hope someone can help me, thanks

3

3 Answers

0
votes

Well immediate is the correct thing to do, because you can't have deferred custom actions in the UI sequence (so it can't be a problem with the execute sequence as you suspect).

Beyond that, if the code starts and it fails then it's a coding/environmental issue. You should just put message box calls in your code while you're in this debugging stage, check that you have the values, and certainly do more that just trhow away any exception with that try/catch! You're asking what the error might be at the same time that you discard it and return a failure result.

0
votes

Thanks, you have right, it's not a problem with the execute sequence.

I've narrowed down the problem. When I don't use CustomActionData then works the custom action

userName = session.CustomActionData("USERNAME")
password = session.CustomActionData("PASSWORD")
...

Why I can't not transfer values?

Update:

The command doesnt' work here:

session.CustomActionData("USERNAME")

With the follow command works fine:

session("USERNAME")
0
votes

CustomActionData cannot be accessed with immediate custom action.

But you can directly access properties using sessions.

try this

  userName = session["USERNAME"];
  password = session["PASSWORD"];