Project.QueueCreateProject Method
Creates a project with the specified entities, and checks in the project to the Drafts database.
Namespace: [Project Web service]
Service reference: http://ServerName:32843/[Project Service Application GUID]/PSI/Project.svc
Web service reference: http://ServerName/ProjectServerName/_vti_bin/PSI/Project.asmx?wsdl
Syntax
'Declaration
<SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/QueueCreateProject", 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 Sub QueueCreateProject ( _
jobUid As Guid, _
dataset As ProjectDataSet, _
validateOnly As Boolean _
)
'Usage
Dim instance As Project
Dim jobUid As Guid
Dim dataset As ProjectDataSet
Dim validateOnly As Boolean
instance.QueueCreateProject(jobUid, dataset, _
validateOnly)
[SoapDocumentMethodAttribute("https://schemas.microsoft.com/office/project/server/webservices/Project/QueueCreateProject", 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 void QueueCreateProject(
Guid jobUid,
ProjectDataSet dataset,
bool validateOnly
)
Parameters
- jobUid
Type: System.Guid
The GUID of the queue job.
- dataset
Type: [Project Web service].ProjectDataSet
Contains the project data.
- validateOnly
Type: System.Boolean
If True, only validates the input data and does not perform the action.
Remarks
QueueCreateProject is an asynchronous method that sends a message to the Project Server Queuing Service.
Note
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.
When creating a ProjectDataSet.TaskRow, you must specify TASK_DUR_FMT. Otherwise, later use of this project in Project Professional can result in unpredictable behavior, including possible data loss.
Any changes made to enterprise resource properties in ProjectDataSet.ProjectResourceRow will be lost the next time Project Professional refreshes the data from Project Server.
When you add a task to a ProjectDataSet, do not set the TASK_WBS property. The TASK_WBS property is read-only, although it is marked as read/write in the PSI. If you add a task with the TASK_WBS property set to a specified value, Project Professional ignores the value set from the PSI and assigns a value according to the task outline position when you open the project. To see the result in Project Professional, check the WBS code value on the Advanced tab of the Task Information dialog box.
When you add a project custom field to to ProjectDataSet.ProjectCustomFields table, do not set the value of the MD_PROP_ID property. Project Server automatically adds a value when it creates the project. The CreateProject4Department code example shows the data in the ProjectDataSet before and after the call to QueueCreateProject.
Project Server Permissions
Permission |
Description |
---|---|
Allows a user to create a new project. Global permission. |
|
Allows a user to create and save a project as an enterprise project template. |
Examples
Example for WCF: The CreateProject4Department example does the following:
Builds a basic ProjectDataSet for one new project that has zero or more tasks, plus a row in the ProjectCustomFields table. The project is assigned to a specified department by using the Project Departments custom field that has a value in the Departments lookup table.
After calling QueueCreateProject, waits for the project queue to finish, and then reads the ProjectDataSet back by using ReadProject.
Saves the ProjectDataSet to XML files, before creating the project and after calling ReadProject. Shows that Project Server automatically creates the MD_PROP_ID field for the Project Departments custom field.
Shows how to use the WCF FaultException, to display the error stack. Comments in the PopulateData method show how to create errors in the ProjectDataSet that trigger the System.ServiceModel.FaultException. For example output of the exception handler, see the Code Example for WCF section in Project Server Error Codes.
For information about using the code sample in a Microsoft Visual Studio 2010 project and creating an app.config file for configuration of the WCF endpoints, see Prerequisites for WCF-Based Code Samples.
using System;
using System.Text;
using System.ServiceModel;
using System.Xml;
using PSLibrary = Microsoft.Office.Project.Server.Library;
namespace Microsoft.SDK.Project.Samples.CreateProject4Department
{
class Program
{
private const string ENDPOINT_PROJECT = "basicHttp_Project";
private const string ENDPOINT_QUEUESYSTEM = "basicHttp_QueueSystem";
// Change the output directory for your computer.
private const string OUTPUT_FILES = @"C:\Project\Samples\Output\";
// Change the following GUID to match a value in your Departments
// lookup table. To find the GUID of a value in the Departments lookup table,
// see the MSPLT_Department_UserView view in the Reporting database.
// For example, use the following query:
// SELECT TOP 20 [LookupMemberUID],[MemberValue],[MemberDescription]
// FROM [ProjectServer_Reporting].[dbo].[MSPLT_Department_UserView]
//
// Alternately, use the LookupTable.ReadLookupTablesByUids method and then
// get the GUID of the value you want. The GUID of the built-in Departments
// lookup table is PSLibrary.LookupTables.DEPARTMENTS_LT_UID.
private const string DEPARTMENT_TEST = "E78E047B-1F01-4882-8336-60DF5A727F6D";
private static SvcProject.ProjectClient projectClient;
private static SvcQueueSystem.QueueSystemClient queueSystemClient;
private static string outFilePath1;
private static string outFilePath2;
static void Main(string[] args)
{
Guid sampleProjNameUid = Guid.NewGuid();
string projName = "TestProjDept " + sampleProjNameUid;
int numTasks = 0;
if (args.Length > 0 && args.Length < 5)
{
if (args[0].ToLower() == "-name")
{
projName = args[1];
}
if (args[2].ToLower() == "-tasks")
numTasks = Convert.ToInt32(args[3]);
}
outFilePath1 = OUTPUT_FILES + "ProjectDataSet4Department_before.xml";
outFilePath2 = OUTPUT_FILES + "ProjectDataSet4Department_after.xml";
ConfigClientEndpoints(ENDPOINT_PROJECT);
ConfigClientEndpoints(ENDPOINT_QUEUESYSTEM);
try
{
SvcProject.ProjectDataSet projectDs = new SvcProject.ProjectDataSet();
projectDs = PopulateData(projectDs, projName.Trim(), numTasks);
Console.WriteLine(
"\nXML output of the ProjectDataSet before QueueCreateProject:\n\t{0}",
outFilePath1);
projectDs.WriteXml(outFilePath1);
// Create the project.
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("Creating project: {0}", projName);
Console.ResetColor();
Guid jobUid = Guid.NewGuid();
DateTime startTime = DateTime.Now;
projectClient.QueueCreateProject(jobUid, projectDs, false);
// Wait for the Project Server Queuing System to create the project.
if (Helpers.WaitForQueue(SvcQueueSystem.QueueMsgType.ProjectCreate,
queueSystemClient, startTime))
{
Console.WriteLine(
"\nXML output of the ProjectDataSet after ReadProject:\n\t{0}",
outFilePath2);
Guid projUid = projectDs.Project[0].PROJ_UID;
projectDs = projectClient.ReadProject(projUid,
SvcProject.DataStoreEnum.WorkingStore);
projectDs.WriteXml(outFilePath2);
}
else
{
Console.WriteLine("The project was not created: {0}.\n\tThe queue wait time exceeded 30 seconds.",
projName);
}
}
catch(FaultException fault)
{
// Use the WCF FaultException, because the ASMX SoapException does not
// exist in a WCF-based application.
WriteFaultOutput(fault);
}
Console.Write("\nPress any key to exit... ");
Console.ReadKey(true);
}
// Populate the minimum data necessary for the ProjectDataSet, for the Project
// table and for the ProjectCustomFields table.
private static SvcProject.ProjectDataSet PopulateData(
SvcProject.ProjectDataSet projDs, string name, int numTasks)
{
SvcProject.ProjectDataSet.ProjectRow projRow = projDs.Project.NewProjectRow();
SvcProject.ProjectDataSet.ProjectCustomFieldsRow projCF =
projDs.ProjectCustomFields.NewProjectCustomFieldsRow();
projRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Project;
projRow.PROJ_UID = Guid.NewGuid();
projRow.PROJ_NAME = name;
projDs.Project.AddProjectRow(projRow);
projCF.CUSTOM_FIELD_UID = Guid.NewGuid();
projCF.FIELD_TYPE_ENUM = (byte)PSLibrary.CustomField.Type.TEXT;
projCF.PROJ_UID = projRow.PROJ_UID;
// It is not strictly necessary to set unused values to null;
// however, doing so helps to emphasize that the custom field is not
// one of the following simple types.
projCF.SetNUM_VALUENull();
projCF.SetFLAG_VALUENull();
projCF.SetDUR_VALUENull();
projCF.SetDUR_FMTNull();
projCF.SetDATE_VALUENull();
projCF.SetTEXT_VALUENull();
// To see the InvalidTypeColumnFilledIn exception when calling
// QueueCreateProject, uncomment the following line:
// projCF.TEXT_VALUE = "Marketing";
projCF.MD_PROP_UID = PSLibrary.CustomField.PROJECT_DEPARTMENT_MD_PROP_UID;
Guid lookupTableMemberUid = new Guid(DEPARTMENT_TEST);
// Comment-out the following line, to see an additional
// CustomFieldRequiredValueNotProvided exception.
projCF.CODE_VALUE = lookupTableMemberUid;
projDs.ProjectCustomFields.AddProjectCustomFieldsRow(projCF);
// Add the specified number of tasks.
if (numTasks > 0)
{
SvcProject.ProjectDataSet.TaskRow task = null;
for (int i = 0; i < numTasks; i++)
{
task = projDs.Task.NewTaskRow();
task.PROJ_UID = projRow.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();
task.TASK_START_DATE = System.DateTime.Now.AddDays(i + 1);
projDs.Task.AddTaskRow(task);
}
}
return projDs;
}
// 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.
public static void ConfigClientEndpoints(string endpt)
{
if (endpt == ENDPOINT_PROJECT)
projectClient = new SvcProject.ProjectClient(endpt);
else if (endpt == ENDPOINT_QUEUESYSTEM)
queueSystemClient = new SvcQueueSystem.QueueSystemClient(endpt);
}
}
// 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;
}
}
}
The following command line runs the CreateProject4Department application to create a project with no tasks. The value for the department GUID (the CODE_VALUE property for the custom field) is hard-coded in the application.
CreateProject4Department -name "Proj Dept Test 2"
Following are contents of the ProjectDataSet4Department_before.xml file, which the CreateProject4Department application saves before calling QueueCreateProject.
<?xml version="1.0" standalone="yes"?>
<ProjectDataSet xmlns="https://schemas.microsoft.com/office/project/server/webservices/ProjectDataSet/">
<Project>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<PROJ_NAME>Proj Dept Test 2</PROJ_NAME>
<PROJ_TYPE>0</PROJ_TYPE>
</Project>
<ProjectCustomFields>
<CUSTOM_FIELD_UID>4802a711-62a0-4f84-8e08-c7d22daadb5b</CUSTOM_FIELD_UID>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<MD_PROP_UID>9d77d62a-a92e-4d40-adc8-446c90eb7456</MD_PROP_UID>
<FIELD_TYPE_ENUM>21</FIELD_TYPE_ENUM>
<CODE_VALUE>a47930d6-b89d-4f3a-b4e3-522015fe82a1</CODE_VALUE>
</ProjectCustomFields>
</ProjectDataSet>
Following are contents of the ProjectDataSet4Department_after.xml file, which the CreateProject4Department application saves after calling ReadProject. Project Server populates many additional fields with default values, including the MD_PROP_ID field in the ProjectCustomFields table.
<?xml version="1.0" standalone="yes"?>
<ProjectDataSet xmlns="https://schemas.microsoft.com/office/project/server/webservices/ProjectDataSet/">
<Project>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<PROJ_NAME>Proj Dept Test 2</PROJ_NAME>
<PROJ_TYPE>0</PROJ_TYPE>
<PROJ_PROP_AUTHOR>REDMOND\jcorbin</PROJ_PROP_AUTHOR>
<CAL_UID>b6635b2e-e747-4771-a78b-24f7509629d0</CAL_UID>
<CAL_NAME>Standard</CAL_NAME>
<PROJ_PROP_TITLE>Proj Dept Test 2</PROJ_PROP_TITLE>
<PROJ_OPT_CALC_ACT_COSTS>false</PROJ_OPT_CALC_ACT_COSTS>
<PROJ_OPT_CRITICAL_SLACK_LIMIT>0</PROJ_OPT_CRITICAL_SLACK_LIMIT>
<PROJ_OPT_CURRENCY_DIGITS>2</PROJ_OPT_CURRENCY_DIGITS>
<PROJ_OPT_CURRENCY_POSITION>0</PROJ_OPT_CURRENCY_POSITION>
<PROJ_OPT_CURRENCY_SYMBOL>$</PROJ_OPT_CURRENCY_SYMBOL>
<PROJ_OPT_CURRENCY_CODE>USD</PROJ_OPT_CURRENCY_CODE>
<PROJ_OPT_NEW_TASKS_ARE_EFFORT_DRIVEN>false</PROJ_OPT_NEW_TASKS_ARE_EFFORT_DRIVEN>
<PROJ_INFO_CURRENT_DATE>2010-06-21T08:00:00-07:00</PROJ_INFO_CURRENT_DATE>
<PROJ_OPT_DEF_FINISH_TIME>2010-06-21T17:00:00-07:00</PROJ_OPT_DEF_FINISH_TIME>
<PROJ_OPT_DEF_FIX_COST_ACCRUAL>3</PROJ_OPT_DEF_FIX_COST_ACCRUAL>
<PROJ_OPT_DEF_OVT_RATE>0</PROJ_OPT_DEF_OVT_RATE>
<PROJ_OPT_DEF_STD_RATE>0</PROJ_OPT_DEF_STD_RATE>
<PROJ_OPT_DEF_START_TIME>2010-06-21T08:00:00-07:00</PROJ_OPT_DEF_START_TIME>
<PROJ_OPT_DEF_TASK_TYPE>0</PROJ_OPT_DEF_TASK_TYPE>
<WPROJ_TRACKING_METHOD>0</WPROJ_TRACKING_METHOD>
<PROJ_OPT_DUR_ENTRY_FMT>7</PROJ_OPT_DUR_ENTRY_FMT>
<PROJ_INFO_FINISH_DATE>2010-06-21T08:00:00-07:00</PROJ_INFO_FINISH_DATE>
<PROJ_OPT_HONOR_CONSTRAINTS>true</PROJ_OPT_HONOR_CONSTRAINTS>
<PROJ_OPT_MULT_CRITICAL_PATHS>false</PROJ_OPT_MULT_CRITICAL_PATHS>
<PROJ_INFO_SCHED_FROM>true</PROJ_INFO_SCHED_FROM>
<PROJ_OPT_SPLIT_IN_PROGRESS>true</PROJ_OPT_SPLIT_IN_PROGRESS>
<PROJ_OPT_SPREAD_ACT_COSTS>false</PROJ_OPT_SPREAD_ACT_COSTS>
<PROJ_OPT_SPREAD_PCT_COMP>false</PROJ_OPT_SPREAD_PCT_COMP>
<PROJ_INFO_START_DATE>2010-06-21T08:00:00-07:00</PROJ_INFO_START_DATE>
<PROJ_INFO_STATUS_DATE>2010-06-21T08:00:00-07:00</PROJ_INFO_STATUS_DATE>
<PROJ_OPT_TASK_UPDATES_RES>true</PROJ_OPT_TASK_UPDATES_RES>
<PROJ_OPT_WORK_ENTRY_FMT>2</PROJ_OPT_WORK_ENTRY_FMT>
<PROJ_OPT_NEW_TASK_EST>true</PROJ_OPT_NEW_TASK_EST>
<PROJ_PROTECTED_ACTUALS_SYNCH>false</PROJ_PROTECTED_ACTUALS_SYNCH>
<PROJ_OPT_FY_START_MONTH>1</PROJ_OPT_FY_START_MONTH>
<PROJ_OPT_FY_USE_START_YR>false</PROJ_OPT_FY_USE_START_YR>
<PROJ_OPT_MINUTES_PER_DAY>480</PROJ_OPT_MINUTES_PER_DAY>
<PROJ_OPT_MINUTES_PER_WEEK>2400</PROJ_OPT_MINUTES_PER_WEEK>
<PROJ_OPT_DAYS_PER_MONTH>20</PROJ_OPT_DAYS_PER_MONTH>
<PROJ_OPT_MOVE_ACTUAL_IF_LATER>false</PROJ_OPT_MOVE_ACTUAL_IF_LATER>
<PROJ_OPT_MOVE_ACTUAL_TO_STATUS>false</PROJ_OPT_MOVE_ACTUAL_TO_STATUS>
<PROJ_OPT_MOVE_REMAINING_IF_EARLIER>false</PROJ_OPT_MOVE_REMAINING_IF_EARLIER>
<PROJ_OPT_MOVE_REMAINING_TO_STATUS>false</PROJ_OPT_MOVE_REMAINING_TO_STATUS>
<PROJ_OPT_SHOW_EST_DUR>true</PROJ_OPT_SHOW_EST_DUR>
<PROJ_OPT_WEEK_START_DAY>0</PROJ_OPT_WEEK_START_DAY>
<ProjectOwnerID>a91826f2-e125-4b85-b59e-0bebbca19208</ProjectOwnerID>
<PROJ_STALE_FLAGS>3</PROJ_STALE_FLAGS>
<PROJ_LAST_SAVED>2010-06-21T14:58:41.01-07:00</PROJ_LAST_SAVED>
<CREATED_DATE>2010-06-21T14:58:39.89-07:00</CREATED_DATE>
<ENTERPRISE_PROJECT_TYPE_UID>09fa52b4-059b-4527-926e-99f9be96437a</ENTERPRISE_PROJECT_TYPE_UID>
<ENTERPRISE_PROJECT_TYPE_NAME>Basic Project Plan</ENTERPRISE_PROJECT_TYPE_NAME>
<PROJ_NEW_TASKS_ARE_MANUAL>true</PROJ_NEW_TASKS_ARE_MANUAL>
<PROJ_WINPROJ_VERSION_NUMBER>14.0000000000</PROJ_WINPROJ_VERSION_NUMBER>
</Project>
<Task>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<TASK_UID>efcca348-2057-4ec7-9e21-13e073fade66</TASK_UID>
<TASK_PARENT_UID>efcca348-2057-4ec7-9e21-13e073fade66</TASK_PARENT_UID>
<TASK_NAME>Proj Dept Test 2</TASK_NAME>
<TASK_ID>0</TASK_ID>
<TASK_IS_MILESTONE>false</TASK_IS_MILESTONE>
<TASK_IS_SUMMARY>true</TASK_IS_SUMMARY>
<TASK_IS_MARKED>false</TASK_IS_MARKED>
<TASK_IGNORES_RES_CAL>false</TASK_IGNORES_RES_CAL>
<TASK_IS_EFFORT_DRIVEN>false</TASK_IS_EFFORT_DRIVEN>
<TASK_IS_CRITICAL>true</TASK_IS_CRITICAL>
<TASK_IS_EXTERNAL>false</TASK_IS_EXTERNAL>
<TASK_IS_FROM_FINISH_SUBPROJ>false</TASK_IS_FROM_FINISH_SUBPROJ>
<TASK_IS_OVERALLOCATED>false</TASK_IS_OVERALLOCATED>
<TASK_IS_RECURRING>false</TASK_IS_RECURRING>
<TASK_IS_RECURRING_SUMMARY>false</TASK_IS_RECURRING_SUMMARY>
<TASK_IS_SUBPROJ>false</TASK_IS_SUBPROJ>
<TASK_IS_READONLY_SUBPROJ>false</TASK_IS_READONLY_SUBPROJ>
<TASK_LOCKDOWN_BY_MANAGER>false</TASK_LOCKDOWN_BY_MANAGER>
<TASK_LEVELING_DELAY>0</TASK_LEVELING_DELAY>
<TASK_LEVELING_DELAY_FMT>8</TASK_LEVELING_DELAY_FMT>
<TASK_LEVELING_CAN_SPLIT>true</TASK_LEVELING_CAN_SPLIT>
<TASK_LEVELING_ADJUSTS_ASSN>true</TASK_LEVELING_ADJUSTS_ASSN>
<TASK_DUR_IS_EST>false</TASK_DUR_IS_EST>
<TASK_DUR>0</TASK_DUR>
<TASK_DUR_FMT>53</TASK_DUR_FMT>
<TASK_DUR_VAR>0</TASK_DUR_VAR>
<TASK_EAC>0</TASK_EAC>
<TASK_VAC>0</TASK_VAC>
<TASK_ACT_DUR>0</TASK_ACT_DUR>
<TASK_REM_DUR>0</TASK_REM_DUR>
<TASK_CONSTRAINT_TYPE>0</TASK_CONSTRAINT_TYPE>
<TASK_PRIORITY>500</TASK_PRIORITY>
<TASK_PCT_COMP>0</TASK_PCT_COMP>
<TASK_PCT_WORK_COMP>0</TASK_PCT_WORK_COMP>
<TASK_TYPE>1</TASK_TYPE>
<TASK_FIXED_COST_ACCRUAL>3</TASK_FIXED_COST_ACCRUAL>
<TASK_WORK>0</TASK_WORK>
<TASK_OVT_WORK>0</TASK_OVT_WORK>
<TASK_REG_WORK>0</TASK_REG_WORK>
<TASK_ACT_WORK>0</TASK_ACT_WORK>
<TASK_ACT_OVT_WORK>0</TASK_ACT_OVT_WORK>
<TASK_REM_WORK>0</TASK_REM_WORK>
<TASK_REM_OVT_WORK>0</TASK_REM_OVT_WORK>
<TASK_COST>0</TASK_COST>
<TASK_OVT_COST>0</TASK_OVT_COST>
<TASK_FIXED_COST>0</TASK_FIXED_COST>
<TASK_ACT_COST>0</TASK_ACT_COST>
<TASK_ACT_OVT_COST>0</TASK_ACT_OVT_COST>
<TASK_REM_COST>0</TASK_REM_COST>
<TASK_REM_OVT_COST>0</TASK_REM_OVT_COST>
<TASK_OUTLINE_LEVEL>0</TASK_OUTLINE_LEVEL>
<TASK_OUTLINE_NUM />
<TASK_START_DATE>2010-06-21T08:00:00-07:00</TASK_START_DATE>
<TASK_START_VAR>0</TASK_START_VAR>
<TASK_FINISH_DATE>2010-06-21T08:00:00-07:00</TASK_FINISH_DATE>
<TASK_FINISH_VAR>0</TASK_FINISH_VAR>
<TASK_EARLY_START>2010-06-21T08:00:00-07:00</TASK_EARLY_START>
<TASK_EARLY_FINISH>2010-06-21T08:00:00-07:00</TASK_EARLY_FINISH>
<TASK_LATE_START>2010-06-21T08:00:00-07:00</TASK_LATE_START>
<TASK_LATE_FINISH>2010-06-21T08:00:00-07:00</TASK_LATE_FINISH>
<TASK_BCWS>0</TASK_BCWS>
<TASK_BCWP>0</TASK_BCWP>
<TASK_ACWP>0</TASK_ACWP>
<TASK_FREE_SLACK>0</TASK_FREE_SLACK>
<TASK_TOTAL_SLACK>0</TASK_TOTAL_SLACK>
<TASK_HAS_LINKED_FIELDS>false</TASK_HAS_LINKED_FIELDS>
<CREATED_DATE>2010-06-21T14:58:39.987-07:00</CREATED_DATE>
<MOD_DATE>2010-06-21T14:58:40.807-07:00</MOD_DATE>
<TASK_BUDGET_COST>0</TASK_BUDGET_COST>
<TASK_IS_NULL>false</TASK_IS_NULL>
<TASK_BUDGET_WORK>0</TASK_BUDGET_WORK>
<TASK_COST_VAR>0</TASK_COST_VAR>
<TASK_CPI>0</TASK_CPI>
<TASK_CV>0</TASK_CV>
<TASK_START_SLACK>0</TASK_START_SLACK>
<TASK_FINISH_SLACK>0</TASK_FINISH_SLACK>
<TASK_IS_ROLLED_UP>false</TASK_IS_ROLLED_UP>
<TASK_SV>0</TASK_SV>
<TASK_TCPI>0</TASK_TCPI>
<TASK_WORK_VAR>0</TASK_WORK_VAR>
<TASK_COMPLETE_THROUGH>2010-06-21T08:00:00-07:00</TASK_COMPLETE_THROUGH>
<TASK_IS_MANUAL>false</TASK_IS_MANUAL>
<TASK_IS_ACTIVE>true</TASK_IS_ACTIVE>
<TASK_IS_DISPSUMMARY>false</TASK_IS_DISPSUMMARY>
<TASK_SCHED_START>2010-06-21T08:00:00-07:00</TASK_SCHED_START>
<TASK_SCHED_FINISH>2010-06-21T08:00:00-07:00</TASK_SCHED_FINISH>
<TASK_SCHED_DUR>0</TASK_SCHED_DUR>
<TASK_SCHED_DUR_FMT>53</TASK_SCHED_DUR_FMT>
</Task>
<ProjectCustomFields>
<CUSTOM_FIELD_UID>4802a711-62a0-4f84-8e08-c7d22daadb5b</CUSTOM_FIELD_UID>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<MD_PROP_UID>9d77d62a-a92e-4d40-adc8-446c90eb7456</MD_PROP_UID>
<MD_PROP_ID>190873600</MD_PROP_ID>
<FIELD_TYPE_ENUM>21</FIELD_TYPE_ENUM>
<CODE_VALUE>a47930d6-b89d-4f3a-b4e3-522015fe82a1</CODE_VALUE>
</ProjectCustomFields>
<ProjectResourceCustomFields>
<CUSTOM_FIELD_UID>ba309fe8-2a23-440c-9e48-bce9dd001845</CUSTOM_FIELD_UID>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<RES_UID>a0cb8b7e-2a8c-436d-0000-0000000000ff</RES_UID>
<MD_PROP_UID>d5799183-1107-4ffa-95c1-26d5dfe2cd79</MD_PROP_UID>
<MD_PROP_ID>205553667</MD_PROP_ID>
<FIELD_TYPE_ENUM>21</FIELD_TYPE_ENUM>
<TEXT_VALUE> calendar</TEXT_VALUE>
</ProjectResourceCustomFields>
<ProjectResourceCustomFields>
<CUSTOM_FIELD_UID>45bf1b3d-a695-49c9-8481-8dc2e1220c34</CUSTOM_FIELD_UID>
<PROJ_UID>e1c2d38b-1529-4128-b707-42a94045e55b</PROJ_UID>
<RES_UID>a0cb8b7e-2a8c-436d-0000-0000000000ff</RES_UID>
<MD_PROP_UID>09c05c93-c582-4dd9-8c44-ae9cd2471603</MD_PROP_UID>
<MD_PROP_ID>205553668</MD_PROP_ID>
<FIELD_TYPE_ENUM>21</FIELD_TYPE_ENUM>
<TEXT_VALUE>Cost center: </TEXT_VALUE>
</ProjectResourceCustomFields>
</ProjectDataSet>
Example for ASMX: The following example creates a project, adds some tasks to it, and then saves the project to the server.
For information about running the code sample, see Prerequisites for ASMX-Based Code Samples.
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.QueueCreateProject
{
class Program
{
[STAThread]
static void Main(string[] args)
{
try
{
const string PROJECT_SERVER_URI = "https://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.Credentials = CredentialCache.DefaultCredentials;
QueueSystemWebSvc.QueueSystem q = new QueueSystemWebSvc.QueueSystem();
q.Url = PROJECT_SERVER_URI + QUEUESYSTEM_SERVICE_PATH;
q.UseDefaultCredentials = true;
// Create a sample project.
Console.WriteLine("Creating project data");
projectDs = new ProjectWebSvc.ProjectDataSet();
// Create the project.
ProjectWebSvc.ProjectDataSet.ProjectRow projectRow = projectDs.Project.NewProjectRow();
projectRow.PROJ_UID = Guid.NewGuid();
projectRow.PROJ_NAME = "Its a wonderful project at " +
DateTime.Now.ToShortDateString().Replace("/", "") + " " +
DateTime.Now.ToShortTimeString().Replace(":", "");
projectRow.PROJ_TYPE = (int)PSLibrary.Project.ProjectType.Project;
projectDs.Project.AddProjectRow(projectRow);
// Add some tasks.
ProjectWebSvc.ProjectDataSet.TaskRow taskOne = projectDs.Task.NewTaskRow();
taskOne.PROJ_UID = projectRow.PROJ_UID;
taskOne.TASK_UID = Guid.NewGuid();
// The Task Duration format must be specified.
taskOne.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Day;
taskOne.TASK_DUR = 4800; // 8 hours in duration units (minute/10)taskOne.TASK_NAME = "Task One";
taskOne.TASK_START_DATE = System.DateTime.Now.AddDays(1);
projectDs.Task.AddTaskRow(taskOne);
ProjectWebSvc.ProjectDataSet.TaskRow taskTwo = projectDs.Task.NewTaskRow();
taskTwo.PROJ_UID = projectRow.PROJ_UID;
taskTwo.TASK_UID = Guid.NewGuid();
// The Task Duration format must be specified.
taskTwo.TASK_DUR_FMT = (int)PSLibrary.Task.DurationFormat.Day;
taskTwo.TASK_DUR = 4800; // 8 hours in duration units (minute/10)
taskTwo.TASK_NAME = "Task Two";
taskTwo.TASK_START_DATE = System.DateTime.Now.AddDays(1);
projectDs.Task.AddTaskRow(taskTwo);
// Save the project to the database.
Console.WriteLine("Saving project data to the server");
jobId = Guid.NewGuid();
projectSvc.QueueCreateProject(jobId, projectDs, false);
WaitForQueue(q, jobId);
}
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 finished.
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);
}
}
}