Run app in new Windows "session"

Started by stevengraff, January 31, 2014, 09:54:14 AM

Previous topic - Next topic

stevengraff

When I look at the Task Manager of my WinXP machine, everything's running in session 0. I assume anything > 0 would be something like an RDP session, yes? Is there any way to run an application in a specific session, even creating that session first?

I'm trying to have multiple DDE conversations with an app, and think this could be the way to go, running it two or three times, each in its own session.

Thanks much,
SG

Deana

Sorry, not my area of expertise. There are no real built in functions in WinBatch to handle this.

However if you have the patience and time, you could feasibly call the necessary Windows APIs. Here is a good resource to get started learning about Window Stations and Desktops:http://msdn.microsoft.com/en-us/library/windows/desktop/ms687105(v=vs.85).aspx

I found some old undebugged code in the tech database that could help get you started if you dare:
http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+WinBatch/Samples~from~Users+DesktopHopper.txt
Deana F.
Technical Support
Wilson WindowWare Inc.

Deana

Check out this interesting KB article: http://support.microsoft.com/KB/105659

It states:

QuoteYou can run multiple instances of the same application under Microsoft Windows. When you communicate with an application using DDE, it may be important to be able to identify which instance of an application should respond to your DDE commands.

You can initiate a DDE conversation with a specific instance of an application by appending the application's Task ID number to the application name argument in the DDE initiate command.

I personally have never tried this, but it might be something you can persue.
Deana F.
Technical Support
Wilson WindowWare Inc.

td

Quote from: stevengraff on January 31, 2014, 09:54:14 AM
When I look at the Task Manager of my WinXP machine, everything's running in session 0. I assume anything > 0 would be something like an RDP session, yes? Is there any way to run an application in a specific session, even creating that session first?

I'm trying to have multiple DDE conversations with an app, and think this could be the way to go, running it two or three times, each in its own session.

Thanks much,
SG

If I remember correctly, DDE communication across login sessions on XP requires having the netDDE service installed and running.   However, the service is not usually installed as part of the system image but is provided by MSFT on the XP installation disk someplace.  As of Window Vista netDDE is not supported.

However, the above is based on a few vague memories so I cannot be certain of the accuracy.

Of course, the netDDE service is not required to communication between processes running in the same session.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stevengraff

Thanks all.

I've got a half-way decent partial solution... only hitch is shutting it down (elegantly).

Re-setting the scenario, I've got commercial program ComProg.exe, and I want to have two DDE conversations with it, with WBprogA and WBprogB. When everything's on the desktop, it's not a problem. But getting it to work as a service was the challenge. ComProg.exe has a native switch that makes it run as a service. But then I could only get one DDE conversation operational with it.

Solution: I created another WB script, WBprogX, and compiled it to run as a service. WBprogX uses the Run command to launch ComProg, WBprogA, and WBprogB. WBprogX has then served its purpose, and it exits, but the the other three programs live happily on, talking their dde-speak with each other just fine.

The problem I face now is an "elegant" shutdown of the three programs, i.e. not End Process from the Task Manager, and not machine Shutdown.

What if... instead of using the Run command to spawn the three apps, I used RunShell with the @GetProcID parameter. Now I'd have a handle on the specific programs I've launched.

But still, how would I kill them?

What if... instead of letting WBprogX exit, I have it stick around? Is there a way to have WBprogX "understand" it is being "stopped" (using Service Control Manager) and by some kind of inference, kill the other three apps? That seems like the most "elegant," but can it be done? Is there any life left in WBprogX once the stop command is issued?

I guess I could write the three ProcIDs to a temp file, and then run yet another script that would pick up the temp file, and stop the ProcIDs contained therein. But then the user would be using quite the non-standard method for exiting from programs, which I don't much like the idea of.

Or, maybe another service, progXwatch.exs,  "watches" WBprogX and, when it sees that WBprogX is no more, progXwatch swings into action and kills the three original programs. progXwatch needs to know their ProcIDs, so I guess it's back to picking them up from a temp file. Or maybe they're passed in as parameters.

Could be I'm overthinking this, and there's a simple and clever solution?

Deana

You might look into having the MyProgX ( WinBatch script) run as a window service. This service can monitor the current service state. Here is a tutorial that should help get you started: http://techsupt.winbatch.com/webcgi/webbatch.exe?techsupt/tsleft.web+Tutorials+Service~Scripts.txt
Deana F.
Technical Support
Wilson WindowWare Inc.

stevengraff

Yes, that is what I was already doing, sorry not to be more clear.

My solution was to launch a 4th program from WBprogX whose job it is to monitor WBprogX, and close all the other programs in the event that WBprogX goes away.

It works!

Thanks for the ref, though, I will peruse it.

stevengraff

I changed my strategy after studying the tutorial... There's no need for another script to monitor the service, I'm able to kill the other apps by running a few commands following receipt of the "close" signal.

ChuckC

The O.P. mentions that WinXP is being used, and is very specifically making use of native NT services in [Terminal Services] Session #0 as part of his solution.  It wasn't clear whether or not any of the WinBatch scripts or the "ComPrg" ever need to interact with the desktop in any way, but if they do, the following supplementary reading material should be examined if the O.P. ever expects to run this code on Vista/Win2K8 or newer.

http://msdn.microsoft.com/en-us/library/windows/hardware/gg463353.aspx

On that web page is another link to a Word document that has a thorough discussion of the issues associated with native NT services needing to interact with the desktop, or vice-versa, and what the impact is on such programs when Session #0 Isolation comes into play as of Vista/Win2K8 & newer.

stevengraff

Thanks for that Chuck. I'm not entirely clear on the concept of what MS considers to be "a service" vs. "an application running as a service." I do see that the .exs file runs in session 0 though on my Server '08 box.

ChuckC

Quote from: stevengraff on February 04, 2014, 05:11:07 AM
Thanks for that Chuck. I'm not entirely clear on the concept of what MS considers to be "a service" vs. "an application running as a service." I do see that the .exs file runs in session 0 though on my Server '08 box.

All native NT services run in Session #0.  Any WinBatch script that has been compiled to be a .EXS file is run as a native NT service.  All programs that are to be run as a service have to have a service entry defined for them in the Service Control Manager [SCM] so that the Services MMC snap-in can be used to start/stop them.

stevengraff

Question: this discussion allows for the possibility of a user-created service that does not run in the zero session?

td

On XP native services must run in session 0.  On Vista and newer all native services must run in session 0 but all user logon sessions must run in other  sessions.
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

stevengraff

Is there such a thing as a "non-native" service?

ChuckC

Quote from: stevengraff on February 04, 2014, 03:58:19 PM
Is there such a thing as a "non-native" service?

No, not really.

There are 2 basic ways that a program executes on Windows:

1)  As an application in an interactive user session on the console or via RDP/TS.

2)  As a service logged on in service mode under the control of the Service Control Manager in Session #0.

All other "methods" of running a program ultimately fall under one of those 2 possibilities.  Depending on how the Windows Task Scheduler is configured, it might run a program within your interactive user session, or it might run it as a child process of the portion of the scheduler that runs as a native NT service.


ChuckC

On the subject of a native NT service and interacting with a session other than Session #0:

It is possible for a thread in a process to make a Win32 API function call that allows it to impersonate the access token associated with a user's RDP/TS Session.  In that case, while performing impersonation, the thread's access to resources is counted as if it were part of the user's RDP/TS Session and not part of Session #0.

At this time, there's nothing in WinBatch that would allow you to do this from within a script.

td

Quote from: ChuckC on February 04, 2014, 04:15:20 PM
On the subject of a native NT service and interacting with a session other than Session #0:

It is possible for a thread in a process to make a Win32 API function call that allows it to impersonate the access token associated with a user's RDP/TS Session.  In that case, while performing impersonation, the thread's access to resources is counted as if it were part of the user's RDP/TS Session and not part of Session #0.

At this time, there's nothing in WinBatch that would allow you to do this from within a script.

Are you saying that impersonation alone would address the issues of window station and and desktops that are associated with a session?     
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

Quote from: td on February 04, 2014, 07:50:56 PM
Are you saying that impersonation alone would address the issues of window station and and desktops that are associated with a session?   


Kinda sorta maybe...

The function I was referring to is WTSQueryUserToken(), which is documented as follows:

http://msdn.microsoft.com/en-us/library/windows/desktop/aa383840%28v=vs.85%29.aspx

Impersonating the access token associated with a particular RDP/TS session will get you access to the file system [e.g. roaming profile folders on disk] and the registry hive of that user.

As for the issues related to windowstation & desktop access, it will depend on a couple of factors that are detailed as follows:

http://msdn.microsoft.com/en-us/library/windows/desktop/ms684859%28v=vs.85%29.aspx

Basically, the first time that a process makes a Win32 API function calls that has some sort of dependency on interacting with a windowstation or desktop, an optional creation of windowstation and/or desktop is performed followed a binding operation that permanently connects the process [and all of its threads] to the windowstation.

If you are very careful with how you create the new process and/or how the code is written, you can get it to bind to a windowstation in a different RDP/TS session from that of its parent process.  The WIL function RunWithLogon() makes use of the Win32 API function CreateProcessWithLogonW(), which in turn relies on a native NT service that is currently named "Secondary Logon" ["seclogon"], but has had different names in the past going back to WinXP.  That service, running in session #0, is capable of creating new processes with arbitrary credentials in any RDP/TS session.  You have to start getting into the unofficially documented functions exported from NTDLL.DLL in order to understand how this services really does its work, but start with a look at ZwSetInformationProcess() and the ProcessSessionInformation information class if you want to see how a process can alter its own RDP/TS session # provided that it has the SE_TCB_NAME privilege.

I know it's not a simple straight forward answer to your question, but it's a somewhat murky subject with little in the way of clear, concise and coherent documentation on it.

Given that WinBatch does some things very early on in execution that create at least one hidden window, the windowstation & desktop binding operation is going to be performed before any WIL statements could be executed that would call into a DLL or access and extender function that would manipulate the binding process.  That would pretty much limit the options to what can be achieved using the STARTUPINFO structure that is passed to the various CreateProcess*() functions in the Win32 API.

td

Its an interesting topic and I appreciate your comments.   
"No one who sees a peregrine falcon fly can ever forget the beauty and thrill of that flight."
  - Dr. Tom Cade

ChuckC

Quote from: td on February 05, 2014, 09:17:14 AM
Its an interesting topic and I appreciate your comments.

You are welcome.

Where this becomes of great interest is when you have a native NT service running that uses the HandlerEx() callback for receiving SCM commands & notifications, the service has indicated that it would like to be notified when a RDP/TS session has been created, destroyed, connected or disconnected, and the service's functionality/purpose requires it to interact with the desktop environment or user profile associated with each of those sessions, or it needs to perform work while impersonating the user access token associated with each of those sessions.