ExecDos::Exec /ASYNC and ExecDos::wait - called exe doesn't end upon sucess
I'm building an NSIS installer to install a data warehouse solution based on SQL Server 2005. The installer also launches a stored proc as a data job when the installer completes. Here are the basic steps:
1. Check for MSI 3.1, install if not exists.
2. Check for .NET 2.0, install if not exists.
3. Check for SQL Server 2005, install if not exists.
4. Run SQL scripts to create the data warehouse.
5. If user chooses, obtain job run configuration from them and invoke the procedure as a "post-install" step (i.e. like Run on Complete).
All works fabulous until the last step. My idea was to invoke the job after the main install via calling sqlcmd.exe. Since this job can take upwards of 20 minutes to complete, I attempted to use ExecDos::Exec /NOUNLOAD /ASYNC and kick it off that way. Then I check on the status in .onGUIEnd, and wait if it's not done, effectively allowing the GUI to tear down, yet the installer exe stay in the processes. So I do a ExecDos::wait inside .onGUIEnd to allow it to finish.
THE PROBLEM: sqlcmd suceeds but does not seem to return to the installer - it hangs in processes, but idle. So when I manually terminate it, then ExecDos returns back to the installer, I get a return code of '1' from ExecDos::wait, and then it finishes.
THE CODE:
Function LaunchJob
ExecDos::Exec /NOUNLOAD /ASYNC 'sqlcmd -v DataSource="$JobConfigDataSource" \ User="$JobConfigUserName" \ Password="$JobConfigPassword" \ Catalog="$JobConfigCatalog" \ Schema="$JobConfigSchema" \ Provider="$JobConfigProvider" \
-Q "$JobProcScript" \
-d "$DatabaseName" \
-b \
-S "$ServerName"'
Pop $R7
; NOTE: I tried it here too and commented out in .onGUIEnd and had the same effect.
;MessageBox MB_ICONEXCLAMATION|MB_OK 'onGUIEnd called...'
;
;ExecDos::isdone /NOUNLOAD $R7
;Pop $R1
;
;${If} $R1 == 0
; ; check process exit code
; ExecDos::wait $R7
; Pop $R2
; MessageBox MB_ICONEXCLAMATION|MB_OK 'Returned $R2"'
;${ElseIf} $R1 == -1
; MessageBox MB_ICONEXCLAMATION|MB_OK 'Error "$R1"'
;${EndIf}
;other stuff ...
FunctionEnd
Function .onGUIEnd
MessageBox MB_ICONEXCLAMATION|MB_OK 'onGUIEnd called...'
ExecDos::isdone /NOUNLOAD $R7
Pop $R1
${If} $R1 == 0
; check process exit code
ExecDos::wait $R7
Pop $R2
MessageBox MB_ICONEXCLAMATION|MB_OK 'Returned $R2"'
${ElseIf} $R1 == -1
MessageBox MB_ICONEXCLAMATION|MB_OK 'Error "$R1"'
${EndIf}
FunctionEnd
FACTS:
* Running sqlcmd manually at the command prompt works and closes at it should, because I use the '-Q' switch - which according to sqlcmd documentation will do a execute and exit; this works.
* When I do the same call with nsExec::ExecToStack, it works successfully.
* Even if I run it with ExecDos::Exec /NOUNLOAD /ASYNC "inline" - immediately grabbing the handle and calling wait on it - it still hangs out there and wont return back (see code comments).
I've isolated it down to this, and still cannot find what the problem is. Note though, of course, that sqlcmd does send data to stdout, so I thus get a file back from DosExec with that data - but ONLY if I manually blow away the sqlcmd process after it's completed. Can I have a few sharp eyes assist?
Also, is there source code for this plug-in that I can peek at?
Thanks much in advance,
Timex