cmd - Exit code "lost" from child process in Windows XP, not in Windows Server 2003 -
edit 3
ok, seems might not installer issue after all. when make simple batch file:
exit /b 12
and call as
cmd /c test.cmd echo %errorlevel%
i "12" on windows server 2003 r2, "0" on xp. thought had tested simple test case many times before apparently not.
so, i've changed tags , title i'm leaving other information here there's lot of useful stuff here not directly related issue.
thoughts?
original below
i have custom action written in vbscript in turn calling windows batch file (the custom action allowing user execute @ install time can run later running batch file - it's convenience). function below:
function mainfunction strcustomactiondata = session.property("customactiondata") strsplit = split(strcustomactiondata, ";") strinstalldir = strsplit(0) strpostcopyaction = strsplit(1) strscriptlocation = strinstalldir & "\migrationmasterprocess.cmd" strfullcommand = """" & strscriptlocation & """ " & strpostcopyaction set objshell = createobject("wscript.shell") dim objexec set objexec = objshell.exec(strfullcommand) intreturncode = objexec.exitcode set objexec = nothing set objshell = nothing writemessage "return value: " & intreturncode ' cf. http://msdn.microsoft.com/en-us/library/windows/desktop/aa371254(v=vs.85).aspx if (intreturncode = 0) mainfunction = 1 else mainfunction = 3 end if end function
when run same kind of code outside of custom action, , batch file returns error code (via exit /b), return value correctly captured in intreturncode. however, custom action, exit code seems "lost" - 0 (i can see in installer log writemessage call). doesn't matter if use exec or run on shell, still 0. script writes own return code out before returning (i can see in stdout stream exec) know it's not 0. need return code report error installer.
ideas?
for record windows installer 3.0 on windows xp sp3. installer in wise don't have wix snippet or include it, function being called.
also stripped - i've left out comments , other calls writemessage function. , yes psuedo-hungarian evil blah blah blah.
edit: here c version of code. it's giving same exact issue:
#include <windows.h> #include <msi.h> #include <msiquery.h> #include <stdio.h> #include <stdlib.h> #include "launchchildprocess.h" bool apientry dllmain( handle hmodule, dword ul_reason_for_call, lpvoid lpreserved ) { return true; } uint __stdcall runmigrationaction(msihandle hmodule) { uint uistat; dword dwpropertysize = max_path * 2; tchar szvaluebuf[max_path * 2]; // arbitrary know strings won't near long tchar *szinstalldir, *szpostcopyaction; tchar *sznexttoken; tchar szscriptlocation[max_path * 2]; tchar szparameters[max_path * 2]; int ireturnvalue; logtaggedstring(hmodule, text("action status"), text("starting")); uistat = msigetproperty(hmodule, text("customactiondata"), szvaluebuf, &dwpropertysize); if (error_success != uistat) { logtaggedstring(hmodule, text("startup"), text("failed custom action data")); return error_install_failure; } logtaggedstring(hmodule, text("properties given"), szvaluebuf); logtaggedinteger(hmodule, text("property length"), dwpropertysize); if (0 == dwpropertysize) { return error_install_failure; } logtaggedstring(hmodule, text("properties given"), szvaluebuf); szinstalldir = wcstok_s(szvaluebuf, text(";"), &sznexttoken); szpostcopyaction = wcstok_s(null, text(";"), &sznexttoken); logtaggedstring(hmodule, text("install dir"), szinstalldir); logtaggedstring(hmodule, text("post-copy action"), szpostcopyaction); wcscpy_s(szscriptlocation, max_path * 2, szinstalldir); wcscat_s(szscriptlocation, max_path * 2, text("\\migrationmasterprocess.cmd")); logtaggedstring(hmodule, text("script location"), szscriptlocation); wcscpy_s(szparameters, max_path * 2, text(" /c ")); wcscat_s(szparameters, max_path * 2, szscriptlocation); wcscat_s(szparameters, max_path * 2, text(" ")); wcscat_s(szparameters, max_path * 2, szpostcopyaction); logtaggedstring(hmodule, text("parameters cmd.exe"), szparameters); ireturnvalue = executeprocess(text("cmd.exe"), szparameters); logtaggedinteger(hmodule, text("return value command"), ireturnvalue); logtaggedstring(hmodule, text("action status"), text("finished")); return (0 == ireturnvalue) ? error_success : error_install_failure; } void logtaggedinteger(msihandle hinstall, tchar* sztag, int ivalue) { tchar szvalue[15]; _itow_s(ivalue, szvalue, 15, 10); logtaggedstring(hinstall, sztag, szvalue); } void logtaggedstring(msihandle hinstall, tchar* sztag, tchar* szmessage) { msihandle hrecord; uint uistat; //tchar szfullmessage[4096]; //wcscpy_s(szfullmessage, 4096, text("--------------- ")); //wcscat_s(szfullmessage, 4096, sztag); //wcscat_s(szfullmessage, 4096, text(": ")); //wcscat_s(szfullmessage, 4096, szmessage); hrecord = msicreaterecord(3); uistat = msirecordsetstring(hrecord, 0, text("--------- [1]: [2]")); uistat = msirecordsetstring(hrecord, 1, sztag); uistat = msirecordsetstring(hrecord, 2, szmessage); uistat = msiprocessmessage(hinstall, installmessage(installmessage_info), hrecord); msiclosehandle(hrecord); return; } int msimessagebox(msihandle hinstall, tchar* szstring, dword dwdlgflags) { pmsihandle newhandle = ::msicreaterecord(2); msirecordsetstring(newhandle, 0, szstring); return (msiprocessmessage(hinstall, installmessage(installmessage_user + dwdlgflags), newhandle)); } dword executeprocess(tchar *szprocess, tchar *szparams) { int imycounter = 0, ipos = 0; dword dwreturnval = 0; tchar *stempstr = l""; /* createprocessw can modify parameters allocate needed memory */ wchar_t * pwszparam = new wchar_t[wcslen(szparams) + 1]; if (null == pwszparam) { return 1; } wcscpy_s(pwszparam, wcslen(szparams) + 1, szparams); /* createprocess api initialization */ startupinfow sistartupinfo; process_information piprocessinfo; memset(&sistartupinfo, 0, sizeof(sistartupinfo)); memset(&piprocessinfo, 0, sizeof(piprocessinfo)); sistartupinfo.cb = sizeof(sistartupinfo); if (createprocessw(const_cast<lpcwstr>(szprocess), pwszparam, 0, 0, false, create_default_error_mode, 0, 0, &sistartupinfo, &piprocessinfo) != false) { /* watch process. */ waitforsingleobject(piprocessinfo.hprocess, infinite); if (!getexitcodeprocess(piprocessinfo.hprocess, &dwreturnval)) { dwreturnval = getlasterror(); } } else { /* createprocess failed */ dwreturnval = getlasterror(); } /* free memory */ free(pwszparam); pwszparam = null; /* release handles */ closehandle(piprocessinfo.hprocess); closehandle(piprocessinfo.hthread); return dwreturnval; }
when run on windows server 2003 r2 visual studio 2008 box, error code expected:
--------- return value command: 5023
when run on windows xp test box, 0, though should error:
--------- return value command: 0
both machines have windows installer 3.1. xp 3.01.4001.5512, 2003 r2 3.01.4000.3959.
so it's acting different between boxes although have no idea what.
edit 2
the exact table row action, generated wise windows installer tool, is:
"runmigrationactionca","1537","calllaunchchildprocess","runmigrationaction","0"
to test immediate flag added 0x800 type column , no change seen in end behavior.
to clear - works fine on 2003 r2 machine. machine not joined domain, xp machine is. there in group policy cause behavior? (grasping @ straws @ point.)
wscript objects don't work inside custom actions please reader more here. use dll custom action. here step step tutorial.
Comments
Post a Comment