0
votes

I want to store a file from Binary table to temp location in Custom Action. I have two Custom actions, first is 'immediate', another one is 'deferred'.

When during run of the 'immediate' custom action I invoke Microsoft.Deployment.WindowsInstaller.Record.GetStream method, it does not save the file.

[CustomAction]
public static ActionResult ImmediateAction(Session session)
{
    try
    {
        View view = db.OpenView("SELECT Name, Data FROM Binary");
        view.Execute();

        foreach (Record row in view)
        {
            row.GetStream("Data", Path.Combine(Environment.GetEnvironmentVariable("temp"), row.GetString("Name"));
        }

        return ActionResult.Success;
    }
    catch (Exception ex)
    {
        session.Log(ex.Message);
        return ActionResult.Failure;
    }
    finally
    {
        db.Close();
    }
}

The Custom Action works without errors, but the file does not get being created.

Update:

In the InstallExecuteSequence the Custom Action described like:

    <InstallExecuteSequence>
       <Custom Action="ImmediateAction"
             Before="DeferredAction">
          NOT Installed
        </Custom>

        <Custom Action="DeferredAction"
             After="InstallInitialize">
          NOT Installed
        </Custom>
   </InstallExecuteSequence>

From the 'deferred' custom action I am not able to get the db view, which is expected. And, I am not able to pass the File's binary data from 'immediate' to 'deferred' Custom Action since System.IO.Stream class does not support serialization.

1
Are you aware the items added to the project as type content copy=true willl be automatically extracted and cleaned up to the current directory in temp during the install?Christopher Painter
It's a good point, but I need to eliminate end user related errors. Good to be sure that nothing breaks when people who use your extension forget to change the content type of a file.Alex
I've done it in VBscript a while back here: alkanesolutions.co.uk/2013/08/01/… However, by looking at your code and having NEVER user Wix myself, I'd suggest: What is "db" in db.openview? Does it not need to be session.database.openview instead (i.e the database of the session object that you pass in?)? Also here's some code I cobbled up - worth a try but no idea if it works or not:Captain_Planet
tempFile = Path.GetTempFileName(); using (View binaryView = session.Database.OpenView("SELECT Name, Data FROM Binary")) { binaryView.Execute(); using (Record binaryRec = binaryView.Fetch()) { binaryRec.GetStream(2, tempFile); } }Captain_Planet
@Captain_Planet, well .Fetch() helped me. Please answer the question, so I can forward reputation to you.Alex

1 Answers

0
votes

Excellent Alex. Thanks for the feedback. The solution to the original question was to call the Fetch() method of the View() object: https://msdn.microsoft.com/en-us/library/windows/desktop/aa372509(v=vs.85).aspx

tempFile = Path.GetTempFileName(); 
using (View binaryView = session.Database.OpenView("SELECT Name, Data FROM Binary")) 
{ 
    binaryView.Execute(); 
    using (Record binaryRec = binaryView.Fetch()) 
    { 
        binaryRec.GetStream(2, tempFile); 
    } 
}