Freigeben über


Project.CreateProjectFromTemplate-Methode

Erstellt ein Projekt aus einer angegebenen Vorlage. Das neue Projekt hat den angegebenen Projektnamen.

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

Syntax

'Declaration
<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
'Usage
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
)

Parameter

  • templateUid
    Typ: System.Guid

    Die GUID der Projektvorlage.

Rückgabewert

Typ: System.Guid
Die GUID des Projekts erstellt.

Hinweise

CreateProjectFromTemplate erstellt das neue Projekt in den Entwurf Datentabellen. Der aktuelle Benutzer muss sowohl der Berechtigungen in der Tabelle Berechtigungen angegeben haben.

Die CreateProjectFromTemplate -Methode keine Formatierung Informationen in einer Projektvorlage für, wie Zeitskala oder der Schriftart beibehalten werden. Sie können die Informationen für ein Projekt mit Project Professional Formatierung festlegen. Formatierung ist nicht in der öffentlichen PSI-Methoden oder Datasets verfügbar. CreateProjectFromTemplate dient zum Abrufen einer ProjectDataSet aus der Projektvorlage in die Entwurfsdatenbank, erstellt eine neue ProjectDataSetund den Sammelvorgang Projektnamen in den angeforderten Projektnamen geändert. Alle Zeilen DataTable klicken Sie dann die neue ProjectDataSet, mit Ausnahme von Zuordnungsdaten, hinzugefügt, und klicken Sie dann mit einer anderen GUID erstellt ein neues Projekt.

Wenn die Vorlage Aufgaben, von denen Notizen enthält, Vorgangsnotizen keine wird angezeigt, wenn Sie ein neues Projekt mithilfe von CreateProjectFromTemplate erstellen und öffnen Sie das Projekt in Microsoft Office Project Professional. Sie können Project Professional verwenden, um eine Vorlage zu erstellen, die Vorgangsnotizen enthält, und veröffentlichen Sie die Projektvorlage. Die MSP_TASKS -Tabelle in der veröffentlichten Datenbank enthält die TASK_RTF_NOTES -Spalte, die Daten für die Vorlage enthält. Nachdem Sie programmgesteuert erstellen und speichern ein neues Projekts basierend auf dieser Vorlage, enthält die TASK_RTF_NOTES Spalte Textdaten für die Vorgangsnotizen, nicht RTF (Rich Text Format)-Daten.

Das Problem ist, dass diese TASK_RTF_NOTES Daten Typ image für RTF-Daten ist. Die PSI-Webdienste in der Project Server-Dienstanwendung können nicht RTF-Daten behandeln. Zum Hinzufügen von Vorgangsnotizen in Projekten, die aus einer Vorlage programmgesteuert in Project Server erstellt werden, müssen Sie direkt in der Tabelle MSP_TASKS die folgenden Aufgaben zugreifen:

  • Fügen Sie die RTF-Daten in die Spalte TASK_RTF_NOTES für eine bestimmte Aufgabe.

  • Legen Sie die TASKS_HAS_NOTES -Spalte auf 1 (true).

Hinweis

Derzeit steht keine-Methode programmgesteuert Vorgangsnotizen ein Projekt aus dieser Vorlage erstellt in einer Vorlage hinzufügen.

Sie können nicht die Project Server Interface (PSI) verwenden, um lokale benutzerdefinierte Felder in Projekten erstellen. Die PSI unterstützt jedoch Werte für lokale benutzerdefinierte Felder auf Aufgaben, Ressourcen und Zuordnungen bearbeiten.

Einstellungen für die Ansicht, wie etwa hinzugefügte Felder werden nicht aus der Vorlage in das neue Projekt kopiert.

Project Server-Berechtigungen

Berechtigung

Beschreibung

NewProject

Ermöglicht einem Benutzer das Erstellen eines neuen Projekts. Die globale Berechtigung.

OpenProjectTemplate

Ermöglicht einem Benutzer das Projektvorlagen zu öffnen. Die globale Berechtigung.

Beispiele

Im folgende Beispiel wird eine Vorlage erstellt, sucht die Vorlage nach Namen und überprüft den Projektnamen für Zeichen, die nicht gültig sind. Im Beispiel wird ein Projekt basierend auf dieser Vorlage erstellt, und klicken Sie dann das Projekt veröffentlicht. Es ist erforderlich, eine Vorlage zu erstellen, da es sich bei Project Server keine Standardvorlagen verfügt, die garantiert erfüllt sind.

In der Regel würden Sie präsentieren eine Liste der Vorlagen und die eindeutigen IDs und verwenden, um die gewünschte Vorlage auswählen. In einigen Fällen können Sie einem Projekt oder einer Vorlage nach Namen suchen möchten. Ist hier gezeigt. Sie benötigen den genauen Namen des Projekts, um sie zu finden sind.

Wichtige Informationen zum Ausführen dieses Codebeispiel finden Sie unter Prerequisites for WCF-based code samples in 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;
        }
    }
}

Wenn Sie das Beispiel CreateProjectFromTemplate ausführen, wird im Konsolenfenster die folgende Ausgabe:

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...

Um die Aktion des Handlers FaultException angezeigt wird, ändern Sie den Code, der die Vorlage und Überprüfungen für ungültige Zeichen benennt. Einführung in das '+'-Zeichen im Namen ein, und Kommentare, den Anruf an die IsNameValid -Methode der folgende Code:

                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();
                //}

Siehe auch

Referenz

Project Klasse

Project-Member

WebSvcProject-Namespace