Cascade Skyline - with Microsoft Logo and Project Support header - author Brian Smith

  • Brian Smith's Microsoft Project Support Blog

    Waiting for Resources? - What happens when you provision a new Project Web Access site

    • 46 Comments

    One problem I have seen a few times is the Project Web Access site provisioning running into issues.  If it fails completely then the error messages are pretty good - and you can generally resolve the issue and re-try and everything will be good.  However, what do you do when it just sits on "Waiting for Resources" and nothing happens?  The quick answer is that this relies on the SharePoint Timer Service and a couple of Shared Service Provider services that can be viewed through Timer Job Definitions (Shared Services Timer Job and Project Server Synchronizing Job for 'SharedServices1' - or whatever yours is called).  If these are not running then you will be "Waiting for resources" for a very long time!  Also there could be multiple versions of the timer jobs if you have multiple SSPs so it can get confusing, particularly as the first one does not differentiate by name.  (Clue - the JobId in the URL for the job is the Id of the timer job row in the Objects table in SharePoint_Config database, and the Properties column from this row will lead you to the Guid of the TargetSharedResourceProvider - which will be the Id of the Shared Services Provider also in the same table.)

    So to dig a little deeper so you can understand where it might be stuck I'll explain what is going on in the background which hopefully will help you find what is stopping it from working.

    So, step 1 - you have been on the Create a Project Web Access Site page (CreatePWA.aspx) and entered all the details, and it goes back to the Manage Project Web Access Sites (ManagePWA.aspx) page and just sits there.  At that point a row has been added to the MIPScheduledJob table in the SharedService1_DB (your database name may vary - this is the default).  This is a pre-synchronizing job for the site, and is added to the database by the account running the Shared Services Provider application pool.

    Step 2.  The Shared Service Timer Job picks up the row from this database table and adds a row to the SharePoint_Config database Objects table.  In the properties field of this table is some XML describing the site to be built, database names etc.  This timer job will run as the account of the farm administrator (i.e. the account running the OWSTIMER service)

    Step 3.  The Project Server Synchronizing Job for 'SharedServices1' sees this row and actions it by creating the site, creating the database and then configuring the instance of PWA.  If everything is working you see the status change on the ManagePWA page as these different stages are processed, and finally it will say Provisioned!  Again, this timer service runs as the farm administrator.

    Waiting for resources will be seen until the early stages of step 3.

    So check all your services are running and your timer jobs are present and enabled and all should be good.  One other workaround that generally gets things moving again is to create  a new Shared Services Provider - which will then create new timer jobs and overcome any underlying issues.  The web applications can then be associated with the new SSP, the new SSP can be made the default if you are not using the old one for anything else, and the old one could be deleted.

    I mention the databases here on the condition that you can look - but don't touch! 

    Technorati Tags: Project Server 2007

  • Brian Smith's Microsoft Project Support Blog

    Yet another OLAP error message - the longest yet!

    • 13 Comments

    Just when I thought I'd seen nearly all of the error messages possible when building a cube along comes another one.  And the longest yet!  I won't bore you all with the full error message but the key piece is:-

    • Error="Analysis Services session failed with the following error: Failed to process the Analysis Services database OLAPCube on the SQLServername server. Error: OLE DB error: OLE DB or ODBC error: [DBNETLIB][ConnectionOpen (Connect()).]SQL Server does not exist or access denied.; 08001.
Errors in the high-level relational engine. A connection could not be made to the data source with the DataSourceID of 'Project Reporting data source', Name of 'Project Reporting data source'.
Errors in the OLAP storage engine: An error occurred while the dimension, with the ID of 'EPMPilotMicron', Name of 'Task Is Milestone' was being processed.

    and so it goes on for another 3 or 4 pages...

    The reason this happened was that the customer has the Project Server databases on a named instance of SQL - lets call this "server1\PS2007".  When provisioning the PWA site from their application server they used an alias for the instance - lets call this "SQLServername".  Now when they ask for a cube build the servername that gets passed over to Analysis Services for use when connecting back to the Reporting database is SQLServername (and not the server1\PS2007).  But the Analysis Serices server does not have the alias set - so does not recognize SQLServername - hence the error.  Resolution is reasonably straightforward - just make the alias available to the Analysis Services machine and all is good!

    *** Update *** For a slight variation on this regarding 32 and 64 bit aliases - see http://blogs.msdn.com/brismith/archive/2009/10/08/project-server-2007-another-olap-cube-building-gotcha-is-your-alias-32-or-64-bit.aspx

     

    Technorati Tags: Project Server 2007

  • Brian Smith's Microsoft Project Support Blog

    Project Conference - What do you want to hear about Administration?

    • 9 Comments

    I have been asked to present a session at the Project Conference titled "Administration of an EPM Solution" and wanted to check that I would be addressing the right issues. 

    The session will cover administrative functions both in Windows SharePoint Services and Project Server.  The SharePoint 3.0 Central Administration features of Diagnostic Logging, Shared Services (including provisioning new PWA sites), Timer jobs, Backup/Restore and administrative account management will be covered.  In Project Server I will be looking at the administrative side of Cube Building, Custom Fields, Active Directory Synchronization, User Management, Administrative Backup/Restore,  Project Workspaces and last and definitely not least Queue Management.  The focus will mainly be on new and changed administrative features of Project Server 2007 so not too much time will be spent on features that have changed little since 2003.  This session will also not be covering the administration of Project Portfolio Server.

    Am I missing anything?

    Technorati Tags: Project Server 2007

  • Brian Smith's Microsoft Project Support Blog

    When are server-side events supposed to fire?

    • 14 Comments

    We have had a few questions on events, and the fact that sometimes, or more correctly, in some circumstances, they don't fire.  So if you are using the PSI to make things happen then all should work and usually the description gives you a good idea when they will fire.  However, you might also expect that doing a similar thing through Project Professional or Project Web Access will fire the same event.  In many cases this is true - a publish is a publish is a publish and wherever you publish a project from will fire the "publish" events.  However in saving from Project Professional after deleting some entity in the project you will not see the "EntitiesDeleted" event fire - that would get triggered by a PSI action doing the same thing.  Project Professional and PWA make use of the same PSI web services in many cases, but also have a private winproj web service  and pwa web service.  It is when using these "private" web services that event behavior may be different. 

    Give us feedback if you are missing some events that as an ISV would make your integration to Project Server easier. 

    The SDK should be going through another revision later this month and we will be updating the event area to give a little more information..

    Technorati Tags: Project Server 2007

  • Brian Smith's Microsoft Project Support Blog

    Creating Issues and Linking to Tasks. Better than task notes?

    • 6 Comments

    There are some limitations with the task notes field and the PSI which are discussed elsewhere on the blogs with a potential workaround of using VBA to access the RTF information.

    Another workaround you might consider is to use SharePoint and the Project Workspaces and instead of having a task note use the issues or risks lists or document library associated with the project.

    In the attached sample I have modified the LoginDemo sample with an additional button that creates a new issue list item in the project workspace. If you don't create a workspace - or click the button before the workspace has been created by the queue then you will discover how much error handling I have coded in (none!). As well as creating an issue I have modified the project creation piece to also create a task in the project - and then finally I create a link between the new issue and this single task using the PSI ObjectLinkProvider web service. I've included the code below in the posting for the main part of the application which is the only .cs file I manually changed from the original LoginDemo. I've commented my changes so you can either make just the mods or use the attached zip of the full modified LoginDemo. If you just modify then note you will also need a reference to Microsoft.SharePoint and a web reference to the Object Link Provider web service.

    Once you have a link then this is visible in the Project Center view both at the task level - you could also link at the project level. The extra bonuses of using a WSS list include alerts, RSS feed and the ability to attach other files - and if you really want to get clever then you can implement some of the WSS workflow on the inserted issue. Much better than tasks notes! One possible extension of this could the the inclusion of content in a workspace template and then linking up the documents to projects/tasks based on an event.

    using System;
    using System.Data;
    using System.Drawing;
    using System.Net;
    using System.Text;
    using System.Windows.Forms;
    using System.Web;
    using System.Web.Services.Protocols;
    using System.Threading;
    using Microsoft.SharePoint;
    using PSLibrary = Microsoft.Office.Project.Server.Library;
    
    /* NOTE: 
     * Delete the Admin, LoginForms, LoginWindows, and Project Web References, and 
     * re-add them for your own Project Server. Use the following URLs 
     * (substitute your values for ServerName and ProjectServerName):
     *
     *   http://ServerName/ProjectServerName/_vti_bin/psi/admin.asmx
     *   http://ServerName/ProjectServerName/_vti_bin/psi/project.asmx
     *   http://ServerName/ProjectServerName/_vti_bin/psi/LoginForms.asmx
     *   http://ServerName/ProjectServerName/_vti_bin/psi/loginwindows.asmx
     */
    
    /* NOTE:
     * For the Object Link Provider example you need to add a reference and using statement for Microsoft.SharePoint 
     * and a Web Reference for the PSI Object Link Provider web service and
     */
    
    namespace LoginDemo
    {
        public partial class LogonProjectServer : Form
        {
            private const string URLPREFIX = "http://";
            private const string PROJECTWEBSERVICE = "_vti_bin/PSI/Project.asmx";
            private const string ADMINWEBSERVICE = "_vti_bin/PSI/Admin.asmx";
            // Constant for Object Link Provider URL
            private const string OLPWEBSERVICE = "_vti_bin/PSI/ObjectLinkProvider.asmx";
            private string baseUrl; // Example: http://ServerName/ProjectServerName/
            private string userName;
            private string password;
            private bool winLogon = true;
            private bool containsUrl = false;
            private bool loggedOn = false;
            private string serverName;
            // Extra definitions for OLP
            private PSLibrary.WebObjectType webObjectType;
            private string linkedItems; 
    
            public static LoginDemo.WebSvcProject.Project project = 
                new LoginDemo.WebSvcProject.Project();
            public static WebSvcAdmin.Admin admin =
                new LoginDemo.WebSvcAdmin.Admin();
            // Added for Object Link Provider
            public static LoginDemo.WebSvcObjectLinkProvider.ObjectLinkProvider objectLinkProvider = 
                new LoginDemo.WebSvcObjectLinkProvider.ObjectLinkProvider();
    
    
            private static LoginUtils loginUtils = new LoginUtils();
            private static AdminUtils adminUtils = new AdminUtils();
            // Defined here so they can be used in the OLP section
            private Guid projectGuid;
            private Guid taskGuid;
            
    
            public LogonProjectServer()
            {
                InitializeComponent();
                lblUserName.Enabled = false;
                lblPassword.Enabled = false;
                txtUserName.Enabled = false;
                txtPassword.Enabled = false;
                radFormsAuthentication.Enabled = false;
                radWindowsAuthentication.Enabled = false;
                btnLogon.Enabled = false;
                btnLogOff.Enabled = false;
                lblProjectCreated.Visible = false;
                txtWorkspaceSubSite.Enabled = false;
                lblVersion.Text = "";
    
                //Get the user.config or the default for the ProjectServerUrl property setting
                txtProjectServerUrl.Text = Properties.Settings.Default.ProjectServerUrl;
                if (txtProjectServerUrl.Text != "http://ServerName/ProjectServer/")
                {
                    radFormsAuthentication.Enabled = true;
                    radWindowsAuthentication.Enabled = true;
                    btnLogon.Enabled = true;
                    btnLogon.Select();
                }
            }
    
            private void radFormsAuthentication_CheckedChanged(object sender, EventArgs e)
            {
                if (radFormsAuthentication.Checked)
                {
                    lblUserName.Enabled = true;
                    lblPassword.Enabled = true;
                    txtUserName.Enabled = true;
                    txtPassword.Enabled = true;
                    winLogon = false;
                    loggedOn = false;
                    lblLoggedOn.Visible = false;
                    btnLogOff.Enabled = false;
                    lblProjectCreated.Text = "";
                    lblWorkspaceUrl.Text = "";
                }
            }
    
            private void radWindowsAuthentication_CheckedChanged(object sender, EventArgs e)
            {
                if (radWindowsAuthentication.Checked)
                {
                    lblUserName.Enabled = false;
                    lblPassword.Enabled = false;
                    txtUserName.Enabled = false;
                    txtPassword.Enabled = false;
                    winLogon = true;
                    loggedOn = false;
                    lblLoggedOn.Visible = false;
                    btnLogOff.Enabled = false;
                    lblProjectCreated.Text = "";
                    lblWorkspaceUrl.Text = "";
                }
            }
    
            private void txtProjectServerUrl_TextChanged(object sender, EventArgs e)
            {
                string url = txtProjectServerUrl.Text.Trim();
    
                if (url.StartsWith(URLPREFIX) && url.Length > 10)
                    containsUrl = true;
                else
                {
                    containsUrl = false;
                }
            }
    
            private void txtProjectServerUrl_Leave(object sender, EventArgs e)
            {
                if (containsUrl)
                {
                    if (!txtProjectServerUrl.Text.EndsWith("/"))
                        txtProjectServerUrl.Text += "/";
                    radFormsAuthentication.Enabled = true;
                    radWindowsAuthentication.Enabled = true;
                    btnLogon.Enabled = true;
                }
                else
                {
                    btnLogon.Enabled = false;
                    MessageBox.Show("Invalid Project Server URL", "Invalid URL",
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                    radFormsAuthentication.Enabled = false;
                    radWindowsAuthentication.Enabled = false;
                    btnLogon.Enabled = false;
                }
            }
    
            private void txtUserName_TextChanged(object sender, EventArgs e)
            {
                userName = txtUserName.Text;
            }
    
            private void txtPassword_TextChanged(object sender, EventArgs e)
            {
                password = txtPassword.Text;
            }
    
            private void btnLogon_Click(object sender, EventArgs e)
            {
                baseUrl = txtProjectServerUrl.Text;
                lblLoggedOn.Visible = false;
                string errMess = "";
                serverName = loginUtils.GetServerName(baseUrl);
    
                this.Cursor = Cursors.WaitCursor;
                try
                {
                    loggedOn = loginUtils.LogonPS(winLogon, baseUrl, userName, password);
                }
                catch (SoapException ex)
                {
                    errMess = ex.Message.ToString();
                }
                catch (WebException ex)
                {
                    errMess = ex.Message.ToString();
                }
                this.Cursor = Cursors.Default;
    
                if (loggedOn)
                {
                    AddContextInfo();
                    lblLoggedOn.Text = "Logon Succeeded!";
                    lblLoggedOn.ForeColor = Color.Green;
                    btnLogOff.Enabled = true;
    
                    string version = adminUtils.ProjectServerVersion(admin);
                    if (version.StartsWith("Error"))
                    {
                        MessageBox.Show(version, "Admin Web service error",
                            MessageBoxButtons.OK, MessageBoxIcon.Error);
                    }
                    else
                        lblVersion.Text = "Project Server Version: " + version;
                }
                else
                {
                    MessageBox.Show(errMess, "Logon Error", MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                    lblLoggedOn.Text = "Logon Failed!";
                    lblLoggedOn.ForeColor = Color.Red;
                }
    
                lblLoggedOn.Visible = true;
            }
    
            private void btnLogOff_Click(object sender, EventArgs e)
            {
                bool loggedOff = false;
                string errMess = "";
                try
                {
                    loggedOff = loginUtils.LogoffPS(winLogon);
                }
                catch (SoapException ex)
                {
                    errMess = ex.Message.ToString();
                }
                catch (WebException ex)
                {
                    errMess = ex.Message.ToString();
                }
                if (loggedOff)
                {
                    RemoveContextInfo();
                    lblLoggedOn.Text = "Logged Off!";
                    lblLoggedOn.ForeColor = Color.Black;
                    lblLoggedOn.Visible = true;
                    lblProjectCreated.Text = "";
                    lblVersion.Text = "";
                    lblWorkspaceLabel.Visible = false;
                    lblWorkspaceUrl.Text = "";
                }
                else
                {
                    MessageBox.Show(errMess, "Logoff Error", MessageBoxButtons.OK, 
                        MessageBoxIcon.Error);
                }
            }
    
            private void btnSaveUrl_Click(object sender, EventArgs e)
            {
                //Save the ProjectServerUrl property to the user.config file.
                Properties.Settings.Default.ProjectServerUrl = txtProjectServerUrl.Text;
                Properties.Settings.Default.Save();
            }
    
            /// <summary>
            /// Add the URL, and the user credentials or logon cookie, to each 
            /// PSI Web service object in the application.
            /// </summary>
            public void AddContextInfo()
            {
                // Add the Url property first.
                admin.Url = loginUtils.BaseUrl + ADMINWEBSERVICE;
                project.Url = loginUtils.BaseUrl + PROJECTWEBSERVICE;
                // Url property for OLP
                objectLinkProvider.Url = loginUtils.BaseUrl + OLPWEBSERVICE;
    
    
                if (winLogon)   // Add Windows credentials
                {
                    admin.Credentials = CredentialCache.DefaultCredentials;
                    project.Credentials = CredentialCache.DefaultCredentials;
                    // Windows credentials for OLP
                    objectLinkProvider.Credentials = CredentialCache.DefaultCredentials;
                }
                else            // Add Project Server logon cookie for Forms logon
                {
                    admin.CookieContainer = loginUtils.Cookies;
                    project.CookieContainer = loginUtils.Cookies;
                    // Forms logon cookie for OLP
                    objectLinkProvider.CookieContainer = loginUtils.Cookies;
                }
            }
    
            /// <summary>
            /// Remove the user credentials or logon cookie from each PSI Web service object.
            /// </summary>
            public void RemoveContextInfo()
            {
                if (winLogon)
                {
                    admin.Credentials = null;
                    project.Credentials = null;
                    // Added for OLP
                    objectLinkProvider.Credentials = null;
                }
                else
                {
                    admin.CookieContainer = null;
                    project.CookieContainer = null;
                    // Adde for OLP
                    objectLinkProvider.CookieContainer = null;
                }
            }
    
            /// <summary>
            /// Test the application with a PSI call. For example, create a project. 
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void btnCreateProject_Click(object sender, EventArgs e)
            {
                string projectCreatedLabel = "Project created!";
                string wssUrl;
                string projectWorkspace = ResetWorkspaceUrl();
                bool created = false;
                lblProjectCreated.Text = "";
                lblWorkspaceUrl.Text = projectWorkspace;
                this.Cursor = Cursors.WaitCursor;
    
                try
                {
                    WebSvcProject.ProjectDataSet dsProject = 
                        new WebSvcProject.ProjectDataSet();
                    WebSvcProject.ProjectDataSet.ProjectRow projectRow = 
                        dsProject.Project.NewProjectRow();
    
                    projectGuid = Guid.NewGuid();
                    projectRow.PROJ_UID = projectGuid;
                    projectRow.PROJ_NAME = this.txtProjectName.Text;
                    projectRow.PROJ_TYPE = 
                        Convert.ToInt32(PSLibrary.Project.ProjectType.Project);
                    
                    dsProject.Project.AddProjectRow(projectRow);
                    
                    // Adding a task to the project so we can have something to link to
                    WebSvcProject.ProjectDataSet.TaskRow taskRow =
                        dsProject.Task.NewTaskRow();
                    taskGuid = Guid.NewGuid();
                    taskRow.PROJ_UID = projectGuid;
                    taskRow.TASK_UID = taskGuid;
                    taskRow.TASK_NAME = "Task 1";
                    taskRow.TASK_DUR = 480000;
                    dsProject.Task.AddTaskRow(taskRow);
                    
    
                    Guid jobGuid = Guid.NewGuid();
                    bool validateOnly = false;
                    // Create and save project to the Draft db
                    project.QueueCreateProject(jobGuid, dsProject, validateOnly);
    
                    // Wait 3 seconds (more or less) for Queue job to complete.
                    // Or, add a routine that checks the QueueSystem for job completion.
                    System.Threading.Thread.Sleep(3000);
    
                    WebSvcProject.ProjectRelationsDataSet dsProjectRelations =
                        new WebSvcProject.ProjectRelationsDataSet();
                    jobGuid = Guid.NewGuid();
    
                    // Set wssUrl = "" to have default WSS project workspace, or null to have no workspace.
                    if (chkDefaultWorkspace.Checked)
                        wssUrl = "";
                    else if (projectWorkspace == "")
                        wssUrl = null;
                    else
                        wssUrl = projectWorkspace;
    
                    bool fullPublish = true;
                    // Publishes project to the Published db
                    dsProjectRelations = project.QueuePublish(jobGuid, projectGuid, fullPublish, wssUrl);
                    created = true;
                }
                catch (SoapException ex)
                {
                    string errMess = "";
                    // Pass the exception to the PSClientError constructor to get 
                    // all error information.
                    PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
                    PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
    
                    for (int j = 0; j < errors.Length; j++)
                    {
                        errMess += errors[j].ErrId.ToString() + "\n";
                    }
                    errMess += "\n" + ex.Message.ToString();
    
                    MessageBox.Show(errMess, "Error", MessageBoxButtons.OK,
                        MessageBoxIcon.Error);
                }
                catch (WebException ex)
                {
                    string message = ex.Message.ToString() +
                        "\n\nLog on, or check the Project Server Queuing Service";
                    MessageBox.Show(message, "Project Creation Error", 
                        MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                this.Cursor = Cursors.Default;
               
                if (created)
                {
                    lblProjectCreated.ForeColor = Color.Green;
                    lblWorkspaceUrl.Visible = true;
                    lblWorkspaceLabel.Visible = true;
                }
                else
                {
                    projectCreatedLabel = "Project not created";
                    lblProjectCreated.ForeColor = Color.Red;
                    lblWorkspaceUrl.Visible = false;
                    lblWorkspaceLabel.Visible = true;
                }
                lblProjectCreated.Text = projectCreatedLabel;
                lblProjectCreated.Visible = true;
            }
    
            private string ResetWorkspaceUrl()
            {
                string workspace;
                if (chkDefaultWorkspace.Checked)
                {
                    workspace = "http://" + serverName + "/" + txtProjectName.Text;
                }
                else
                {
                    workspace = "http://" + serverName + "/" + txtWorkspaceSubSite.Text;
                }
                return workspace;
            }
    
            private void txtProjectName_TextChanged(object sender, EventArgs e)
            {
                lblProjectCreated.Text = "";
                if (chkDefaultWorkspace.Checked)
                    txtWorkspaceSubSite.Text = txtProjectName.Text;
                lblWorkspaceLabel.Visible = false;
                lblWorkspaceUrl.Visible = false;
            }
    
            private void chkDefaultWorkspace_CheckedChanged(object sender, EventArgs e)
            {
                if (chkDefaultWorkspace.Checked)
                {
                    txtWorkspaceSubSite.Enabled = false;
                }
                else
                {
                    txtWorkspaceSubSite.Enabled = true;
                }
            }
    
            private void btnExit_Click(object sender, EventArgs e)
            {
                Application.Exit();
            }
    
            private void btnAddIssue_Click(object sender, EventArgs e)
            {
                //First find the Issues list in the site collection for the new project
                // siteCollection will fidn the collection for http://servename/pwa
                SPSite siteCollection = new SPSite(txtProjectServerUrl.Text + txtProjectName.Text);
                
                // sites will hold collection of sites under pwa - which will be he workspaces
                SPWebCollection sites = siteCollection.AllWebs;
    
                // lists will be the collection of lists in the specific site with the project name we just created
                SPListCollection lists = sites[txtProjectName.Text].Lists;
                
                // and finally list will be the Issues list for this site
                SPList list = lists["Issues"];
    
                // create a list collection
                SPListItemCollection listItems = list.Items;
    
                // add a new item
                SPListItem item = listItems.Add();
    
                // set some properties - in this sample I just set Title
                // but you can set any of the properties of the Project Workspace Issues list
                item["Title"] = "New Issue for Project " + txtProjectName.Text;
                
                // and update - we now have a new issue
                item.Update();
                
                // get some properties of the new item we will need later
                int itemTPID = item.ID;
                Guid listGuid = list.ID;
                string listName = list.Title.ToString();
    
                //  This code is basicall from the SDK OLP example but using the properties 
                // of the project task and items created earlier in this sample
                Guid taskWebObjectUid = Guid.Empty;
                WebSvcObjectLinkProvider.ObjectLinkProviderDataSet dsLinkedObjects =
                    objectLinkProvider.ReadTaskWebObject(taskGuid);
                int numTaskWebObjects = dsLinkedObjects.WebObjects.Count;
                // In this sample there will be no existing objects - but would be useful in other scenarios
                if (numTaskWebObjects > 0)
                    taskWebObjectUid = dsLinkedObjects.WebObjects[0].WOBJ_UID;
                
    
                WebSvcObjectLinkProvider.ObjectLinkProviderDataSet dsTask =
        new WebSvcObjectLinkProvider.ObjectLinkProviderDataSet();
                WebSvcObjectLinkProvider.ObjectLinkProviderDataSet.WebObjectsRow taskRow =
                    dsTask.WebObjects.NewWebObjectsRow();
    
                // Provide all known information to the Web object row for the task.  
                // If a task Web object does not exist, AddWebObjects creates
                // a new Web object and updates WOBJ_UID in taskRow.  
                taskRow.WOBJ_UID = taskWebObjectUid;
                taskRow.WOBJ_TASK_UID = taskGuid;
                taskRow.WOBJ_PROJ_UID = projectGuid;
                taskRow.WOBJ_TYPE = (int)PSLibrary.WebObjectDatabaseType.Task;
                dsTask.WebObjects.AddWebObjectsRow(taskRow);
    
                WebSvcObjectLinkProvider.ObjectLinkProviderDataSet dsListItems =
        new WebSvcObjectLinkProvider.ObjectLinkProviderDataSet();
                WebSvcObjectLinkProvider.ObjectLinkProviderDataSet.WebObjectsRow listItemRow =
                    dsListItems.WebObjects.NewWebObjectsRow();
    
                listItemRow.WOBJ_UID = Guid.NewGuid();
                listItemRow.WOBJ_TP_ID = itemTPID;
                listItemRow.WOBJ_LIST_NAME = listGuid;
                listItemRow.WOBJ_PROJ_UID = projectGuid;
                
                // I left the switch in but in this sample it will always be an issue
                switch (listName)
                {
                    case "Issues":
                        listItemRow.WOBJ_TYPE = (int)PSLibrary.WebObjectDatabaseType.Issue;
                        webObjectType = PSLibrary.WebObjectType.Issue;
                        linkedItems = "Issues found for task: " + taskGuid;
                        break;
                    case "Risks":
                        listItemRow.WOBJ_TYPE = (int)PSLibrary.WebObjectDatabaseType.Risk;
                        webObjectType = PSLibrary.WebObjectType.Risk;
                        linkedItems = "Risks found for task: " + taskGuid;
                        break;
                    case "Documents":
                        listItemRow.WOBJ_TYPE = (int)PSLibrary.WebObjectDatabaseType.Document;
                        webObjectType = PSLibrary.WebObjectType.Document;
                        linkedItems = "Documents found for task: " + taskGuid;
                        break;
                    case "Commitments":  // Commitments are now called Deliverables
                        listItemRow.WOBJ_TYPE = (int)PSLibrary.WebObjectDatabaseType.Commitment;
                        webObjectType = PSLibrary.WebObjectType.Commitment;
                        linkedItems = "Deliverables found for task: " + taskGuid;
                        break;
                    default:
                        string errMess = listName +
                            " is not a default SharePoint list type for task links.";
                        throw new SystemException(errMess);
                }
                dsListItems.WebObjects.AddWebObjectsRow(listItemRow);
    
                WebSvcObjectLinkProvider.WebObjectLinkType generalLinkType =
        WebSvcObjectLinkProvider.WebObjectLinkType.General;
                WebSvcObjectLinkProvider.WebObjectLinkType[] wssLinkTypeArray = 
        { generalLinkType };
    
                objectLinkProvider.CreateWebObjectLinks(dsTask, dsListItems, wssLinkTypeArray);
    
    
                
            }
        }
    }
    Technorati Tags: Project Server 2007
Page 82 of 92 (458 items) «8081828384»