Project.CreateProjectFromTemplate Method

Creates a new project from a specified template. The new project has the specified project name.

Namespace:  WebSvcProject
Assembly:  ProjectServerWebServices (in ProjectServerWebServices.dll)

Syntax

'Declaration
<SoapDocumentMethodAttribute("http://schemas.microsoft.com/office/project/server/webservices/Project/CreateProjectFromTemplate", RequestNamespace := "http://schemas.microsoft.com/office/project/server/webservices/Project/",  _
    ResponseNamespace := "http://schemas.microsoft.com/office/project/server/webservices/Project/",  _
    Use := SoapBindingUse.Literal, ParameterStyle := SoapParameterStyle.Wrapped)> _
Public Function CreateProjectFromTemplate ( _
    templateUid As Guid, _
    projectName As String _
) As Guid
'Usage
Dim instance As Project
Dim templateUid As Guid
Dim projectName As String
Dim returnValue As Guid

returnValue = instance.CreateProjectFromTemplate(templateUid, _
    projectName)
[SoapDocumentMethodAttribute("http://schemas.microsoft.com/office/project/server/webservices/Project/CreateProjectFromTemplate", RequestNamespace = "http://schemas.microsoft.com/office/project/server/webservices/Project/", 
    ResponseNamespace = "http://schemas.microsoft.com/office/project/server/webservices/Project/", 
    Use = SoapBindingUse.Literal, ParameterStyle = SoapParameterStyle.Wrapped)]
public Guid CreateProjectFromTemplate(
    Guid templateUid,
    string projectName
)

Parameters

  • templateUid
    Type: System.Guid
    GUID of the project template.

Return Value

Type: System.Guid
The GUID of the created project.

Remarks

CreateProjectFromTemplate creates the new project in the Draft database. The current user must have both of the permissions specified in the Permissions table.

If the template includes tasks that have notes, the task notes do not show when you create a new project using CreateProjectFromTemplate and then open the project in Microsoft Office Project Professional. You can use Project Professional to create a template that contains task notes, and publish the project template. The MSP_TASKS table in the Published database includes the TASK_RTF_NOTES column, which has data for the template. After you programmatically create and save a new project based on that template, the TASK_RTF_NOTES column contains text data for the task notes, not RTF (Rich Text Format) data.

The problem is that TASK_RTF_NOTES is of data type image for RTF data. The PSI Web services in the Shared Services Provider cannot handle RTF data. To add task notes in projects that are programmatically created on Project Server from a template, you must directly access the MSP_TASKS table to do the following:

  • Add the RTF data to the TASK_RTF_NOTES column for the specific task.

  • Set the TASKS_HAS_NOTES column to 1 (true).

Note

Currently no method is available to programmatically add the task notes in a template to a project created from that template. You cannot use the Project Server Interface (PSI) to create local custom fields in projects. However, the PSI does support editing local custom field values on tasks, resources, and assignments. View settings such as added fields are not copied into the new project from the template.

Project Server Permissions

Permission

Description

NewProject

Can create a new project. Global permission.

OpenProjectTemplate

Can open project templates. Global permission.

Examples

The following example creates a template, finds that template by name, and then creates a new project based on that template. It is necessary to create a template since Project Server 2007 does not have any default templates that are guaranteed to be in place.

Typically, you would present a list of templates and their unique IDs, and use that to choose the desired template. In some cases you might want to find a project or template by name. That is demonstrated here. You must have the exact name of the project to find it.

Please see Prerequisites for Reference Code Samples for critical information on running this code sample.

using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Web.Services.Protocols;
using System.Threading;
using PSLibrary = Microsoft.Office.Project.Server.Library;

namespace Microsoft.SDK.Project.Samples.CreateProjectFromTemplate
{
   class Program
   {
      static void Main(string[] args)
      {
         try
         {
            const string PROJECT_SERVER_URI = "http://ServerName/ProjectServerName/";
            const string PROJECT_SERVICE_PATH = "_vti_bin/psi/project.asmx";
            const string QUEUESYSTEM_SERVICE_PATH = "_vti_bin/psi/queuesystem.asmx";

            Guid jobId;

            // Set up the Web service objects
            ProjectWebSvc.Project projectSvc = new ProjectWebSvc.Project();

            ProjectWebSvc.ProjectDataSet projectDs = new ProjectWebSvc.ProjectDataSet();

            projectSvc.Url = PROJECT_SERVER_URI + PROJECT_SERVICE_PATH;
            projectSvc.UseDefaultCredentials = true; 

            QueueSystemWebSvc.QueueSystem q = new QueueSystemWebSvc.QueueSystem();
            q.Url = PROJECT_SERVER_URI + QUEUESYSTEM_SERVICE_PATH;
            q.UseDefaultCredentials = true;

            // Create a template to find
            //  - Normally, you would have a template already stored on the
            //    server that you would use, but we will create one to 
            //    use in our example
            Console.WriteLine("Creating template");
            ProjectWebSvc.ProjectDataSet templateDs = new ProjectWebSvc.ProjectDataSet();
            ProjectWebSvc.ProjectDataSet.ProjectRow templateRow = templateDs.Project.NewProjectRow();
            templateRow.PROJ_UID = Guid.NewGuid();
            templateRow.PROJ_NAME = "Its a wonderful template! " + DateTime.Now.ToShortTimeString().Replace(":", "+");
            templateRow.WPROJ_DESCRIPTION = "Temporary template for use in CreateProjectFromTemplate example.";
            templateRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Template;

            templateDs.Project.AddProjectRow(templateRow);

            // write the new template info to the database
            Console.WriteLine("Saving template to database");
            jobId = Guid.NewGuid();
            projectSvc.QueueCreateProject(jobId, templateDs, false);
            WaitForQueue(q, jobId);

            // Find the template by name
            //    We could just use the Guid to create the project from a template now
            //    but we want to show how to obtain the Guid from the name.
            // Note: If you have a template on the enterprise server already, you can use
            //    projectSvc.ReadProjectStatus(Guid.Empty, ProjectWebSvc.DataStoreEnum.PublishedStore, String.Empty, (int) PSLibrary.Project.ProjectType.Template);
            //    to get a list of published templates.
            Console.WriteLine("Finding the template by name");
            ProjectWebSvc.ProjectDataSet readTemplateDs = projectSvc.ReadProjectStatus(Guid.Empty, ProjectWebSvc.DataStoreEnum.WorkingStore, templateRow.PROJ_NAME, (int)PSLibrary.Project.ProjectType.Template);

            // Come up with a name for the project
            string projectName = "Created from " + readTemplateDs.Project[0].PROJ_NAME + " at " + DateTime.Now.ToShortTimeString().Replace(":", "-");

            // Create the new project on the Server and get its Guid
            Console.WriteLine("Create the new project from the template");
            Guid newProjectGuid = projectSvc.CreateProjectFromTemplate(readTemplateDs.Project[0].PROJ_UID, projectName);
         }
        catch (SoapException ex)
         {
            PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
            PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
            string errMess = "==============================\r\nError: \r\n";
            for (int i = 0; i < errors.Length; i++)
            {
               errMess += "\n" + ex.Message.ToString() + "\r\n";
               errMess += "".PadRight(30, '=') + "\r\nPSCLientError Output:\r\n \r\n";
               errMess += errors[i].ErrId.ToString() + "\n";

               for (int j = 0; j < errors[i].ErrorAttributes.Length; j++)
               {
                  errMess += "\r\n\t" + errors[i].ErrorAttributeNames()[j] + ": " + errors[i].ErrorAttributes[j];
               }
               errMess += "\r\n".PadRight(30, '=');
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(errMess);
         }
         catch (WebException ex)
         {
            string errMess = ex.Message.ToString() +
               "\n\nLog on, or check the Project Server Queuing Service";
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Error: " + errMess);
         }
         catch (Exception ex)
         {
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine("Error: " + ex.Message);
         }
         finally
         {
            Console.ResetColor();
            Console.WriteLine("\r\n\r\nPress any key...");
            Console.ReadKey();
         }
      }
      static private void WaitForQueue(QueueSystemWebSvc.QueueSystem q, Guid jobId)
      {
         QueueSystemWebSvc.JobState jobState;
         const int QUEUE_WAIT_TIME = 2; // two seconds
         bool jobDone = false;
         string xmlError = string.Empty;
         int wait = 0;

         //Wait for the project to get through the queue
         // - Get the estimated wait time in seconds
         wait = q.GetJobWaitTime(jobId);

         // - Wait for it
         Thread.Sleep(wait * 1000);
         // - Wait until it is done.

         do
         {
            // - Get the job state
            jobState = q.GetJobCompletionState(jobId, out xmlError);

            if (jobState == QueueSystemWebSvc.JobState.Success)
            {
               jobDone = true;
            }
            else
            {
               if (jobState == QueueSystemWebSvc.JobState.Unknown
               || jobState == QueueSystemWebSvc.JobState.Failed
               || jobState == QueueSystemWebSvc.JobState.FailedNotBlocking
               || jobState == QueueSystemWebSvc.JobState.CorrelationBlocked
               || jobState == QueueSystemWebSvc.JobState.Canceled)
               {
                  // If the job failed, error out
                  throw (new ApplicationException("Queue request failed \"" + jobState + "\" Job ID: " + jobId + ".\r\n" + xmlError));
               }
               else
               {
                  Console.WriteLine("Job State: " + jobState + " Job ID: " + jobId);
                  Thread.Sleep(QUEUE_WAIT_TIME * 1000);
               }
            }
         }
         while (!jobDone);
      }
   }
}

See Also

Reference

Project Class

Project Members

WebSvcProject Namespace