Search code examples
ms-projectcsomproject-serverms-project-server-2013ms-project-server-2016

Is there a way to programmatically tell when Project has finished Publishing to Project Server?


I have a tool that is going to open a MS Project file off the Project Web App (PWA/Project Server). and make some changes. I then need to save the file and publish the changes before closing it and checking it it. Project Server has issues when a file is checked in before the publish process is complete. I'm trying to find something in the API that will indicate when the publish is complete but I can't find anything.

Is there any way I can programmatically tell when the publish to Project Server is complete?

I've attempted to call the Application.Publish method before the Application.FileCloseEx(PjSaveType.pjDoNotSave, CheckIn: true) method but the FileCloseEx method will execute before the publish is complete in my tests

Maybe something in the CSOM library can access the Project Server's queued jobs?


Solution

  • Figured out a way to do this by using the CSOM NuGet package:

    // add this using statement at the top of the file.
    using PWA = Microsoft.ProjectServer.Client; 
    
    
    public static PWA.JobState WaitForProjectToFinishPublishing(string projectName, string serverUrl)
        {
            PWA.JobState jState = PWA.JobState.Failed;
            
            PWA.ProjectContext serverContext = null;
    
            using (serverContext = new PWA.ProjectContext(serverUrl))
            {
                try
                {
                    serverContext.Credentials = System.Net.CredentialCache.DefaultNetworkCredentials;
    
                    // Query PWA for the Projects
                    serverContext.Load(serverContext.Projects);
                    serverContext.ExecuteQuery();
    
                    // get the project we are wanting to wait to finish publishing
                    var pubPrj = serverContext.Projects.Where(p => p.Name == projectName).FirstOrDefault();
    
                    if (pubPrj != null)
                    {
                        // Query PWA for the Queued jobs of the Project. (Publish will be one of the queued jobs if it is still publishing)
                        serverContext.Load(pubPrj.QueueJobs);
                        serverContext.ExecuteQuery();
    
                        // get the publish job
                        var publishJob = pubPrj.QueueJobs.Where(qJ => qJ.MessageType == PWA.QueueMsgType.ProjectPublish).FirstOrDefault();
    
                        if (publishJob != null)
                        {
                            // use the WaitForQueue method to wait for the publish job to finish. Timeout after 5 minutes (large projects can take some time to publish)
                            jState = serverContext.WaitForQueue(publishJob, 300);
                        }
                    }
                }
                catch (Exception ex)
                {
                    // log something if you want
                }
            }
    
            return jState;
        }