A general rule with C++ CAs that I follow:  Put ALL of your local/stack 
variables above the WcaInitialize call.  I run into weird behaviour (crashes, 
access violations, etc.) if I don't.  This is true when running in VS2010 and 
VS2013 compilers.

-----Original Message-----
From: Sarvagya Pant [mailto:sarvagya.p...@gmail.com] 
Sent: March-13-15 1:40 PM
To: General discussion about the WiX toolset.
Subject: [WiX-users] Writing a C++ Custom Action Project

I have written a C# Custom Action that is supposed to get the Values of 
Properties passed to the installer and create some config file. Since the C# 
Custom action was done, my installer depends upon .Net too. I want to avoid 
this dependency, thus I am opting to write the Custom action in C++.

Following is the C# code that I'm trying to convert in C++:

session.Log("Entering WriteFileToDisk");string ipAddress = 
session["IPADDRESS"];string productCode = session["ProductCode"];string 
config_path = "C:\\SomeFolderToInstall\\";string compression = 
session["COMPRESSION"];string ssl = session["SSL"];if 
(string.IsNullOrEmpty(compression)){
      compression = "True"; //default true}if (string.IsNullOrEmpty(ssl)){
      ssl = "False"; //default false}if (string.IsNullOrEmpty(ipAddress)){
      ipAddress = "127.0.0.1";}string temp = @"
{{
      ""logpoint_ip"" : ""{0}"",
      ""compression"" : ""{1}"",
      ""ssl"": ""{2}""
}}";string filePath =
"C:\\SomeFolderToInstall\\lpa.config";System.IO.FileInfo file = new 
System.IO.FileInfo(filePath); file.Directory.Create(); // If the directory 
already exists, this method does 
nothing.System.IO.File.WriteAllText(file.FullName,
config);System.IO.File.WriteAllText(config_path + "productcode.txt", 
productCode); session.Log("Confile file is written"); session.Log("Product Code 
file is written");return ActionResult.Success;

The Visual C++ code is given below:

#include "stdafx.h"


UINT __stdcall WriteFileToDisk(MSIHANDLE hInstall){
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    hr = WcaInitialize(hInstall, "WriteFileToDisk");
    ExitOnFailure(hr, "Failed to initialize");

    LPWSTR ip = NULL;
    hr = WcaGetProperty(L"IPADDRESS",&ip);
    ExitOnFailure(hr, "Failure in IPADDRESS");

    if(ip == L"" || ip == NULL)
    {
        ip = L"127.0.0.1";
    }
    WcaLog(LOGMSG_STANDARD, (PCSTR)ip);
    LPWSTR ssl = NULL;
    hr = WcaGetProperty(L"SSL",&ssl);
    ExitOnFailure(hr, "Failure in SSL");

    if(ssl == L"" || ssl == NULL)
    {
        ssl = L"False";
    }
    LPWSTR comp = NULL;
    hr = WcaGetProperty(L"COMPRESSION",&comp);
    ExitOnFailure(hr, "Failure in COMPRESSION");

    if(comp == L"" || comp == NULL)
    {
        comp = L"True";
    }

    WcaLog(LOGMSG_STANDARD, "Got the Parameters");
    char buffer[150];
    sprintf(buffer, "{\n\"ipaddress\": \"%s\",\n\"ssl\":
\"%s\",\n\"compression\":\"%s\"\n}",ip,ssl,comp);
    WcaLog(LOGMSG_STANDARD, "Config Generated is : ");
    WcaLog(LOGMSG_STANDARD, buffer);

    HANDLE hFile;
    hFile = CreateFile(L"C://LogPointAgent//some_config.config",
         // name of the write
                       GENERIC_WRITE,          // open for writing
                       0,                      // do not share
                       NULL,                   // default security
                       CREATE_NEW,             // create new file only
                       FILE_ATTRIBUTE_NORMAL,  // normal file
                       NULL);

     if (hFile == INVALID_HANDLE_VALUE)
    {
        WcaLog(LOGMSG_STANDARD, "Invalid Handle for Config File");
        ExitFunction();
    }
     BOOL bErrorFlag;
     DWORD dwBytesToWrite = (DWORD)strlen(buffer);
     DWORD dwBytesWritten = 0;
     bErrorFlag = WriteFile(
                    hFile,           // open file handle
                    buffer,      // start of data to write
                    dwBytesToWrite,  // number of bytes to write
                    &dwBytesWritten, // number of bytes that were written
                    NULL);            // no overlapped structure


     if (FALSE == bErrorFlag)
    {
        WcaLog(LOGMSG_STANDARD, "Terminal failure: Unable to write to file.\n");
    }
    else
    {
        if (dwBytesWritten != dwBytesToWrite)
        {
            // This is an error because a synchronous write that results in
            // success (WriteFile returns TRUE) should write all data as
            // requested. This would not necessarily be the case for
            // asynchronous writes.
            WcaLog(LOGMSG_STANDARD, "Error: dwBytesWritten != 
dwBytesToWrite\n");
        }
        else
        {
            WcaLog(LOGMSG_STANDARD, "Wrote Config file Successfully");
        }
    }

      CloseHandle(hFile);LExit:
    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);}

UINT __stdcall DeleteResidue(MSIHANDLE hInstall){
    HRESULT hr = S_OK;
    UINT er = ERROR_SUCCESS;

    hr = WcaInitialize(hInstall, "DeleteResidue");
    ExitOnFailure(hr, "Failed to initialize");
LExit:
    er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    return WcaFinalize(er);}// DllMain - Initialize and cleanup WiX custom 
action utils.extern "C" BOOL WINAPI DllMain(
    __in HINSTANCE hInst,
    __in ULONG ulReason,
    __in LPVOID
    ){
    switch(ulReason)
    {
    case DLL_PROCESS_ATTACH:
        WcaGlobalInitialize(hInst);
        break;

    case DLL_PROCESS_DETACH:
        WcaGlobalFinalize();
        break;
    }

    return TRUE;}

C++ code is successfully compiled. When used in Wix as:

<Binary Id="SetupCA"
SourceFile="..\WixCustomActionCPP\bin\Release\WixCustomActionCPP.dll"/><CustomAction
Id="WRITEFILETODISK" Execute="immediate" BinaryKey="SetupCA"
DllEntry="WriteFileToDisk" /><InstallExecuteSequence>
  <Custom Action="WRITEFILETODISK" Before="InstallFinalize">NOT 
Installed</Custom></InstallExecuteSequence>

When installer is supposed to get installed as msiexec /i installer.msi /l*v 
out.txt IPADDRESS="192.168.2.208", following config should have been created

{"ip":"192.168.2.208","ssl":"False","compression":"True"}

but what it generates is:

{"ipaddress": "1","ssl": "","compression":""}

What is wrong in my C++ code here? Any help would be appreciated. Thanks.

--
*sarvagya*
------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored 
by Intel and developed in partnership with Slashdot Media, is your hub for all 
things parallel software development, from weekly thought leadership blogs to 
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
WiX-users mailing list
WiX-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wix-users

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
_______________________________________________
WiX-users mailing list
WiX-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/wix-users

Reply via email to