Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Reply
Thread Tools Search this Thread Display Modes
Old 14th December 2007, 18:45   #1
inmytime3021
Junior Member
 
Join Date: Dec 2007
Posts: 7
Unhappy 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
inmytime3021 is offline   Reply With Quote
Old 14th December 2007, 18:55   #2
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
You can create a second installer that'd just execute sqlcmd.exe with ExecDos and execute that installer with Exec. This way you won't have to use /ASYNC.

The source code is part of the ZIP available on the Wiki page.

http://nsis.sourceforge.net/ExecDos_plug-in

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 14th December 2007, 19:06   #3
inmytime3021
Junior Member
 
Join Date: Dec 2007
Posts: 7
Unhappy

But wouldn't this installer then be synchronous to the main installer?

I'd rather keep it within a single installer solution for several reasons:

* Less maintenance and more important dependencies.
* I don't want or need any GUI for this last step ... it just needs to quietly run, without hanging up anything, then gracefully exit.

So, what I'm really get at...shouldn't ExecDos return from it once it's completed?! That is, return back via ExecDos::wait, so that I can Pop the return. It doesn't do this. It's like it hangs indefinitely on the ExecDos::wait, never returning me a return code. Why?

Thanks for your suggestion though! I did think of maybe moving my code to the .onGUIEnd, and running the job there SYNCHRONOUSLY via plain old nsExec::ExecToStack. That way, my GUI tears down first, then runs it silently i nthe background, and closes when finished. But, I'd hate to have to refactor my script in this fashion - less readable and not as elegant - yuck!

I want ExecDos::Exec /ASYNC to WORK! It is the solution I am after.

- Timex
inmytime3021 is offline   Reply With Quote
Old 14th December 2007, 19:07   #4
kichik
M.I.A.
[NSIS Dev, Mod]
 
kichik's Avatar
 
Join Date: Oct 2001
Location: Israel
Posts: 11,343
No, it wouldn't be synchronous as you'd use Exec and not ExecWait.

NSIS FAQ | NSIS Home Page | Donate $
"I hear and I forget. I see and I remember. I do and I understand." -- Confucius
kichik is offline   Reply With Quote
Old 14th December 2007, 19:25   #5
inmytime3021
Junior Member
 
Join Date: Dec 2007
Posts: 7
Hmmmm, good point. Tried it and that works. Sometimes it's the simple things, heh. Well, the reason I was so hung up on doing the ExecDos and/or /ASYNC method was because originally I was doing this step during the install step and thus logging the stdout. This way works, but with the sacrifice of rich logging. Also, the command window is open, of course. But, I'll handle all of that! I saw some thread discussing this and thought I remember reading a thing or two about how to handle the command window (e.g. SW_HIDE). Besides, my job does logging in the database.

Thanks kichik! Sometimes four eyes are better than 2 (or one, lol).

- Timex
inmytime3021 is offline   Reply With Quote
Old 15th December 2007, 07:55   #6
Takhir
Major Dude
 
Join Date: Feb 2004
Location: Moscow, Russia
Posts: 1,222
SQL commands execution has a long history on this forum and many people had problems with it . The same situation I see here because simple script using consApp.exe (included to ExecDos pack) works as expected message appears 5 sec after installer close:
code:
!define APP_NAME onguiend
!define DOS_APP consApp.exe

Name "${APP_NAME} Test"
OutFile "${APP_NAME}.exe"

AutoCloseWindow true

!include "MUI.nsh"
!insertmacro MUI_PAGE_INSTFILES
!insertmacro MUI_LANGUAGE "English"


Section "Dummy Section" SecDummy
ExecDos::exec /NOUNLOAD /ASYNC /TIMEOUT=5000 "$EXEDIR\consApp.exe" \
"test_login$\ntest_pwd$\n" "$EXEDIR\stdout.txt"
Pop $0 ; thread handle for 'wait'
SectionEnd

Function .onGUIEnd
ExecDos::wait $0
Pop $0
MessageBox MB_OK "Exit code $0"
FunctionEnd


The only thing I can offer is to add 2 parameters to ExecDos command line, "" for stdin and "$EXEDIR\stdout.txt" for stdout (temp file would be better for release script because of possible RO location).
Takhir is offline   Reply With Quote
Reply
Go Back   Winamp & Shoutcast Forums > Developer Center > NSIS Discussion

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump