public static void MainLoop()
        {
            comm.GotStartPublishMessage += new EventHandler<WatchdogMessageEventArgs<StartPublishMessage>>(comm_GotStartPublishMessage);
            comm.GotStopPublishMessage += new EventHandler<WatchdogMessageEventArgs<StopPublishMessage>>(comm_GotStopPublishMessage);
            comm.GotWatchdogTerminateMessage += new EventHandler<WatchdogMessageEventArgs<WatchdogTerminateMessage>>(comm_GotWatchdogTerminateMessage);
            comm.GotCommandMessage += new EventHandler<WatchdogMessageEventArgs<CommandMessage>>(comm_GotCommandMessage);

            Thread t = new Thread(new ThreadStart(StatusThread));
            t.Name = "Watchdog Status Thread";
            t.Start();
            Publish autoP = AutodetectActivePublish();
            if (autoP != null)
            {
                StartPublish(autoP.name);
            }
            #if !SERVICE

            while(running)
            {
                string s = Console.ReadLine();
                if (s == null) continue;
                if (s.StartsWith("load") && s.Split(" ".ToCharArray(), StringSplitOptions.None).Length > 1) //load a publish
                {
                    Trace.WriteLine("Loading " + s.Substring(s.IndexOf(" ") + 1));
                    curPublish = Publish.Load(s.Substring(s.IndexOf(" ") + 1),pubRoot);
                }
                if (s.StartsWith("show all"))
                {
                    foreach (string p in Publish.GetAllPublishNames(pubRoot))
                    {
                        Trace.WriteLine(p);
                    }
                }
                if (s.StartsWith("curpub"))
                {
                    if (curPublish == null)
                        Trace.WriteLine("No Publish Loaded.");
                    else
                    {
                        curPublish.PrintDebug();
                        Trace.WriteLine("Running: " + curPublish.IsCommandRunning());
                    }
                }
                if (s.StartsWith("start"))
                {
                    if (curPublish == null) Trace.WriteLine("No publish loaded.");
                    else curPublish.Start(pubRoot);
                }

                if (s.StartsWith("wdon"))
                {
                    if (curPublish == null) Trace.WriteLine("No publish loaded.");
                    else
                    {
                        Trace.WriteLine("Enabling Watchdog...");
                        curPublish.watchdogAutoRestart = true;
                    }
                }

                if (s.StartsWith("wdoff"))
                {
                    if (curPublish == null) Trace.WriteLine("No publish loaded.");
                    else
                    {
                        Trace.WriteLine("Disabling Watchdog...");
                        curPublish.watchdogAutoRestart = false;
                    }
                }
                if (s.StartsWith("list"))
                {
                    Process[] parr = Process.GetProcesses();
                    List<Process> runningProcesses = new List<Process>(parr);
                    foreach (Process filename in runningProcesses)
                    {
                        Trace.WriteLine(filename.ProcessName);
                    }
                }

            }
            t.Abort();
            traceText.Flush();
            #endif
        }
        static void StartPublish(string name)
        {
            //if we had an old publish, kill it.
            if (curPublish != null)
            {
                curPublish.Stop();
                curPublish.Dispose();
            }

            try
            {
                curPublish = Publish.Load(name, pubRoot);
            }
            catch (Exception ex)
            {
                comm.SendMessage<StartStopPublishMessageReply>(new StartStopPublishMessageReply(WatchdogComm.GetMachineName(), name, false, "Exception Loading Publish" + ex.Message));
                return;
            }
            PublishRunStatus status = new PublishRunStatus("Unknown Publish Error", false);
            try
            {
                status = curPublish.Start(pubRoot);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Exception Starting! " + ex.Message);
                comm.SendMessage<StartStopPublishMessageReply>(new StartStopPublishMessageReply(WatchdogComm.GetMachineName(), name, false, "Exception Loading Publish" + ex.Message));
                return;
            }
            Trace.WriteLine("Pub Status: " + status.text);
            curPublish.WatchdogReset += new EventHandler(curPublish_WatchdogReset);
            comm.SendMessage<StartStopPublishMessageReply>(new StartStopPublishMessageReply(WatchdogComm.GetMachineName(), curPublish.name, status.ok, status.text));
        }
        public static void SendPublishDefinitionOnly(Publish pub, RemotePublishLocation publoc, string pubRoot)
        {
            Trace.WriteLine("------------Attempting to send publish definition " + pub.name + " to " + publoc.name + ".---------------");
            string netDrive = NetworkDrive.GetNextAvailableDrive();
            if (publoc.remoteShare.EndsWith("\\")) publoc.remoteShare = publoc.remoteShare.Remove(publoc.remoteShare.Length - 1);
            Trace.WriteLine("Mounting Drive " + netDrive + " to " + publoc.remoteShare + "...");
            try
            {
                NetworkDrive.zMapDrive(publoc.username, publoc.password, netDrive, publoc.remoteShare);
            }
            catch (Exception ex)
            {
                Trace.WriteLine("Failed to map network drive! " + ex.Message);
                return;
            }

            Trace.WriteLine("Copying files...");
            try
            {
                File.Copy(Publish.FilenameFromPublishname(pub.name, pubRoot), netDrive + "\\" + pub.name + Publish.pubExt, true);
            }
            catch (IOException ex)
            {
                Trace.WriteLine("Error copying file " + Publish.FilenameFromPublishname(pub.name, pubRoot) + ".");
                Trace.WriteLine("Check the publish is stopped and that your definition of the publish is recent. Detail:" + ex.Message);
                NetworkDrive.zUnMapDrive(true, netDrive);
                Trace.WriteLine("Published Defition Failed!----------------------------------------");
                return;
            }
            pub.lastPublish = DateTime.Now;
            pub.Save(pubRoot);
            if (publoc.removeShare)
                NetworkDrive.zUnMapDrive(true, netDrive);
            Trace.WriteLine("Published Defition Sent OK!----------------------------------------------");

            return;
        }
        public static void SendPublishToRemoteComputer(Publish pub, RemotePublishLocation publoc, string pubRoot, EventHandler<SendPublishEventArgs> completed, bool dobackup )
        {
            Object[] objects = new object[5];
            objects[0] = pub; objects[1] = publoc; objects[2] = pubRoot; objects[3] = completed; objects[4] = dobackup;

            Thread publishThread = new Thread(new ParameterizedThreadStart(SendPublish));
            publishThread.Start(objects);
        }
        void MonitorFunction(object state)
        {
            Trace.WriteLine("Monitor Started.");

            Publish p = (state as Publish);

            if (p.watchdogNames == null || p.watchdogNames.Count == 0)
            {
                Trace.WriteLine("Cannot Monitor becuase watchdog name is null or blank.");
                return;                 //we cant monitor without a watchdog name
            }
            WaitHandle[] handles = new WaitHandle[p.watchdogNames.Count];
            int          i       = 0;

            foreach (string s in p.watchdogNames)
            {
                handles[i++] = new EventWaitHandle(false, EventResetMode.AutoReset, s);
                Trace.WriteLine("Created WatchdogHandle : " + s);
            }


            if (!AutoResetEvent.WaitAll(handles, 30000, false))
            {
                Trace.WriteLine("Timed out waiting for init signal (30 seconds).");
            }
            Thread.Sleep(p.watchdogPeriodms);
            Trace.WriteLine("Monitor Initialized. Watchdog Active: " + watchdogAutoRestart.ToString());



            while (runWatchdogThread)
            {
                if (!AutoResetEvent.WaitAll(handles, p.watchdogPeriodms, false))
                //if (!AutoResetEvent.WaitOne(p.watchdogPeriodms, false))//check for timeout
                {
                    if (watchdogAutoRestart && active)                     //we have timed out, see if we should reset
                    {
                        lastWatchdogIntervention = DateTime.Now;
                        Trace.WriteLine("Beginning Watchdog Reset @ " + DateTime.Now);
                        Trace.WriteLine("Watchdog Stopping Processs...");
                        if (this.StopCommands())
                        {
                            Thread.Sleep(p.watchdogPeriodms * 2);
                            Trace.WriteLine("Watchdog Starting Processs...");
                            this.StartCommands(pubRoot);
                            Trace.WriteLine("Watchdog Firing Event..");
                            if (WatchdogReset != null)
                            {
                                WatchdogReset(this, null);
                            }
                            Trace.WriteLine("Reinitializing Wait Handles...");
                            if (!AutoResetEvent.WaitAll(handles, 30000, false))
                            {
                                Trace.WriteLine("Timed out waiting for init signal (30 seconds).");
                            }
                            Thread.Sleep(p.watchdogPeriodms);
                        }
                    }
                }
                else
                {
                    Trace.WriteLine("Got Signals OK");
                }
            }
            Trace.WriteLine("Monitor Exited.");
        }