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