cancel
Showing results for 
Search instead for 
Did you mean: 
Read only

xp_cmdshell with dbsvc

Baron
Participant
2,469

I have difficulty using the xp_cmdshell to start an .exe file or a .batch file, which starts an exe, which in turns is a desktop application connecting to the database. so, from dbisql I write xp_cmdshell 'C:\\temp\\startreports.bat' Actually I have this problem only when I start the DBSRV10 from within a service (dbsvc).

Our startreports.exe is on environment and registry dependant, so that I start the service with a specific user (which has an appropriate profile for the exe) so it looks something like:

dbsvc -a WIN_USER -p WIN_PWD -s Manual -sd "SOME_DESCRIPTION" -t network -w SVC_NAME "C:\\Program Files (x86)\\SQL Anywhere 10\\win32\\dbsrv10.exe" -xs http(port=8888) -n SRV_NAME -c 768M "C:\\TEST\\DB1.db"

I dont see any other possibility to change the service (could the -i change something) (-i = allow service to interact with desktop), but I had always difficulty to add this option to the dbsvc!!

Accepted Solutions (0)

Answers (2)

Answers (2)

VolkerBarth
Contributor

So far we have tried to explain the problem. If you really need a SQL Anywhere server running as a service to display a GUI, you will need some kind of "man in the middle" in my understanding. That is because a service uses an invisible "window station" whereas a visible GUI must be run within the one and only "interactive window station".

Let's use a very silly example: Say, your SQL Anywhere server service would do regular backups of its database but want to ask the user to confirm that. Therefore it would need to display a simple message box awaiting a "yes" or "no" answer.

  1. AFAIK, you would need a process running in the session of the logged-in interactive user (say, automatically started via "AutoStart"). That process would be silently waiting for an event triggered by the database service. One means would be to check for modified database contents but I would prefer a basic OS IPC facility like a named Win32 event. So that "waiter" would just use one of the Win32 wait functions to wait on the event to be set.

  2. When the database server wants to ask for a backup, it would "do something" to signal that event. That's (rather easily) doable via an external C function that maintains and sets the according event. (FWIW, that's something we use ourselves to synchronize processes - for different reasons, apparently...). So some database code calls that external function which in turn sets the event. (Alternatively, you could use xp_cmdshell to call an application that sets such an event.)

  3. Now the "waiter" process in the interactive session is notified that the event is set and therefore displays the GUI, either as part of its own process or by starting a GUI app. As the "waiter" runs within the interactive window station, its output and that of processes it has started are visible for the logged-in user. So a message box is displayed, and the user chooses "yes" or "no".

  4. In this sample, the database service needs to get the GUI's result. So there must be another IPC in the opposite direction: The database code would need to wait for the response, either by waiting for some database modification (say, the GUI would change a database row based on the user's input) and/or by another event set by the "waiter" that the GUI has closed. As a consequence, the database server would now do a backup or skip that task. (As stated, it's a silly sample...:)).

  5. The waiter would reset the first event and would return to its "waitning" state and wait until the database server sets that event again.


I have not used code like that to make a SQL Anywhere service display a GUI, however we have used IPC to synchronize tasks within SQL Anywhere with other processes for years, and that has worked fine.

Baron
Participant

an interesting alternative is the SYSTEM statement, which can start an GUI from within DBISQL even if the DB is started as Service. The drawback is that this statement can only be used within dbisql, and can not be called within a procedure.

Breck_Carter
Participant
0 Kudos

Have you tried the Windows START command from a call to xp_cmdshell?

VolkerBarth
Contributor
0 Kudos

The question is what process runs the xp_cmdshell command. If the database server running as a service does start that command, you are pretty much still in the invisible window station and cannot show a GUI to the interactive user. That's my limited understanding, of course...

Baron
Participant
0 Kudos

Yes I tried, it does the same thing, except that it starts the program in a new dos-window

Breck_Carter
Participant
0 Kudos

So you are saying that you CAN run START from xp_cmdshell in a procedure running in a service, AND get a GUI showing?

FWIW START has a lot of options / capabilities, some of them [cough] magically confusing 🙂

Baron
Participant
0 Kudos

No, I didnt say that. I said the SYSTEM statement can do that (start GUI application even if the DB is started as service).

Baron
Participant
0 Kudos

I know that it took long time to discuss this subject, and I understand that it goes on the OS to allow or not allow desktop interaction for a service. I got the answer thankfully since last week, and with my new answer wanted just to mention the SYSTEM statement (which was for me new)

VolkerBarth
Contributor
0 Kudos

wanted just to mention the SYSTEM statement (which was for me new)

FWIW, I wasn't aware of that command either, so thanks for that:)

Breck_Carter
Participant
0 Kudos

New to me too, and embarrassing... because it dates back to V5.5 at least:

 User's Guide 
   Part VI. SQL Anywhere Reference
     Chapter 43. Watcom-SQL Statements
      SYSTEM statement
Function
To execute an operating system command from within ISQL.
Syntax
SYSTEM [ operating-system-command ]
Usage
ISQL (DOS and QNX only).