Question

I have a CustomAction that checks a license key against a cloud database. This uses an async method to wait for the response before continuing.

When I test the methods below outside of the CustomAction, it works fine; sends request, task waits for completion, returns results.

When I use the same methods in the CustomAction, I can see (using debug) that as soon as the t.Wait() line is hit the Dialog instantly goes to the "ended prematurely" page.

Is there something I am missing or are tasks - specifically waiting for async tasks - not possible in CustomActions?

[CustomAction]
public static ActionResult LicenseCheck(Session session)
{
#if DEBUG
    System.Diagnostics.Debugger.Launch();
#endif
    // Default Values
    ReturnActionResult = ActionResult.Success;
    session["PIDACCEPTED"] = "0";

    string key = session["PIDKEY"].Replace("-", "");

    IEnumerable<ParseObject> results = ParseCustom.StartQueryRequest("Store", "Key", key);

    // Not making it past this point

...

public static class ParseCustom
{

    public static IEnumerable<ParseObject> StartQueryRequest(string className, string key, string value)
    {
        Task<IEnumerable<ParseObject>> t = DoWorkAsync(className, key, value);
        t.Wait(); // Hitting this line in CustomAction causes instant Failure, doesnt get past this line
        return t.Result;
    }

    private static Task<IEnumerable<ParseObject>> DoWorkAsync(string className, string key, string value)
    {
        return Task<IEnumerable<ParseObject>>.Factory.StartNew(() =>
        {
            var x = AsyncTaskHelper(className, key, value);
            return x.Result;
        });
    }

    private static Task<IEnumerable<ParseObject>> AsyncTaskHelper(string className, string key, string value)
    {
        return Task.Run(async () =>
        {
            IEnumerable<ParseObject> ParseResults = await AccessParseAsync(className, key, value);
            return ParseResults;
        });
    }

    private static async Task<IEnumerable<ParseObject>> AccessParseAsync(string className, string key, string value)
    {
        ParseQuery<ParseObject> query = ParseObject.GetQuery(className).WhereEqualTo(key, value);
        IEnumerable<ParseObject> parseResults = await query.FindAsync();
        return parseResults;
    }
}

TempLog:

MSI (c) (0C:BC) [09:24:13:569]: Doing action: LicenseCheckAction
Action 9:24:13: LicenseCheckAction. 
Action start 9:24:13: LicenseCheckAction.
MSI (c) (0C:04) [09:24:13:591]: Invoking remote custom action. DLL: C:\Users\dirt\AppData\Local\Temp\MSIFF5.tmp, Entrypoint: LicenseCheck
MSI (c) (0C:F0) [09:24:13:592]: Cloaking enabled.
MSI (c) (0C:F0) [09:24:13:592]: Attempting to enable all disabled privileges before calling Install on Server
MSI (c) (0C:F0) [09:24:13:592]: Connected to service for CA interface.
MSI (c) (0C!A4) [09:24:16:819]: PROPERTY CHANGE: Adding PIDACCEPTED property. Its value is '0'.
Action ended 9:24:16: LicenseCheckAction. Return value 3.
DEBUG: Error 2896:  Executing action LicenseCheckAction 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: LicenseCheckAction, , 
Action ended 9:24:16: WelcomeDlg. Return value 3.
MSI (c) (0C:BC) [09:24:16:873]: Doing action: FatalError
Action 9:24:16: FatalError. 
Action start 9:24:16: FatalError.
Action 9:24:16: FatalError. Dialog created
Action ended 9:32:02: FatalError. Return value 2.
Action ended 9:32:02: INSTALL. Return value 3.
MSI (c) (0C:BC) [09:32:02:489]: Destroying RemoteAPI object.
MSI (c) (0C:F0) [09:32:02:489]: Custom Action Manager thread ending.
Was it helpful?

Solution

This ended up having nothing to do with WiX, the issue was in the CustomAction code itself and not initializing something properly.

I was able to figure this out thanks to @Stephan Cleary reminder to put the code in try catch block which gave me the exception details I was missing.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top