locked
Closing a Terminal Services session remotely RRS feed

  • Question

  • I've got a c# Windows Service that needs to locate all the user processes on a server that have been idle for >30 mins and zap them. Identification was simple as I used Cassia to do all the work for me. The only problem is, I have no idea how to close down a process once identified, Cassia doesn't seem to have any methods to do this. How do I do this in standard c#?
    Monday, April 27, 2009 1:57 PM

Answers

  • I believe logging the user off does kill any user mode processes started under that session.

    However, I'm not sure that's what Rob was wanting to do... he was asking how to kill any processes idle more than 30 minutes.  A user could be active in a session, and have a copy of some program sitting minimized for 2 hours.  Logging them off might be nasty in that case... 

    Either way, there are two good options for him at this point to try.  :)
    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by Harry Zhu Tuesday, May 5, 2009 10:55 AM
    Tuesday, April 28, 2009 6:10 PM

All replies

  • Once you know the process ID, you can use:

    Process process = System.Diagnostics.Process.GetProcessById(procID);
    process.CloseMainWindow(); // Nice way

    // or
    process.Kill(); // Bad - hard terminate the process



    Reed Copsey, Jr. - http://reedcopsey.com
    • Edited by Reed Copsey, JrMVP Monday, April 27, 2009 4:40 PM Fixed message to CloseMainWindow - oops
    Monday, April 27, 2009 4:17 PM
  • Not quite (Process.Close will not close the process).

    You can request a process to close by calling Process.CloseMainWindow. This sends a window message to the process asking it to exit. Process.Kill is the only way to force a process to exit.

    If you're talking terminal services, use WTSLogoffSession instead.

           -Steve
    Monday, April 27, 2009 4:31 PM
  • Thanks Stephan,

    You're absolutely correct - I accidentally forgot about CloseMainWindow() :)  I edited my original to fix.
    Reed Copsey, Jr. - http://reedcopsey.com
    Monday, April 27, 2009 4:41 PM
  • As I'm using Terminal Services, I tried WTSLogoffSession, which seems to do nothing at all...

    I was running it as my user, which has rights to do all the disconnecting (I do it manually all the time).

    What am I missing?
    Tuesday, April 28, 2009 12:38 PM
  • WTSLogoffSession will try to logoff a terminal services session - it's potentially useful, but different than trying to shutdown a process.

    If you're just trying to kill the process as found by Cassia, I'd do:

    Process process = System.Diagnostics.Process.GetProcessById(procID);
    process.CloseMainWindow();

    Once you've done this, give it a bit to close- this sends a close message to the process main window, and "requests" that it close, but doesn't kill it.  It's a much less abusive way of killing the process.

    If it still doesn't close, you should be able to do process.Kill() and force it to shutdown.

    If you just want to logoff people, the WTSLogoffSession should work.  Have you checked the return codes and parameters you're feeding it?

    Reed Copsey, Jr. - http://reedcopsey.com
    Tuesday, April 28, 2009 4:11 PM
  • I did assume that logging off a TS user would stop their processes (assuming it succeeded). I could be wrong about this, though; the only time I've written software to end a TS session was actually checking (enforcing a policy) at the time the session was established, so they didn't have other programs running yet.

    I'll take a quick look at my old TS code when I get a chance, but it's possible that Process may be the best choice.

          -Steve
    Coming soon: an actual signature! Watch this space for details!
    Tuesday, April 28, 2009 6:08 PM
  • I believe logging the user off does kill any user mode processes started under that session.

    However, I'm not sure that's what Rob was wanting to do... he was asking how to kill any processes idle more than 30 minutes.  A user could be active in a session, and have a copy of some program sitting minimized for 2 hours.  Logging them off might be nasty in that case... 

    Either way, there are two good options for him at this point to try.  :)
    Reed Copsey, Jr. - http://reedcopsey.com
    • Marked as answer by Harry Zhu Tuesday, May 5, 2009 10:55 AM
    Tuesday, April 28, 2009 6:10 PM
  • Rob,

    It looks like you posted this question just a couple of days before Cassia 2.0 was released. Version 2.0 added support for a number of operations, including logging off sessions and killing processes.

    Logging off sessions idle for 30 minutes or more could be done with the following code:
    ITerminalServicesManager manager = new TerminalServicesManager();
    using (ITerminalServer server = manager.GetRemoteServer("your-server-name"))
    {
    	server.Open();
    	foreach (ITerminalServicesSession session in server.GetSessions())
    	{
    		if (session.ConnectionState == ConnectionState.Active && session.IdleTime >= TimeSpan.FromMinutes(30))
    		{
    			session.Logoff();
    		}
    	}
    }
    
    
    Reed suggested using the Kill or CloseMainWindow methods of System.Diagnostics.Process; however, these methods are not supported for remote processes (they'll throw a NotSupportedException). Killing processes running in idle sessions could be accomplished with the following:
    ITerminalServicesManager manager = new TerminalServicesManager();
    using (ITerminalServer server = manager.GetRemoteServer("your-server-name"))
    {
    	server.Open();
    	foreach (ITerminalServicesSession session in server.GetSessions())
    	{
    		if (session.ConnectionState == ConnectionState.Active && session.IdleTime >= TimeSpan.FromMinutes(30))
    		{
    			foreach (ITerminalServicesProcess process in session.GetProcesses())
    			{
    				try
    				{
    					process.Kill();
    				}
    				catch (Win32Exception)
    				{
    					// You'll get an access denied error for certain processes, like the System process.
    				}
    			}
    		}
    	}
    }
    Dan
    Wednesday, May 27, 2009 10:45 PM