tags:

views:

64

answers:

3

Hello,

I am writing a test application which is controlling another computer. The test computer is started by sending a command string via the RS-232 port (from a control computer running Windows XP SP2 using a C# application), at which time the test computer will power-on and boot into Windows XP. I would like to know what would be the best method to determine when that computer has completed it boot process and running normally.

I was thinking of the following:

1) I was either thinking of pinging that computer, or
2) Have a shared drive and if able to access that shared drive, or
3) Writing a small service which I can communicate with

Is there different/better approach?

Mark

A: 

the service would be the mos elegant solution ...

+1 useful question

Luiscencio
+1  A: 

It all depends on what you consider "completed its boot process and is running normally". For instance, if all you care is the moment the network card is initialized, pinging might be good (as long as the ECHO port isn't closed).

A share is not a good idea as they generally only become available when a user is logged in, which may or may not be the case depending on your situation. But even if, what if you change the configuration or decide it is a security breach to open up a share?

If you want to play it certain or if you just need to wait until all services have started, you should consider your third option. It's easiest to do. Let it listen on port 80 and run from IIS. When queried, it can answer with some details of the machine. This will also give you the most flexibility. Using IIS helps you for not having to write your own service and makes it trivial to install and configure.

If IIS is not an option, you can of course consider writing your own service. Not that hard to do, but it'll require you to write the code to listen to certain ports yourself.

Abel
A: 

I had the exact problem you did, I found writing a custom service was the most useful. (I actually needed to know when a headless machine had the Remote Desktop service ready to accept connections, the program I wrote actually beeps the PC speaker a little tune when it is ready to be logged in.

EDIT: I dug up the source in case you where interested.

using System.ComponentModel;
using System.Configuration.Install;
using System.Runtime.InteropServices;
using System.ServiceProcess;
using System.Threading;

namespace Beeper
{
    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        static void Main()
        {
            ServiceBase[] ServicesToRun;
            ServicesToRun = new ServiceBase[] 
                { 
                    new Beeper() 
                };
            ServiceBase.Run(ServicesToRun);
        }
    }

    public partial class Beeper : ServiceBase
    {
        public Beeper()
        {
        }

        protected override void OnStart(string[] args)
        {
            if (MainThread != null)
                MainThread.Abort();
            MainThread = new Thread(new ThreadStart(MainLoop));
            MainThread.Start();
        }

        protected override void OnStop()
        {
            if (MainThread != null)
                MainThread.Abort();
        }

        protected void MainLoop()
        {
            try
            {
                //main code here
            }
            catch (ThreadAbortException)
            {
                //Do cleanup code here.
            }
        }

        System.Threading.Thread MainThread;
    }
    [RunInstaller(true)]
    public class BeeperInstaller : Installer
    {
        private ServiceProcessInstaller processInstaller;
        private ServiceInstaller serviceInstaller;
        public BeeperInstaller()
        {
            processInstaller = new ServiceProcessInstaller();
            serviceInstaller = new ServiceInstaller();
            processInstaller.Account = ServiceAccount.LocalSystem;
            serviceInstaller.StartType = ServiceStartMode.Automatic;
            serviceInstaller.ServiceName = "MyProgram";
            serviceInstaller.ServicesDependedOn = new string[] { "TermService" }; //Optional, this line makes sure the terminal services is up and running before it starts.
            Installers.Add(serviceInstaller);
            Installers.Add(processInstaller);
        }
    }
}
Scott Chamberlain
Just curious: why wouldn't you, in that scenario, just query the RDP port? If you'd receive an answer, it's up.
Abel
So I don't need to be constantly clicking connect to see when it is ready. When I hear the tone it reminds me to go start up mstsc and connect in.
Scott Chamberlain
It seems that a developing a service is probably the best approach, though I may rely on a shared folder as the user *may* need to log on to run some test software, unless it will run without the user logging on. I still need to see if the test software will run without the user logging on. In either case I can have the service check to see if the user is logged on then send a signal back to the controller PC to start the test. I selected Scott's answer as he was kind enough to provide source code for my cause.
lordhog
@lordhog One thing to note, if your code is not going to just self terminate immediately like my code does. the main loop of your code should not be in the OnStart function. OnStart should create its own thread and do the work here. I will update the example.
Scott Chamberlain