Automating Project Pro to Project Server - Winproj State

I’m heading off for a holiday vacation, so I’m front loading my posts for a few weeks. I’m getting pretty excited because I should be able to start talking about Project 12 once the Project Conference completed in January.

Let’s complete the series on automating Project Pro to Project Server. The final key to the solution is detecting when

1) Project Pro is not running

2) Project Pro is running AND connected to Project Server.

We’ll start with the first case, how to detect Project Pro is not running. Your first question should be, “Why do I care if Project Pro is NOT running?” You care because if you send a command to start Project Pro and Project Pro is ALREADY running you will NOT restart Project Pro. You will get whatever the current running condition is, maybe offline, but not necessarily the requested condition. So hence we want to shut down Project Pro before we start it up, and verify it is shut down. The following routine will wait a prescribed number of seconds to verify Project Pro is shut down.

        public bool IsProjectClosed(double WaitTime)

        {

            int i;

            DateTime currentTime = DateTime.Now;

            DateTime adjustedTime = currentTime.AddSeconds(WaitTime);

            TimeSpan targetTime = new TimeSpan(adjustedTime.Ticks);

            i = targetTime.CompareTo(new TimeSpan(DateTime.Now.Ticks));

            while (i >= 0)

            {

                Process[] winProjProcess = Process.GetProcessesByName("WINPROJ");

                if (winProjProcess.Length == 0)

                    // No Project process so return

                    return true;

                else

                    // Found Process

                    Thread.Sleep(200);

                i = targetTime.CompareTo(new TimeSpan(DateTime.Now.Ticks));

            }

            // Continued to get window before wait time expired

            return false;

        }

Other than the time manipulation routines (which you can look up on your own) the key here is searching for the WINPROJ process. If it’s not found in the process list, true is retuned.

The final act in automating Project Pro is detecting when it’s running. At first blush you would say reverse the above procedure to find when WINPROJ is a valid process. That would only work in a disconnect mode. If you immediately make a call to the COM API, you would get an 0x80040005 error. But why does it fail, I have a valid object? It fails because Project Pro is still connecting to Project Server. Detecting that Project Server is connected is not straight forward, you can’t call the COM API to find out. There are various solutions, the most obvious being setting a timer to wait. But this could be disastrous on a high latency system. The route I chose was to detect windows. What I found is the Gantt chart doesn’t display till the Project Server connection is completed. Below is my routine for detecting that project Pro has started up connected to Project Server.

        [DllImport("user32.dll", EntryPoint = "FindWindow")]

        private static extern int FindWindow(string strClassName, string strWindowName);

        [DllImport("User32.dll")]

        public static extern int FindWindowEx(int hwndParent, int hwndChildAfter, string strClassName, string strWindowName);

        public bool IsProjectRunning(double WaitTime)

        {

            int i;

            DateTime currentTime = DateTime.Now;

            DateTime adjustedTime = currentTime.AddSeconds(WaitTime);

            TimeSpan targetTime = new TimeSpan(adjustedTime.Ticks);

            i = targetTime.CompareTo(new TimeSpan(DateTime.Now.Ticks));

            while (i >= 0)

            {

                int hwdMain = FindWindow("JWinproj-WhimperMainClass", null);

                if (hwdMain > 0)

         {

                    int hwdMDI = FindWindowEx(hwdMain, 0, "MDIClient", null);

                    if (hwdMDI > 0)

                    {

                        // Project Server initialization not complete till project shows in window

            if (FindWindowEx(hwdMDI, 0, "Winproj-DocWindowClass", null) > 0)

                            // Found Window

                            return true;

                        else

                            Thread.Sleep(200);

                  }

                    else

                        Thread.Sleep(200);

                }

                else

                    Thread.Sleep(200);

                i = targetTime.CompareTo(new TimeSpan(DateTime.Now.Ticks));

            }

            // Failed to get window before wait time expired

            return false;

        }

The key is there is a progression of three windows that you cycle through to determine complete startup. The last window Winproj-DocWindowClass is the container for the Gantt chart.

Everyone have a wonderful holiday and a Happy New Year. However you celebrate I hope it’s with friends, family, and loved ones.

Comments

  • Anonymous
    February 17, 2006
    Could you provide complete sample code for the process to get Project (hooked to Project Server) started and ready for automation calls?  It also apears that when you create the automation instance of Project, it automatically connects to the running instance of Project. Is this true?