.comment-link {margin-left:.6em;}

I Hate Linux

Monday, January 14, 2008

WHS Dev Tip #15: Terminal Services

Did you know the Home Server Console uses the Remote Desktop Protocol/Terminal Services to bring the application to clients? Did you know that you can launch additional applications in the session?

Terminal Services

Before getting into what we can do... lets make sure we all understand what we are using...

Windows Terminal Services is a server component dating back to NT4 which allows remote machines to connect to a server and be presented with a (nearly) fully functional desktop where a user can do their work almost as fast and easily as if it was local without having to having access to anything more than a client app (available as either a desktop app or ActiveX control) and a network connection.

We saw this same technology brought to Windows XP for it's Remote Desktop feature and now in Windows Home Server for both normal Console use as well as more complicated administration.

Using Remote Desktop

Ordinarily when we want to connect to our Home Server to do administrative tasks that cannot be achieved in the Home Server Console, we'll do the following:

  1. Launch the Remote Desktop client
    • XP/2003: Start -> Run -> mstsc
    • Vista/2008: Start -> mstsc
  2. Specify server name/address
  3. Click the Connect button
  4. Provide credentials and click the OK button.

This is the simple way to connect and with default options. The client and protocol have many more options than we normally use.

Regular Connect

Startup Program

Rather than connecting to a new (or existing) user session on the server complete with desktop and start menu, we can instead request that a specific application (on the server) be launched on the server, to do so we need only:

  1. Click the Options button on the main Remote Desktop Connection Window
  2. Select the Program tab
  3. Check "Start the following program on connection"
  4. Specify a program or file

Once done, we can do something a simple as launch the Windows Calculator right away when we connect...

Calculator

Calculator in RDP

Or even just the Windows Home Server Console:

Start program

Console in regular Remote Desktop

The only thing missing (aside from the parent client window being sized better) is the removal of the window frame... which can be achieved by throwing in the -b argument:

Resized

That's right... the WHSConsoleClient application on WHS client PC's is largely just a fancy Terminal Services client that executes "homeserverconsole.exe -b" on the server on connect as well as provides the plumbing to make IConsoleServices.OpenHelp() and IConsoleServices.OpenUrl() calls be passed back to and launched on the client.

With this in mind we have a number of possibilities.

Warning

Before going any further I want to make clear that what I will be describing below is completely unsupported by me and by Microsoft and can result in loss of key files.

This information is provided for informational purposes only and for those who wish to do some hacking of their own server. Nothing in this post should be used as part of any add-in or other software on Home Server's that are not owned by reader of this post and author of said add-in or software.

Replacement

The simple method is simply to rename (and backup) HomeServerConsole.exe on the server and put in it's place an application of our choice or design that can handle being used in the strange window size used by the Home Server Console.

It's interesting to note that HomeServerConsole.exe like a good number of the Home Server files are not protected by Windows File Protection, nor is there any other security mechanism in place to prevent a malicious user from replacing HomeServerConsole.exe with their own application.

So what should we replace it with?

One method

I find myself often using the Remote Access web site to connect to my main desktop PC and sometimes need to do something on my Home Server... which requires launching one Remote Desktop connection inside of another one.

While this works... it's certainly not ideal. Instead what if we were to launch Windows Explorer in the same Terminal Services session that we have the Home Server Console in?

As easy as this would be with an add-in... a problem we have is is that the Console is displayed there without a Window frame or title bar...

So one option would be something like this:

class Program
{
   static void Main(string[] args)
   {
      string initalProgram = TerminalServices.GetInitialProgram(Process.GetCurrentProcess().SessionId);
 
      //In Home Server Connector?
      if (initalProgram.ToLower().StartsWith("homeserverconsole"))
      {
         //then launch explorer
         LaunchExplorer();
      }
 
      //Launch the Home Server Console anyway.
      LaunchHomeServerConsole();
   }
 
   static void LaunchHomeServerConsole()
   {
      Process.Start(@"C:\Program Files\Windows Home Server\HomeServerConsole1.exe");
   }
 
   static void LaunchExplorer()
   {
      Process.Start(@"explorer.exe");
   }
}

In the above code, I use some methods from the Terminal Services API to determine if the session our app is running in was asked to launch the Home Server Console, if so we'll launch the real thing (named HomeServerConsole1.exe in this example) as well as a copy of Explorer... otherwise we'll just launch the Home Server Console.

The actual check for to determine the startup application involves a call to WTSQuerySessionInformation() with the WTS_CONFIG_CLASS.WTSUserConfigInitialProgram enumerated value.

As simple and as workable as this is... it does have a major flaw... the Home Server Console expects to be named HomeServerConsole.exe for any number of operations including access to it's .config file. Instead of launching a new processes.. an alternative is to load the assembly containing the real thing and launch it within our own application (gotta love .NET reflection):

static void LaunchHomeServerConsole()
{
   Assembly whsConsole = Assembly.LoadFile(@"C:\Program Files\Windows Home Server\HomeServerConsole1.exe");
   whsConsole.EntryPoint.Invoke(null, new object[] { new string[0] });
}

Note the above code is remarkably slow on my WHS when it comes to launching the Home Server Console... resulting in a load time of several minutes, something I have not spent much time debugging as yet.

Home Server Console with Explorer

Improvements

With a little additional work, we could enumerate the currently running processes (with WTSEnumerateProcesses() ) and determine if an instance of explorer is already running, and if not launch one.

The Future

Likely this method will only work so long as there is no protection of the WHS files, although should that not change this option will be even more powerful should the next version of Windows Home Server be based on Windows Server 2008 and use TS RemoteApp for displaying of the Home Server Console.

Sample

No sample this week as this post is intended to be more theoretical and informational rather than practical.

Hopefully this has given you some ideas of how you could use this on your own.

Conclusion

With a little use of the Terminal Services API and a bit of file renaming it is possible to execute ones own custom code prior to the Home Server Console being launched, giving numerous options for additional customization of the Windows session that the Console is loaded in... be it launching Windows Explorer, other applications or applying custom external settings to the Home Server Console.

Next Time

Hacking the Home Server Console (in place) using reflection.

As always though, I'd love to hear your ideas of what you'd like to see in future.

Note: The information in this post is based on undocumented and at times deduced information on Windows Home Server and is not officially supported or endorsed by Microsoft and could very easily be wrong or subject to change in future, so please take it and everything else said on this blog with a grain of salt and use with caution.

Labels:

5 Comments:

  • I use an Add-in called Program Launcher that lets you run applications installed on your WHS. It has a Desktop option that allows you to hide all applications and show the desktop just like the Desktop button in the Quick Launch tray.
    I use it all the time to quit the console from the task menu and remote in to my WHS box without having to do all the work you suggest. You should check it out...

    Here is the add-in link:
    http://www.danno.ca/blog/WHS+Program+Launcher+12.aspx

    By Anonymous Anonymous, at 1:30 PM  

  • You are absolutely right that Program Launcher can launch Explorer within the remote session. Biggest problem with it’s method of doing things is that you still end up without the window frame around the Home Server Console, making it difficult to switch between it and other applications.

    By Blogger Brendan, at 9:52 AM  

  • Anonymous here again with a name. I have found your Dev Tips incredibly useful...

    I still think Program Launcher is a viable solution, mostly because I use it myself all the time.

    If you use taskmgr to end task on the console you can re-launch the console you now have a window-ed version of the console that you can close, minimize, restart, etc.

    I work on my add-ins with DevStudio installed on my WHS using this method when I have a minute or two and am not on my LAN.

    -Jeff Alexander

    By Blogger jeff, at 6:30 PM  

  • Hmm - I'd figured out a lot of this already, but the -b switch will be very useful for what I am trying to do.
    I want to set it up so that another user can log into the console and have limited access to some of the console functions (i.e. Computers & Backup) but not others (such as User Accounts).
    So far, I have:
    1. Created a separate account for the RDC to connect to (for the moment I've assigned it the same groups as the Administrator account)
    2. Set up RDC to automatically launch Home Server Console on connection (now using the -b switch)

    What I want to do next is be able to customize which tabs will appear in this particular instance of the console, so that the user opening the console in this way will have limited access, as well as giving the user some way of logging off (before I used the -b switch, closing the console initiated the log-off)

    Any thoughts?

    By Blogger Michael, at 6:02 PM  

  • thanks for the tip on WHSC using RDP.

    You can resize the parent window by creating a shortcut to call Remote Desktop then modify the properties to specify the size of the window.

    Here's what I put into the Target field on the Shortcut tab of the shortcut proeprties:

    %SystemRoot%\system32\mstsc.exe /w:995 /h:674

    /w and /h are for width and height, respectively, and the values are what I arrived at by trial and error to make an exact fit.

    ymmv

    By Blogger kima, at 10:17 AM  

Post a Comment

<< Home