Welcome to TechNet Blogs Sign in | Join | Help

News for All PSI Developers

If you are doing Project Server development using the PSI then you NEED to check out what Colby Africa is doing with mpFx.  This is a set of class libraries that simplifies the development of PSI code. It reduces the number of calls you need to make to do things like create projects, assign resources, create tasks, etc.

This is what is required to create a project and wait for the queue job to finish:

   1: namespace Microsoft.SDK.Project.Samples.QueueCreateProject
   2: {
   3:     class Program
   4:     {
   5:         [STAThread]
   6:         static void Main(string[] args)
   7:         {
   8:             try
   9:             {
  10:                 const string PROJECT_SERVER_URI = "h//ServerName/ProjectServerName/";
  11:                 const string PROJECT_SERVICE_PATH = "_vti_bin/psi/project.asmx";
  12:                 const string QUEUESYSTEM_SERVICE_PATH = "_vti_bin/psi/queuesystem.asmx";
  13:  
  14:                 Guid jobId;
  15:  
  16:                 // Set up the Web service objects
  17:                 ProjectWebSvc.Project projectSvc = new ProjectWebSvc.Project();
  18:  
  19:                 ProjectWebSvc.ProjectDataSet projectDs = new ProjectWebSvc.ProjectDataSet();
  20:  
  21:                 projectSvc.Url = PROJECT_SERVER_URI + PROJECT_SERVICE_PATH;
  22:                 projectSvc.Credentials = CredentialCache.DefaultCredentials;
  23:  
  24:                 QueueSystemWebSvc.QueueSystem q = new QueueSystemWebSvc.QueueSystem();
  25:                 q.Url = PROJECT_SERVER_URI + QUEUESYSTEM_SERVICE_PATH;
  26:                 q.UseDefaultCredentials = true;
  27:  
  28:                 projectDs = new ProjectWebSvc.ProjectDataSet();
  29:  
  30:                 // Create the project
  31:                 ProjectWebSvc.ProjectDataSet.ProjectRow projectRow = projectDs.Project.NewProjectRow();
  32:                 projectRow.PROJ_UID = Guid.NewGuid();
  33:                 projectRow.PROJ_NAME = "Its a wonderful project at " +
  34:                    DateTime.Now.ToShortDateString().Replace("/", "") + " " +
  35:                    DateTime.Now.ToShortTimeString().Replac", "");
  36:                 projectRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Project;
  37:                 projectDs.Project.AddProjectRow(projectRow);
  38:  
  39:                 // Add some tasks        
  40:                 jobId = Guid.NewGuid();
  41:                 projectSvc.QueueCreateProject(jobId, projectDs, false);
  42:                 WaitForQueue(q, jobId);
  43:  
  44:             }
  45:             catch (SoapException ex)
  46:             {
  47:                 PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
  48:                 PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
  49:                 string errMess = "==============================\r\nEr \r\n";
  50:                 for (int i = 0; i < errors.Length; i++)
  51:                 {
  52:                     errMess += "\n" + ex.Message.ToString() + "\r\n";
  53:                     errMess += "".PadRight(30, '=') + "\r\nPSCLientError Out\r\n \r\n";
  54:                     errMess += errors[i].ErrId.ToString() + "\n";
  55:  
  56:                     for (int j = 0; j < errors[i].ErrorAttributes.Length; j++)
  57:                     {
  58:                         errMess += "\r\n\t" + errors[i].ErrorAttributeNames()[j]  " + errors[i].ErrorAttributes[j];
  59:                     }
  60:                     errMess += "\r\n".PadRight(30, '=');
  61:                 }
  62:                 Console.ForegroundColor = ConsoleColor.Red;
  63:                 Console.WriteLine(errMess);
  64:             }
  65:             catch (WebException ex)
  66:             {
  67:                 string errMess = ex.Message.ToString() +
  68:                    "\n\nLog on, or check the Project Server Queuing Service";
  69:                 Console.ForegroundColor = ConsoleColor.Red;
  70:                 Console.WriteLine("Er " + errMess);
  71:             }
  72:             catch (Exception ex)
  73:             {
  74:                 Console.ForegroundColor = ConsoleColor.Red;
  75:                 Console.WriteLine("Er " + ex.Message);
  76:             }
  77:             finally
  78:             {
  79:                 Console.ResetColor();
  80:                 Console.WriteLine("\r\n\r\nPress any key...");
  81:                 Console.ReadKey();
  82:             }
  83:         }
  84:         static private void WaitForQueue(QueueSystemWebSvc.QueueSystem q, Guid jobId)
  85:         {
  86:             QueueSystemWebSvc.JobState jobState;
  87:             const int QUEUE_WAIT_TIME = 2; // two seconds
  88:             bool jobDone = false;
  89:             string xmlError = string.Empty;
  90:             int wait = 0;
  91:  
  92:             //Wait for the project to get through the queue
  93:             // - Get the estimated wait time in seconds
  94:             wait = q.GetJobWaitTime(jobId);
  95:  
  96:             // - Wait for it
  97:             Thread.Sleep(wait * 1000);
  98:             // - Wait until it is done.
  99:  
 100:             do
 101:             {
 102:                 // - Get the job state
 103:                 jobState = q.GetJobCompletionState(jobId, out xmlError);
 104:  
 105:                 if (jobState == QueueSystemWebSvc.JobState.Success)
 106:                 {
 107:                     jobDone = true;
 108:                 }
 109:                 else
 110:                 {
 111:                     if (jobState == QueueSystemWebSvc.JobState.Unknown
 112:                     || jobState == QueueSystemWebSvc.JobState.Failed
 113:                     || jobState == QueueSystemWebSvc.JobState.FailedNotBlocking
 114:                     || jobState == QueueSystemWebSvc.JobState.CorrelationBlocked
 115:                     || jobState == QueueSystemWebSvc.JobState.Canceled)
 116:                     {
 117:                         // If the job failed, error out
 118:                         throw (new ApplicationException("Queue request failed \"" + jobState + "\" Job " + jobId + ".\r\n" + xmlError));
 119:                     }
 120:                     else
 121:                     {
 122:                         Console.WriteLine("Job St " + jobState + " Job " + jobId);
 123:                         Thread.Sleep(QUEUE_WAIT_TIME * 1000);
 124:                     }
 125:                 }
 126:             }
 127:             while (!jobDone);
 128:         }
 129:     }
 130: }

 

Here is the same code in mpFx:

   1: using System;
   2: using System.Web.Services.Protocols;
   3: using CodePlex.MicrosoftProject.mpFx;
   4: using CodePlex.MicrosoftProject.mpFx.ProjectsWebService;
   5:  
   6: namespace ConsoleTest
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             using (ProjectServer projectServer = new ProjectServer("h//epm2007demo/pwa", DataStoreEnum.WorkingStore))
  13:             {
  14:                 using (ProjectDataSet projectDataSet = EntityFactory.NewProject("Demo"))
  15:                 {
  16:                     try
  17:                     {
  18:                         projectServer.Projects.Create(projectDataSet, false, true);
  19:                     }
  20:                     catch (SoapException exception)
  21:                     {
  22:                         Console.WriteLine(Errors.ProcessMSProjectErrors(exception));
  23:                     }
  24:                     catch (Exception exception)
  25:                     {
  26:                         Console.WriteLine(exception.Message);                        
  27:                     }
  28:                 }
  29:             }
  30:         }
  31:     }
  32: }

32 lines of code as opposed to 130!

Published Thursday, January 29, 2009 8:12 AM by brianken

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

No Comments

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker