Поделиться через


Метод Project.CreateProjectFromTemplate

Создает проект на основе указанного шаблона. Новый проект имеет имя указанного проекта.

Пространство имен:  WebSvcProject
Сборка:  ProjectServerServices (в ProjectServerServices.dll)

Синтаксис

'Декларация
<SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/CreateProjectFromTemplate", RequestNamespace := "https://schemas.microsoft.com/office/project/server/webservices/Project/",  _
    ResponseNamespace := "https://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
'Применение
Dim instance As Project
Dim templateUid As Guid
Dim projectName As String
Dim returnValue As Guid

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

Параметры

  • templateUid
    Тип: System.Guid

    Идентификатор GUID шаблона проекта.

  • projectName
    Тип: System.String

    Имя нового проекта.

Возвращаемое значение

Тип: System.Guid
Идентификатор GUID, созданный проект.

Замечания

CreateProjectFromTemplate создает новый проект в таблиц данных черновиков. Текущий пользователь должен иметь оба разрешения, указанные в таблице разрешений.

Метод CreateProjectFromTemplate сохраняются все сведения о форматировании в шаблон проекта, например формата шкала времени или шрифта. Можно задать форматирование данные проекта с помощью Project Professional; форматирование недоступен в открытые методы PSI или наборов данных. CreateProjectFromTemplate возвращает ProjectDataSet из шаблона проекта в базе данных черновиков, создает новый ProjectDataSetи изменяет имя суммарной задачи проекта на запрошенный проекта. Он добавляет все строки DataTable новой ProjectDataSet, за исключением даты назначения и затем создает новый проект с другой код GUID.

Если шаблон содержит задачи, которые заметки, заметок задачи не показывать при создании нового проекта с помощью CreateProjectFromTemplate и затем откройте проект в Microsoft Office Project Professional. Можно использовать Project Professional для создания шаблона, который содержит заметок задачи и опубликовать шаблон проекта. В таблице MSP_TASKS в опубликованной базы данных включает в себя столбец TASK_RTF_NOTES , который содержит данные для шаблона. После создания программным путем и сохраните новый проект на основе этого шаблона, столбец TASK_RTF_NOTES содержит данные текст для заметок задачи, не данные в формате RTF (формат RTF).

Проблема в том, что TASK_RTF_NOTES имеет тип данных image для данные в формате RTF. Веб-службы PSI в приложении-службе Project Server не может обработать данные в формате RTF. Добавление заметки к задачам в проектах, созданных программными средствами на сервере Project Server на основе шаблона, необходимо прямого доступа к таблице MSP_TASKS для выполнения следующих:

  • Добавьте данные в формате RTF в столбце TASK_RTF_NOTES для определенной задачи.

  • Значение в столбце TASKS_HAS_NOTES1 (true).

Примечание

В настоящее время отсутствует метод доступен для программного добавления заметок задачи в шаблоне в проект, созданный на основе этого шаблона.

Интерфейс Project Server (PSI) нельзя использовать для создания локальных настраиваемых полей в проектах. Тем не менее PSI поддерживает редактирование значения локальных настраиваемых полей для задач, ресурсов и назначений.

Параметры представления, такие как добавленных полей, не копируются в новый проект на основе шаблона.

Разрешения Project Server

Разрешение

Описание

NewProject

Позволяет пользователям для создания нового проекта. Глобальное разрешение.

OpenProjectTemplate

Позволяет пользователю открывать шаблоны проектов. Глобальное разрешение.

Примеры

Следующий пример создает шаблон, поиск по имени шаблона и проверяет имя проекта для знаков, которые являются недопустимыми. В примере создается проект на основе этого шаблона и затем публикует проект. Это необходимо для создания шаблона, так как Project Server не имеет любое шаблонов по умолчанию, в которых может быть на месте.

Как правило будет представлен список шаблонов и их уникальные идентификаторы и использовать ее для выберите нужный шаблон. В некоторых случаях может потребоваться найти шаблон проекта или по имени. Показано ниже. Необходимо иметь точное имя проекта, чтобы его найти.

Важные сведения о запуске в этом примере кода Необходимые условия для примеров кода на основе WCF в Project 2013см.

using System;
using System.Text;
using System.Xml;
using System.ServiceModel;
using PSLibrary = Microsoft.Office.Project.Server.Library;

namespace CreateProjectFromTemplate
{
    class Program
    {
        private const string ENDPOINT_PROJECT = "basicHttp_Project";
        private const string ENDPOINT_QUEUESYSTEM = "basicHttp_QueueSystem";
        private static SvcProject.ProjectClient projectClient;
        private static SvcQueueSystem.QueueSystemClient queueSystemClient;

        static void Main(string[] args)
        {
            try
            {
                ConfigClientEndpoints(ENDPOINT_PROJECT);
                ConfigClientEndpoints(ENDPOINT_QUEUESYSTEM);

                // Create a template to use. Normally, you would already have a template 
                // stored in PWA that you would use, but this example creates a template.

                Console.WriteLine("Creating template");
                SvcProject.ProjectDataSet templateDs = new SvcProject.ProjectDataSet();
                SvcProject.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;

                if (IsNameValid(templateRow.PROJ_NAME))
                {
                    templateDs.Project.AddProjectRow(templateRow);
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("\nThe project name contains characters that are not valid:" 
                                      + "\n\t{0}", templateRow.PROJ_NAME);
                    QuitTheApp();
                }

                // Add two tasks to the template.
                int numTasks = 2;
                SvcProject.ProjectDataSet.TaskRow task = null;

                for (int i = 0; i < numTasks; i++)
                {
                    task = templateDs.Task.NewTaskRow();
                    task.PROJ_UID = templateRow.PROJ_UID;
                    task.TASK_UID = Guid.NewGuid();
                    task.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Day;
                    task.TASK_DUR = 4800; // The task duration is 8 hours.
                    task.TASK_NAME = "T" + (i + 1).ToString() + " in template";
                    task.TASK_START_DATE = System.DateTime.Now.AddDays(i + 1);
                    templateDs.Task.AddTaskRow(task);
                }

                // Write the new template information to the database.
                Console.WriteLine("\n\nSaving template to database");
                Guid jobId = Guid.NewGuid();
                DateTime startTime = DateTime.Now;

                projectClient.QueueCreateProject(jobId, templateDs, false);

                // Wait for the Project Server Queuing System to create the project.
                if (Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ProjectCreate,
                    queueSystemClient, startTime))
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("\nTemplate created:\n\t{0}", templateRow.PROJ_NAME);
                    Console.ResetColor();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("\nThe template was not created:\n\t{0}.\nThe queue wait time exceeded 30 seconds",
                        templateRow.PROJ_NAME);
                    Console.ResetColor();
                    QuitTheApp();
                }

                // Find the template by name.
                //    You could just use the GUID to create the project from a template, 
                //    but this example shows how to get the GUID from the template name.
                // Note: If you have a template on the enterprise server already, you can use
                // the ReadProjectStatus method to get a list of published templates.
                //    projectSvc.ReadProjectStatus(Guid.Empty, SvcProject.DataStoreEnum.PublishedStore, 
                //                                 String.Empty, (int) PSLibrary.Project.ProjectType.Template);
                Console.WriteLine("Finding the template by name");
                SvcProject.ProjectDataSet readTemplateDs = projectClient.ReadProjectStatus(Guid.Empty,
                    SvcProject.DataStoreEnum.WorkingStore, templateRow.PROJ_NAME,
                    (int)PSLibrary.Project.ProjectType.Template);

                // Name 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 newProjectUid = projectClient.CreateProjectFromTemplate(readTemplateDs.Project[0].PROJ_UID,
                                                                             projectName);
                Console.ForegroundColor = ConsoleColor.Yellow;
                Console.WriteLine("Project created:\n\t{0}\n\t{1}", newProjectUid.ToString(), projectName);
                Console.ResetColor();

                // Publish the project, to make it visible in PWA.
                jobId = Guid.NewGuid();
                projectClient.QueuePublish(jobId, newProjectUid, true, string.Empty);
                startTime = DateTime.Now;

                if (Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ProjectPublish,
                                         queueSystemClient, startTime))
                {
                    Console.ForegroundColor = ConsoleColor.Yellow;
                    Console.WriteLine("Project published");
                    Console.ResetColor();
                }
                else
                {
                    Console.ForegroundColor = ConsoleColor.Red;
                    Console.WriteLine("\nThe project was not published.\nThe queue wait time exceeded 30 seconds");
                    Console.ResetColor();
                }

            }
            catch (FaultException fault)
            {
                // Use the WCF FaultException, because the ASMX SoapException does not 
                // exist in a WCF-based application.
                WriteFaultOutput(fault);
            }
            finally
            {
                QuitTheApp();
            }
        }

        // Check the project name for invalid characters.
        private static bool IsNameValid(string projName)
        {
            bool result = true;
            char[] badChars = PSLibrary.Project.InvalidCharacters();

            Console.WriteLine("Check project name for Project.InvalidCharacters:");
            Console.ForegroundColor = ConsoleColor.Yellow;
            foreach (char c in badChars)
            {
                Console.Write(c);
                Console.Write(" ");
            }
            Console.ResetColor();

            // The name is not valid if it is empty or contains leading or trailing white space.
            if (String.IsNullOrEmpty(projName) || String.Compare(projName, projName.Trim(), StringComparison.Ordinal) != 0)
            {
                return false;
            }

            // The name is also not valid if it contains one of the invalid characters.
            if (badChars != null)
            {
                if (projName.IndexOfAny(badChars) != -1)
                {
                    return false;
                }
            }
            return result;
        }

        // Extract a PSClientError object from the WCF FaultException object, and
        // then display the exception details and each error in the PSClientError stack.
        private static void WriteFaultOutput(FaultException fault)
        {
            string errAttributeName;
            string errAttribute;
            string errOut;
            string errMess = "".PadRight(30, '=') + "\r\n"
                + "Error details: " + "\r\n";

            PSLibrary.PSClientError error = Helpers.GetPSClientError(fault, out errOut);
            errMess += errOut;

            PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
            PSLibrary.PSErrorInfo thisError;

            for (int i = 0; i < errors.Length; i++)
            {
                thisError = errors[i];
                errMess += "\r\n".PadRight(30, '=') + "\r\nPSClientError output:\r\n";
                errMess += thisError.ErrId.ToString() + "\n";

                for (int j = 0; j < thisError.ErrorAttributes.Length; j++)
                {
                    errAttributeName = thisError.ErrorAttributeNames()[j];
                    errAttribute = thisError.ErrorAttributes[j];
                    errMess += "\r\n\t" + errAttributeName
                        + ": " + errAttribute;
                }
            }
            Console.ForegroundColor = ConsoleColor.Red;
            Console.WriteLine(errMess);
            Console.ResetColor();
        }


        // Use the endpoints defined in app.config to configure the client.
        private static void ConfigClientEndpoints(string endpt)
        {
            if (endpt == ENDPOINT_PROJECT)
                projectClient = new SvcProject.ProjectClient(endpt);
            else if (endpt == ENDPOINT_QUEUESYSTEM)
                queueSystemClient = new SvcQueueSystem.QueueSystemClient(endpt);
        }

        // Quit the application.
        private static void QuitTheApp()
        {
            Console.ResetColor();
            Console.WriteLine("\nPress any key to exit...");
            Console.ReadKey(true);
            Environment.Exit(1);
        }
    }

    // Helper methods: WaitForQueue and GetPSClientError.
    class Helpers
    {
        // Wait for the queue jobs to complete.
        public static bool WaitForQueue(SvcQueueSystem.QueueMsgType jobType,
            SvcQueueSystem.QueueSystemClient queueSystemClient,
            DateTime startTime)
        {
            const int MAX_WAIT = 30;    // Maximum wait time, in seconds.
            int numJobs = 1;            // Number of jobs in the queue.
            bool completed = false;     // Queue job completed.
            SvcQueueSystem.QueueStatusDataSet queueStatusDs =
                new SvcQueueSystem.QueueStatusDataSet();

            int timeout = 0;            // Number of seconds waited.
            Console.Write("Waiting for job: {0} ", jobType.ToString());

            SvcQueueSystem.QueueMsgType[] messageTypes = { jobType };
            SvcQueueSystem.JobState[] jobStates = { SvcQueueSystem.JobState.Success };

            while (timeout < MAX_WAIT)
            {
                System.Threading.Thread.Sleep(1000);    // Sleep one second.

                queueStatusDs = queueSystemClient.ReadMyJobStatus(
                    messageTypes,
                    jobStates,
                    startTime,
                    DateTime.Now,
                    numJobs,
                    true,
                    SvcQueueSystem.SortColumn.QueuePosition,
                    SvcQueueSystem.SortOrder.LastOrder);

                timeout++;
                Console.Write(".");
            }
            Console.WriteLine();

            if (queueStatusDs.Status.Count == numJobs)
                completed = true;
            return completed;
        }

        /// <summary>
        /// Extract a PSClientError object from the ServiceModel.FaultException,
        /// for use in output of the GetPSClientError stack of errors.
        /// </summary>
        /// <param name="e"></param>
        /// <param name="errOut">Shows that FaultException has more information 
        /// about the errors than PSClientError has. FaultException can also contain 
        /// other types of errors, such as failure to connect to the server.</param>
        /// <returns>PSClientError object, for enumerating errors.</returns>
        public static PSLibrary.PSClientError GetPSClientError(FaultException e,
                                                               out string errOut)
        {
            const string PREFIX = "GetPSClientError() returns null: ";
            errOut = string.Empty;
            PSLibrary.PSClientError psClientError = null;

            if (e == null)
            {
                errOut = PREFIX + "Null parameter (FaultException e) passed in.";
                psClientError = null;
            }
            else
            {
                // Get a ServiceModel.MessageFault object.
                var messageFault = e.CreateMessageFault();

                if (messageFault.HasDetail)
                {
                    using (var xmlReader = messageFault.GetReaderAtDetailContents())
                    {
                        var xml = new XmlDocument();
                        xml.Load(xmlReader);

                        var serverExecutionFault = xml["ServerExecutionFault"];
                        if (serverExecutionFault != null)
                        {
                            var exceptionDetails = serverExecutionFault["ExceptionDetails"];
                            if (exceptionDetails != null)
                            {
                                try
                                {
                                    errOut = exceptionDetails.InnerXml + "\r\n";
                                    psClientError =
                                        new PSLibrary.PSClientError(exceptionDetails.InnerXml);
                                }
                                catch (InvalidOperationException ex)
                                {
                                    errOut = PREFIX + "Unable to convert fault exception info ";
                                    errOut += "a valid Project Server error message. Message: \n\t";
                                    errOut += ex.Message;
                                    psClientError = null;
                                }
                            }
                            else
                            {
                                errOut = PREFIX + "The FaultException e is a ServerExecutionFault, "
                                    + "but does not have ExceptionDetails.";
                            }
                        }
                        else
                        {
                            errOut = PREFIX + "The FaultException e is not a ServerExecutionFault.";
                        }
                    }
                }
                else // No detail in the MessageFault.
                {
                    errOut = PREFIX + "The FaultException e does not have any detail.";
                }
            }
            errOut += "\r\n" + e.ToString() + "\r\n";
            return psClientError;
        }
    }
}

При выполнении примера CreateProjectFromTemplate , в окне консоли отображает следующие выходные данные:

Creating template
Check project name for Project.InvalidCharacters:
' # : ; < > / | ? \ . * " ~ % & { } +

Saving template to database
Waiting for job: ProjectCreate ..............................

Template created:
        Its a wonderful template! 3-50 PM
Finding the template by name
Create the new project from the template
Project created:
        b9d0272e-62db-e111-b1ce-00155d146f2c
        Created from Its a wonderful template! 3-50 PM at 3-50 PM
Waiting for job: ProjectPublish ..............................
Project published

Press any key to exit...

Чтобы увидеть действие обработчика FaultException , измените код, имена шаблонов и проверок для недопустимых символов. Следующий код представляет знак «+» в полях имя и комментарии в работе вызов метода IsNameValid :

                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);
                //if (IsNameValid(templateRow.PROJ_NAME))
                //{
                //    templateDs.Project.AddProjectRow(templateRow);
                //}
                //else
                //{
                //    Console.ForegroundColor = ConsoleColor.Red;
                //    Console.WriteLine("\nThe project name contains characters that are not valid:" 
                //                      + "\n\t{0}", templateRow.PROJ_NAME);
                //    QuitTheApp();
                //}

См. также

Справочные материалы

Project класс

Элементы Project

Пространство имен WebSvcProject