Quantcast
Channel: Project Programmability and Business Intelligence
Viewing all 19 articles
Browse latest View live

An Impersonation Web Application

$
0
0

Jim Corbin has passed along this great post:

When you impersonate a user in an application for Project Server 2007, you adopt the global and category permissions of the impersonated user. This article shows how to develop a Web application for Project Server that uses impersonation. The attached pj12Impersonation.zip file includes a complete Web application that allows you to log on Project Server using Forms or Windows authentication, checks your permissions for listing and creating projects, and then lets you impersonate any other Project Server user.

Important: The Impersonation Web application is an example for demonstration purposes only. The application is designed to run on a test installation of Project Server. It allows anyone with a Project Server account to log on, impersonate any other user, and create projects. To use any impersonation application on a production server, you must programmatically limit usage and add security checks that are appropriate for your organization.

Most applications for Project, including Project Professional 2007 and Project Web Access, call the Project Server Interface (PSI) Web services through the Project Web Access URL. Project Server enforces the security permissions of your account when you log on through an application that uses the Project Web Access URL. Impersonation requires direct calls to the PSI through the Shared Service Provider (SSP) Web application that hosts Project Web Access.

The Project 2007 SDK includes the section Using Impersonation in Project Server with the article How to Write a Simple Impersonation Application. The ProjTool application in the SDK download also uses impersonation.

The following figure shows the Impersonate page in the Web application, which indicates the identity of the application user. The application user can log on Project Server using Windows authentication; in the figure, the user has clicked Forms for the Authentication Type and logged on a Project Server user named Joe. Joe has the NewProject global permission to create a project, but is denied the ManageQueue permission necessary to execute the ReadProjectList PSI method. If you (as the application user) select Joe in the Select User drop-down list and then click Impersonate, you would run the application with Joe’s permissions. If you click List Draft Projects, the application would return an exception because Project Server does not allow Joe to use ReadProjectList. If you check the UseReadProjectStatus() checkbox while impersonating Joe, the application would call the ReadProjectStatus method instead, and Joe could get the list of draft projects.

 

In the figure, the logged-on user Joe is impersonating the Administrator user, who does have the ManageQueue permission. Therefore, Joe can use the ReadProjectList method even though his own account does not have permission to do so. The application also enables an impersonated user (who has the NewProject permission) to create and publish a project, and then shows the new project in the list. The Draft Projects grid shows up to six projects and dynamically creates additional grid pages as needed.

To install the Impersonation Web application:

1.     Create a directory for the source files on your test Project Server computer, for example, C:\Project\.

2.     Unzip all of the files in pj12Impersonation.zip to C:\Project\. The top-level folder in the zip file is named Impersonation, so the local directory for the Web application is C:\Project\Impersonation.

3.     Using Internet Information Services (IIS) Manager on your Project Server computer, create a top-level Web site named, for example, Impersonation. Use the local path you created in Step 1 (C:\Project\Impersonation). Allow script access and executables. Disable anonymous access (use Integrated Windows Auth only). The Impersonation Web site can't be a SharePoint site, so set the port to something besides the ports that Project Web Access and Windows SharePoint Services use, such as 5636. Project Web Access typically uses port 80 for Windows authentication and port 81 for Forms authentication. Your Impersonation site URL would therefore be the following:

http://ServerName:5636

4.     The Impersonation Web site needs to run under a service account that is trusted by Project Server. Create a new application pool in IIS, for example, ImpersonationAppPool. On the Identity tab of the ImpersonationAppPool Properties dialog box, set the Configurable property of the Application Pool Identity to the same user account and password for the Project Web Access site administrator. To find the user account for configuring Project Web Access,  do the following:

a.     Open the SharePoint 3.0 Central Administration site, and click Application Management.

b.    On the Application Management page, click Create or configure this farm’s shared services.

c.     Click the name of the SSP where Project Web Access is installed. For example, click SharedServices1 (Default).

d.    On the Home page of the Shared Services Administration site, click Project Web Access Sites.

e.     On the Manage Project Web Access Sites page, pause the mouse pointer over the site instance you want, click the down-arrow, and then click Edit.

f.     On the Edit Project Web Access Site page, use the value in the Administrator Account text box. For example, set the Application Pool Identity to domain\pwaAdminName.

5.     In IIS Manager, right-click the Impersonation Web site, click Properties, and then click the Home Directory tab. Set the Application pool  value to the ImpersonationAppPool you created in Step 4.

6.     On the Impersonation Web site Properties page in IIS, click the ASP.NET tab, and then set the ASP.NET version to 2.0.50727.

7.     In IIS Manager, right-click the local computer name, and then click Properties. Click Enable Direct Metabase Edit. Then use Notepad to open the metabase.xml file in %systemroot%\system32\inetsrv.  Search for the site name within an IISWebServer tag. Add the attribute NTAuthenticationProviders="NTLM”. For example, following is the complete element for the new Impersonation site.

<IIsWebServer     Location ="/LM/W3SVC/784768436"

            AuthFlags="0"

            NTAuthenticationProviders="NTLM"

            ServerAutoStart="TRUE"

            ServerBindings=":5636:"

            ServerComment="Impersonation"

      >

</IIsWebServer>

8.     Restart IIS.

9.     Copy the following files to the Bin subdirectory in the Impersonation Web site:

·         Microsoft.Office.Project.Server.Library.dll (copy from C:\Program Files\Microsoft Office Servers\12.0\Bin)

·         Microsoft.SharePoint.dll (copy from C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI)

·         Microsoft.SharePoint.Search.dll

10.  Start Visual Studio 2005, and then open the Impersonation Web site from the Local IIS. When you click Save All, save the solution file as Impersonation.sln in C:\Project\Impersonation, for easy access.

11.  The Web application needs the same validation key that Project Web Access uses for calling the PSI. The <machineKey> element in web.config sets keys to use for encryption and decryption of Forms authentication cookie data. The <machineKey> element allows developers to configure a validation key that performs message authentication checks on Viewstate data and Forms authentication tickets. <machineKey> can be declared at the computer, site, or application levels, but not at a subdirectory level . If you don't specify the correct <machineKey> attributes, then you get a Viewstate error.

Set the <machineKey> attributes for your Project Server computer in web.config for the Impersonation site. Copy the complete <machineKey ...> line from the web.config file in your top-level site for Project Web Access (typically the default Web site), and replace the <machineKey … > line in the web.config file of the Impersonation site. The element should be all on one line, and a child of the <system.web> element, for example:

<machineKey validationKey="7C9DF8E41A03170EFF870936E0FED824859E541C6CF5768F" decryptionKey="EAAECB67BFF6AED2F4F812ADE1967CB6AB33A94A9FDE400C" validation="SHA1" />

12.  In the App_Code subdirectory, the Global.asax.cs file has all of the Application_Start, etc., methods that normally are in Global.asax. There’s no particular reason that Global.asax.cs is in App_Code, except that is where Visual Studio prefers to put it. You could put Global.asax.cs under Global.asax, if you add the following attribute to the Application directive in Global.asax:

CodeBehind="Global.asax.cs"

13.  In ImpersonationUtils.cs, change the SERVER_NAME constant to use your server name. Change the name of the Shared Service Provider (SSP) from SharedServices1 to the correct name for your SSP, and change the SSP port value if necessary. Build the Web site.

14.  Your Impersonation Web site should now work. Test the site on the local Project Server computer and on a remote computer. If the Impersonation application works on the local Project Server computer but not on a remote computer, it is likely that the IISWebServer tag (Step 7) is not correct. If you get an HTTP 401 (unauthorized) exception when you first try to log on with a Windows account, check that the application pool owner is set properly (Step 4).

When you log on Project Server with the Impersonation application, calls to the PSI use PROJECT_SERVER_URI for the value of the ResourceDerived.Url property. For Forms logon, the application sets the Url property to PROJECT_SERVER_FORMS_URI. During impersonation, the application sets the Url property to SSP_URI, for PSI calls to the ProjectDerived and SecurityDerived objects.

There are comments in the code that explain several parts of the application. For an explanation of the proxy and derived classes for the PSI Web services, see How to: Write a Simple Impersonation Application in the Project 2007 SDK. The logon routines in the ImpersonationUtils.cs file are based on code in the ProjTool sample; for more information, see Using the ProjTool Test Application.


Creating a PSI Extension

$
0
0

Overview

The Project Server Interface (PSI) is a set of over 20 web services that provide a programming interface for Project Server 2007. The PSI is used by Project Professional, Project Web Access (PWA) and third party applications to communicate with Project Server. For an overview of the PSI, read: PSI Reference Overview.

Even though the PSI is a rich set of web services that provide access to the majority of Project Server data, there are still scenarios where custom extensions to the PSI are required. The PSI provides the ability to extend the PSI with custom web services. This provides the ability to create a web service that tightly integrate with Project Server.

Here are a few scenarios that might make use of a PSI extension:

  • A PSI extension that pulls data from the reporting database. This allows for a simple deployment story for third party applications that are deployed outside a firewall from Project Server. They will not have to do direct query to the SQL database. If you create a PSI extension that opens up the reporting database, please make sure you do the appropriate security checks.
  • PSI extension and impersonation works easily because the PSI extension will be running in the correct security context.
  • Seamless third party integration. If you write an application that extends the functionality of project server with additional functionality, a PSI extension may provide a seamless integration story.

In this article, we will begin by creating a simple "Hello World" web service that is an extension of the PSI and have a client application access the "Hello World" web service. Then we will extend the web service to show how to get the user context information and how to call into existing PSIs from the new web service.

Creating a Simple "Hello World" Web Service in Visual Studio

To begin, we are going to create the "Hello World" web service. This example is written in C# using Visual Studio 2005; Visual Basic .NET provides equivalent functionality and could also be used.

This web service has only one exposed web method, HelloWorld(). All the method does, is return the string "Hello World".

  1. Open Visual Studio 2005
  2. Click File à New Web Site
  3. From the Templates, Select "ASP.NET Web Service" and enter a location:



    In this example, the location is set to HelloWorldPSI.
  4. Click OK

Next, you are going to want to create a new project within the HelloWorldPSI solution. This class library project is going to be used to contain the Web service logic:

  1. To create the project, right click on the solution name from the Solution Explorer, click Add àNew Project:


  2. From the Templates, Select "Class Library" and give the Class a name:


    In this example, the class name is HelloWorldPSI.
  3. In the Class Library Project, add the references to System.Web.Services and Microsoft.Office.Project.Server.Library by Right Clicking References à Add Reference in the Solution Explorer:


  • System.Web.Services should be found in the list of .Net Assemblies
  • Microsoft.Office.Project.Server.Library can be found by browsing to the bin directory in the install directory of Project Server. (C:\Program Files\Microsoft Office Servers\12.0\Bin)
  • Replace the default Class1.cs file in the project with the Service.cs file that Visual Studio provides in the App_Code folder of the Web Service. To replace the Class1.cs file with the Service.cs file:

    • In Solution Explorer, drag Service.cs to the top node in the class library project.
    • Delete the Class1.cs file, and also delete the Service.cs file that remains in the App_Code folder.

    The Solution Explorer should look like this when you are done:

  • Open the Services.cs file and Replace:

    [WebService(Namespace = "http://tempuri.org/")]

    With:

    [WebService(Namespace = "http://schemas.microsoft.com/office/project/server/webservices/Service/", Name = "HelloWorldPSI", Description = "Contains the Service web service for Microsoft Project Server.")]
  • Create a strong name for the class library. In Solution Explorer:

    1. Right Click the Class Library Project à Properties dialog box
    2. Click Signing,
    3. Select Sign the assembly, and select <New> in the box for choosing a strong name key file.
    4. Provide a file name for the key
    5. Deselect Protect my key file with a password
    6. Click OK.
  • Build only the Class Library Project, Right Click the project in Solution Explorer, and click Build.
  • Add the assembly to the Global Assembly Cache (GAC), you can either:
    1. Drag and drop the assembly into the %windows%\assembly directory using 2 instances of Windows Explorer
    2. Use the command line utility gacutil.exe that is installed with the .NET Framework SDK 2.0.To use gacutil.exe to copy the class library DLL into the GAC:
      1. To open the Visual Studio command prompt, Click Start à All Programsà Microsoft Visual Studio 2005 à Visual Studio Tools à Visual Studio 2005 Command Prompt.
      2. Enter the following command and press ENTER:

        gacutile.exe -iF "<Full file system path to DLL>".
  • Open %windows%\assembly in Windows Explorer
  • Open the Properties of the assembly by Right Clicking on the assembly and Selecting Properties:


  • In Visual Studio, open Service by Right Clicking the file in the Solution Explorer and Clicking Open
  • Remove the CodeBehind attribute from the page directive in Service.asmx, and modify the contents of the Class attribute so that the directive matches the following format:

    <%@WebServiceLanguage="C#"Class="Service, HelloWorldPSI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3f8ef1d5444ca3c9"%>
  • Rename the Service.asmx to something meaningful. In this example, it will be renamed to HelloWorldPSI.asmx.
  • Generating and Modifying Static Discovery and WSDL Files

    To provide discovery and description for your custom Web service, you must create a .disco and a .wsdl file. Since Windows SharePoint Services virtualizes URLs, you cannot use the auto generated .disco and .wsdl files generated by ASP.NET. Instead, you must create a .disco page and a .wsdl that provides the necessary redirection and maintains virtualization.

    You can use ASP.NET to generate the .disco and .wsdl files by hosting your Web service in a virtual directory, such as /SharedServices1/PSI, and then using the .NET Framework Web Service Discovery tool (Disco.exe) to obtain the generated files.

    The below steps assume that you have installed project server in the default directory. To generate .disco and .wsdl follow these steps:

    1. In Windows Explorer, copy the .asmx file to C:\Program Files\Microsoft Office Servers\12.0\WebServices\Shared\PSI.
    2. Open the web.config found in: C:\Program Files\Microsoft Office Servers\12.0\WebServices\Shared\PSI.
    3. Add the following below the line <add assembly="Microsoft.Office.Project.Server.WebService, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" />:

      <add assembly="HelloWorldPSI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=3f8ef1d5444ca3c9" />

      You will need to change the public key token to match the public key token for your assembly. Your public key token was determined in step 9 in the section "Creating a Web Service in Visual Studio".
    4. Restart IIS by opening a command prompt and entering: iisreset
    5. Run disco.exe in the command prompt:

      disco /o:"C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\isapi\PSI" http://localhost:56737/SharedServices1/PSI/HelloWorldPSI.asmx
    6. In Windows Explorer navigate to: C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI\PSI
    7. Rename HelloWorldPSI.disco to HelloWorldPSIdisco.aspx
    8. Rename HelloWorldPSI.wsdl to HelloWorldPSIwsdl.aspx
    9. To register namespaces of the Windows SharePoint Services object model, open both HelloWorldPSIdisco.aspx and HelloWorldPSIwsdl.aspx files and replace the opening XML processing instruction <?xmlversion="1.0"encoding="utf-8"?> with instructions such as the following:

      <%@PageLanguage="C#"Inherits="System.Web.UI.Page"%><%@AssemblyName="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%><%@ImportNamespace="Microsoft.SharePoint.Utilities"%><%@ImportNamespace="Microsoft.SharePoint"%><% Response.ContentType = "text/xml"; %>
    10. In the HelloWorldPSI.disco file, modify the contract reference and SOAP address tags to be like the following example, which replaces literal paths with code generated paths through use of the Microsoft.SharePoint.Utilities.SPEncode class, and which replaces the method name that is specified in the binding attribute:

      <discoveryxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:xsd="http://www.w3.org/2001/XMLSchema"xmlns="http://schemas.xmlsoap.org/disco/">
      <
      contractRefref=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request) + "?wsdl"),Response.Output); %>docRef=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>xmlns="http://schemas.xmlsoap.org/disco/scl/"/>
      <
      soapaddress=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>xmlns:q1="http://schemas.microsoft.com/projectserver/soap/Service/"binding="q1:ServiceSoap"xmlns="http://schemas.xmlsoap.org/disco/soap/"/>
      <
      soapaddress=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>xmlns:q2="http://schemas.microsoft.com/projectserver/soap/Service/"binding="q2:ServiceSoap12"xmlns="http://schemas.xmlsoap.org/disco/soap/"/>
      </
      discovery>
    11. In the HelloWorldPSI.wsdl file, make the following, similar substitution for the SOAP address:

      Replace:

      <soap:addresslocation="http://localhost:56737/SharedServices1/PSI/HelloWorldPSI.asmx"/>

      With:

      <soap:addresslocation=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>/>


      And Replace:

      <soap12:addresslocation="http://localhost:56737/SharedServices1/PSI/HelloWorldPSI.asmx"/>

      With:

      <
      soap12:addresslocation=<% SPHttpUtility.AddQuote(SPHttpUtility.HtmlEncode(SPWeb.OriginalBaseUrl(Request)),Response.Output); %>/>
    12. Restart IIS by opening a command prompt and entering: iisreset

    Creating a Client Application

    At this point, we have a basic web service that extends the PSI. Now we are going to write a small client application that calls the web service. Open Visual Studio and create a new project:

    • File à New Project
    • From the Templates, Select "Windows Application"
    • Give the Windows Application a name. In this example, we will use "HelloWorldPSIClient"
    • Add Web Reference to: http://localhost/pwa/_vti_bin/PSI/HelloWorldPSI.asmx?WSDL and call it WSHelloWorldPSI
    • Rename Form.cs to HelloWorld.cs
    • Open HelloWorld.cs in Deisgn Mode
    • Add a Button Called "Connect to Hello World PSI"
    • Copy the following Code:

          using System;
          using System.Collections.Generic;
         
    using System.ComponentModel;
         
    using System.Data;
         
    using System.Drawing;
         
    using System.Text;
         
    using System.Windows.Forms;
         
    using System.Net;

    namespace HelloWorldPSIClient
    {

      publicpartialclassHelloWorld : Form
     
    {
        public HelloWorld()
        {
          InitializeComponent();
       
    }

        privatevoid cmdHelloWorld_Click(object sender, EventArgs e)
       
    {
          
    WSHelloWorldPSI.HelloWorldPSI helloWorldWS
            
    = new HelloWorldPSIClient.WSHelloWorldPSI.HelloWorldPSI(); 
          
    helloWorldWS.Url = http://localhost/pwa/_vti_bin/psi/HelloWorldPSI.asmx;
           helloWorldWS.Credentials = CredentialCache.DefaultCredentials;

           string hello = helloWorldWS.HelloWorld(); 
           
    MessageBox.Show(hello);
       

      }
     
    }

    If you run the client application and click the button, it should connect to Project Server, get the string "Hello World" and show it in a message box:

    Now we have successfully created a web service that extends the PSI and a client application that calls into the web service. The attached file, Sample Code.zip contains PSIExtensionSample1.zip, which has the source code to the web service, the client application, HelloWorldPSI.disco and HelloWorldPSI.wsdl.

    Doing More with the Simple Web Service

    In the last example we created a simple web service that returned "Hello World". In this example, we are going to extend the "Hello World" web service. Within the HelloWorld() web method, we are going to get the user context and get the user's e-mail address from the Resource PSI.

    Starting from the HelloWorldPSI solution:

    1. Add a Reference to System.Web
    2. Add a Web Reference to the Resource PSI: http://localhost/_vti_bin/PSI/Resourcewsdl.aspx and call it WSResource
    3. Open the Service.cs to edit the code
    4. Add using System.Net;to the top of the class file
    5. In the method HelloWorld() Replace:

      return"Hello World";

      With:

      // Get the user context of the calling user

         HttpContext context = HttpContext.Current; 
         
    string pjAuthHeader = context.Request.Headers["PjAuth"];
        
    PSContextInfo contextInfo = PSContextInfo.DeserializeFromString(pjAuthHeader);

         String message = "Hello World\r\n\r\n"
              
    message += "Following user called the Custom Project Server Web Service\r\n";
              
    message += String.Format(System.Globalization.CultureInfo.InvariantCulture,
                               
    "UserName = {0}, SiteGuid = {1}, Lcid = {2}\r\n",
                               
    contextInfo.UserName, contextInfo.SiteGuid, contextInfo.Lcid);

         // Call into the Resource PSI for the user's e-mail address

         HelloWorldPSI.WSResource.Resource resWS = newHelloWorldPSI.WSResource.Resource();

         resWS.Url = http://localhost/pwa/_vti_bin/psi/Resource.asmx
         resWS.Credentials = CredentialCache.DefaultCredentials;

         HelloWorldPSI.WSResource.ResourceDataSet resDS = resWS.ReadResource(contextInfo.UserGuid);

         message += "E-Mail Address: "
           
    resDS.Tables[resDS.Resources.TableName].Rows[0][resDS.Resources.WRES_EMAILColumn.ColumnName].ToString();

      return message;

    Now we need to deploy the changes:

    1. Build only the Class Library Project, Right Click the project in Solution Explorer, and click Build.
    2. Add the assembly to the Global Assembly Cache (GAC), you can either:
      1. Drag and drop the assembly into the %windows%\assembly directory using 2 instances of Windows Explorer
      2. Use the command line utility gacutil.exe that is installed with the .NET Framework SDK 2.0.To use gacutil.exe to copy the class library DLL into the GAC:
        1. To open the Visual Studio command prompt, Click Start à All Programsà Microsoft Visual Studio 2005 à Visual Studio Tools à Visual Studio 2005 Command Prompt.
        2. Enter the following command and press ENTER:

          gacutile.exe -iF "<Full file system path to DLL>".
    3. Restart IIS by opening a command prompt and entering: iisreset
    4. Run the Client Application and click the button:

    As you can see from the message box, we have successfully got the user context of the calling user and have been able to call into an existing PSI. The attached file, Sample Code.zip contains PSIExtensionSample2.zip, which has the source code to the web service that displays the user context and the resources e-mail address, the client application, HelloWorldPSI.disco and HelloWorldPSI.wsdl.

    Best Practices for Project Server Extensions

    There are best practices to follow when developing a Microsoft Office Project Server 2007 extension for the PSI:

    1. Do not modify any Project Server database objects (tables, views, stored procedures, and so on)
    2. You can read and manipulate Project Server Data by calling into existing PSIs
    3. You can read Project Server data from the Reporting Database
    4. Incorporate security into your PSI extensions. Do not return data back to users who should not have access to the data.
    5. PSIs can throw runtime exceptions in many situations. Make sure all your code is protected with try/catch blocks so that a sensible reply message can be returned to the client.

    April update of the Project 2007 SDK is now available on MSDN

    $
    0
    0

    The April update of the SDK is now available on MSDN. It includes many final versions of articles that have been published as posts on this blog.  

    ·         SDK Download: http://www.microsoft.com/downloads/details.aspx?FamilyId=2672F6F9-7028-4B30-99A2-18CB1EED1ABE&displaylang=en .
    The pj12ProjectSDK.exe download includes (new and updated items in blue bold):

    o   pjSDK2007.chm (conceptual topics and managed code reference – the same topics as on the MSDN online library)

    o   pj12ReportingDB.chm (Reporting database schema reference and Visio diagrams)

      • OLAPCubeSchemas.xls (dimensions, measures, and properties of the Project Server OLAP cubes)
      • XML data interchange schema for Project 2007 (mspdi_pj12.xsd plus supplemental schemas for enterprise custom fields)
      • Statusing schemas (ChangeList.xsd and SetAssignmentWorkData.xsd)
      • Project Portfolio Server 2007 Database Reference(AccountData and AccountIndex)
      • Redistribution license for the Microsoft.Office.Project.Server.Library.dll
      • SDK code samples:
    1. ChangeXML Utility: generate, validate, and test ChangeXML parameters for the UpdateStatus method
    2. Custom Web Parts: two samples; one uses the Microsoft.Office.Project.Server.PWA.dll assembly, and one does not
    3. Impersonation: two samples; a simple console application and the Impersonation Web Application
    4. Login Demo
    5. OLP Example
    6. Project Guide: default Project Guide files, and the sample Critical Path custom Project Guide updated for Project 2007
    7. Project Workspace
    8. ProjTool: a sample application to help generate data and test many of the PSI methods
    9. PSI Extensions: develop and test a custom PSI Web service
    10. Report Pack: seven sample reports using SQL Server Reporting Services 2005 (SP1)
    11. Test Event Handler
  • SDK Online: Project 2007 SDK in MSDN online library: http://msdn2.microsoft.com/en-us/library/ms512767.aspx
    • Object Model Maps: The Project 2007 VBA Reference was also recently posted on MSDN, along with four pages of the new Project object model maps. For example, click any object in Application and Projects Object Map to go to the topic for that object. You can also see the object model maps in VBA Help when you use Project Standard or Project Professional. In the Project Help window, click the Connection Status menu at the lower right, and then select Show content from Office Online.
  • Portal:  Project Developer Portal in the Office Developer Center on MSDN includes links to the Project 2007 SDK,  Project 2007 blogs, as well as the Project 2003 SDK.
  •  

    What’s new in pjSDK2007.chm and the online SDK:

     

    In addition to new code samples and schemas in the download, the April update of the SDK includes 97 conceptual topics (28 new since the RTM release) and many updates in the managed code reference topics. Major new and updated conceptual topics include the following:

    ·         XML Schema References for Project (15 topics; includes the ChangeList Schema Reference)

    ·         Changes for Custom Project Guides 

    ·         Custom Fields in OLAP Cubes (in the Local and Enterprise Custom Fields topic)

    ·         How to: Generate ChangeXML for Statusing Updates

    ·         Project Server Report Pack (9 topics)

    ·         Walkthrough: Creating a PSI Extension 

    ·         Walkthrough: Develop an Impersonation Web Application

                                                                                                                                                       

    Other updates include enumeration descriptions, PSI method permissions, TimesheetDataSet properties, and a VBA sample for Project Deliverables.

     

    For related content, see the Office Developer Centers,  SharePoint Developer Center, and the SharePoint Server 2007 Developer Portal.

    Project 2010 SDK - January update

    $
    0
    0

    The  pre-release Project 2010 SDK is updated on MSDN. Post-beta builds of Project Server are changed for setting ASMX and WCF service references and using multi-authentication (where Windows and Forms are both used) with Claims. These issues do not affect the Project Server 2010 beta release.

    New topic:
    How to: Use Impersonation with WCF  (see note at bottom for Claims)

    Topics with major updates:
    Project 2010 SDK Documentation (introductory page)
    Using Formulas and Graphical Indicators with Custom Fields 

    How to: Create a Branching Workflow 
    How to: Install and Test a Project Server Workflow

    Overview of WCF and the PSI 
    Walkthrough: Developing PSI Applications Using WCF (see note at bottom for Claims)
    Prerequisites for ASMX-Based Code Samples  (see note at bottom for Claims)
    Prerequisites for WCF-Based Code Samples  (see note at bottom for Claims)

     

     

     

     

    Update of Impersonation Article and Code for Project Server 2010

    $
    0
    0

    Because there have been several recent changes in the post-beta version of Project Server 2010 and Office SharePoint Server 2010, the article How to: Use Impersonation with WCF in the January 2010 release of the SDK is not correct for the 4730.1010 and later builds of Project Server. The article in the March 2010 release of the SDK is correct. The attached Impersonation_PSIProxy.zip file includes the following:

    • Revised article: How to: Use Impersonation with WCF.docx
      • Changes required to use a Project Server installation that has multi-authentication (both Windows and Forms authentication)
      • Procedures for setting permissions for impersonation (requires permissions in both the SharePoint Service application and in Project Web App)
    • Complete Visual Studio 2008 solution (can be opened and converted with Visual Studio 2010)
    • Proxy files for the PSI services (build 4730.1010), including:
      • Scripts to update the proxy files on a Project Server computer and build a PSI proxy assembly
      • Intellisense files
      • Temporary web.config file and instructions, to use when updating the proxy files

     

    Project 2010 SDK, **March** update (online MSDN only)

    $
    0
    0

    See Project 2010 SDK Documentation for the March update of the online Project 2010 SDK.
    The  pre-release Project 2010 SDK is updated on MSDN. Post-beta builds of Project Server are changed for setting WCF service references and using multi-authentication (where Windows and Forms are both used) with Claims. These issues do not affect the Project Server 2010 beta release.

    The topic How to: Use Impersonation with WCF is updated again for the RC release, since the previous update in February.
    Update of Impersonation Article and Code for Project Server 2010 in the Project_Programmability blog includes  code download with the second round of changes that have been made in Project Server 2010 and SharePoint Server 2010 since the beta release.

    Topics with major updates:
    Developing Project Server Workflows (all four subtopics are updated, including a PowerShell script for managing workflow deployment)
    Prerequisites for WCF-Based Code Samples (includes the corrected changes for creating a PSI proxy)
    The managed code reference also has more content, particularly in the Workflow and Driver areas.

    The SDK download will be updated shortly after product general availability.

    ProjTool for Project Server 2010

    $
    0
    0

    Note: For the updated article, see Using the ProjTool Test Application in Project Server 2010 in the Project 2010 SDK. The attached ProjTool_ProjectServer2010.zip file includes the ProjTool application and the complete Visual Studio 2010 solution.

    The ProjTool test application was introduced in the Microsoft Office Project 2007 SDK. Many developers found it useful for creating, examining, and changing data by using the PSI on a test installation of Project Server, and checking actions by impersonating users on a test server. The 2007 release of ProjTool does not work correctly with Project Server 2010.

    ProjTool was originally developed by many different testers on the Project team. In the SDK release, the internal test code has been removed. The download that is attached to this post includes an update of ProjTool for Project Server 2010, along with a draft document on how to use ProjTool. The article and source code will be included in a future update of the Project 2010 SDK.

    The updated ProjTool uses the .NET Framework 3.5; all calls to PSI methods use WCF instead of the ASMX interface. ProjTool now works for Windows authentication, Forms authentication,  multi-authentication (both Windows and Forms on the same Project Web App port address), and impersonation on Project Server 2010.

    Here is an example screenshot from ProjTool, which shows part of the AssignmentDataTable in the ProjectDataSet for one project, after the user has changed the value of the ASSN_PCT_WORK_COMPLETE field in an assignment. When Update Project is clicked, ProjTool shows fields in all of the datatables that have changed as a result.

    --Jim

    Timesheet Solutions for Webcast: Understanding the PSI in Project Server 2010

    $
    0
    0

    The MSDN Webcast: Understanding Project Server Interface (PSI) in Project Server 2010 (Level 300) presentation is available for download, when you register for the event. Several of the sample applications that were demonstrated in the webcast are available in the Project 2010 SDK download. The TimesheetSamples.zip file that is attached to this blog post includes the two example solutions for timesheets. (Steven Haden and Olivier Laymand, Microsoft Corporation, did the webcast and created the sample code.)

    • MyTsSample shows how to update a  timesheet for a resource, where the timesheet is in single entry mode.
    • TimesheetEventHandler shows how to use impersonation with a TimesheetEventReceiver.OnCreated event handler, to update the timesheet name.

    Using the updated ChangeXML utility for Statusing

    $
    0
    0

    The Statusing methods in the Project Server Interface (PSI) in Microsoft Project Server 2010 enable one user to read, submit, and update assignment and task status for another user, without resorting to impersonation. In the Project Server 2007 SDK, the How to: Generate ChangeXML for Statusing Updates article shows how to generate the changeXml parameter for the UpdateStatus method, validate the XML, and use the ReadStatus and SubmitStatus methods. The Project 2007 SDK download includes the complete Visual Studio 2005 solution for the ChangeXML utility. However, the ChangeXML utility could only update status for the current user.

    The ChangeXML utility  is now updated for Project Server 2010, in the attached ChangeXMLUtility.zip file. With it, you can generate the changeXml parameter and update status for the current user or for another user. To update status for another user, the utility uses the ReadStatusForResource and UpdateStatusForResource methods. In addition, the utility checks whether the current user has the global StatusBrokerPermission security permission, adds the ResID attribute to the changeXml parameter, and validates the XML against the updated ChangeList.xsd schema in Project Server 2010. For more information about the ChangeList.xsd schema, see Introduction to the ChangeList Schema and Statusing ChangeXML.

    Note: The ChangeXML utility is designed for use only on a test installation of Project Server 2010, as an example of a programming utility for statusing. It should not be used on a production installation.

    The updated ChangeXML utility also has several other changes. The previous version uses the ASMX interface, which was the only choice available for Project Server 2007. In the updated version, you can choose to programmatically initialize the WCF interface of the PSI by entering the Project Web App URL, or by using the WCF endpoint values in the app.config file. In the following screenshot, the login is automatic if you use the app.config value.

            ChangeXML_LogOn_AppConfig

    Note: To use the app.config file, change the URL to the value for your PWA instance, for each PSI service endpoint.

    In the main window, after you log on Project Server, choose Build Change XML.

            ChangeXML_Main_Empty

    You can choose to update the status of available assignments for the current user, or – if you have the StatusBrokerPermission– you can choose another user and update assignments for that user. In the following screenshot, the update is for another user. The Items available for update list shows the Project name : Task name : User name values for each item. You can choose to update assignment values or task values for that assignment. The Generate a Change dialog box shows different controls in the Update section, depending on what kind of update you choose. For example, if you choose to update an assignment custom field, you can choose the custom field and the lookup table value, if the custom field uses a lookup table.

            ChangeXML_Generate_4User_Assign_HealthCF

    When you choose Update XML, the tool generates the changeXml parameter value, as follows:

            ChangeXML_Main_4User_Assign_HealthCF

    Following is the changeXml parameter value in the case shown, for updating the Health assignment custom field. Note that the XML value includes the ResID attribute for the Assn element.

    <Changes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><Proj ID="a3e78597-2302-45fc-bb15-7f23d74efdf8"><Assn ID="b001d2d9-69eb-49a0-aa9f-6bbe53f9484c"
    ResID="aa3a6f6f-bb70-4d2e-92da-b06580ae6376"><LookupTableCustomFieldChange IsMultiValued="false"
    CustomFieldType="Text"
    CustomFieldGuid="00004f6d-90a2-439a-8cc2-1c1ef6d2da4f"
    CustomFieldName="Health"><LookupTableValue
    Guid="0000c45d-8a43-4eb0-9b74-e535b391988a">Late</LookupTableValue></LookupTableCustomFieldChange></Assn></Proj></Changes>

    You can clear the Run Update check box to just validate the changeXml parameter. For example, manually change one of the elements, attributes, or values in the XML, and see if it still validates. Or, you can check Run Update to validate and run the change.

    When the change is completed, try opening the project in Project Professional. If you are the project manager, you are prompted to review the status change in PWA. If you accept the change in PWA, to see the change, open the project in Project Professional. For example, if you changed the Health assignment custom field, go the the Task Usage view, and then add the Health field to the view.

            WinProj_OpenProject_AssnHealthCF_Changed

    After you save and publish the project, you can also see the change in the Reporting database. For example, run the following query in SQL Server Management Studio for the RDB:

    SELECTTOP 1000 [AssignmentUID]
          , [ResourceUID]
          , [Health_T]FROM [ProjectServer_Reporting].[dbo].[MSP_EpmAssignment_UserView]

    Find the correct assignment and resource GUIDs in the Results pane:

    SQLSrv_ReportingDB_EpmAssignment

    The ChangeXML utility is useful for creating and testing values of the changeXml parameter for the UpdateStatus method,
    where
    you can create and test changes for the current user and for other Project Server 2010 users. It also contains code examples
    that show how to check for a security permission of a resource and use statusing methods.

    Updating the ChangeXML utility

    Here are the main steps that were used to update the application from Project Server 2007 to 2010. The user interface had only
    minor tweaks, because that was not an issue for a test tool.

    1. Open in Visual Studio 2010 to update the solution; change the target to .NET Framework 3.5.
    2. Add a reference to the updated ProjectServerServices.dll, which contains a proxy WCF interface of the PSI services.
    3. Remove ASMX initialization; initialize PSI services for WCF (programmatic and/or with app.config). This step is not
      essential, but the WCF interface is recommended for moving forward.
    4. Modify the login dialog box; use the WCFHelpers.dll assembly from ProjTool for login routines. The ProjTool code for
      Project Server 2010 is in the SDK download.
      Note: The logon routines for Forms authentication are not updated in this sample.
    5. Get and display the StatusBrokerPermission value for the current user. Enable the Update for user option if the current
      user has the correct permission.
    6. Get the list of active resources, by using ReadUserList; add the ResourceItem class for combobox display and values.
    7. Refresh the list of items to update, by using ReadStatusForResource.
    8. Add ResID to classes for generating and displaying the changeXml parameter (ChangesProj, ChangesProjAssn,
      ChangesProjTask, and Items).
    9. Remove the empty ResID attribute in the changeXml value for the current user.
    10. Run statusing updates for a selected user, by using SubmitStatusForResource.
    11. Test

    In actuality, testing occurs after each step is completed.

    —Jim Corbin

    Using the updated ChangeXML utility for Statusing

    $
    0
    0

    The Statusing methods in the Project Server Interface (PSI) in Microsoft Project Server 2010 enable one user to read, submit, and update assignment and task status for another user, without resorting to impersonation. In the Project Server 2007 SDK, the How to: Generate ChangeXML for Statusing Updates article shows how to generate the changeXml parameter for the UpdateStatus method, validate the XML, and use the ReadStatus and SubmitStatus methods. The Project 2007 SDK download includes the complete Visual Studio 2005 solution for the ChangeXML utility. However, the ChangeXML utility could only update status for the current user.

    The ChangeXML utility  is now updated for Project Server 2010, in the attached ChangeXMLUtility.zip file. With it, you can generate the changeXml parameter and update status for the current user or for another user. To update status for another user, the utility uses the ReadStatusForResource and UpdateStatusForResource methods. In addition, the utility checks whether the current user has the global StatusBrokerPermission security permission, adds the ResID attribute to the changeXml parameter, and validates the XML against the updated ChangeList.xsd schema in Project Server 2010. For more information about the ChangeList.xsd schema, see Introduction to the ChangeList Schema and Statusing ChangeXML.

    Note: The ChangeXML utility is designed for use only on a test installation of Project Server 2010, as an example of a programming utility for statusing. It should not be used on a production installation.

    The updated ChangeXML utility also has several other changes. The previous version uses the ASMX interface, which was the only choice available for Project Server 2007. In the updated version, you can choose to programmatically initialize the WCF interface of the PSI by entering the Project Web App URL, or by using the WCF endpoint values in the app.config file. In the following screenshot, the login is automatic if you use the app.config value.

            ChangeXML_LogOn_AppConfig

    Note: To use the app.config file, change the URL to the value for your PWA instance, for each PSI service endpoint.

    In the main window, after you log on Project Server, choose Build Change XML.

            ChangeXML_Main_Empty

    You can choose to update the status of available assignments for the current user, or – if you have the StatusBrokerPermission – you can choose another user and update assignments for that user. In the following screenshot, the update is for another user. The Items available for update list shows the Project name : Task name : User name values for each item. You can choose to update assignment values or task values for that assignment. The Generate a Change dialog box shows different controls in the Update section, depending on what kind of update you choose. For example, if you choose to update an assignment custom field, you can choose the custom field and the lookup table value, if the custom field uses a lookup table.

            ChangeXML_Generate_4User_Assign_HealthCF

    When you choose Update XML, the tool generates the changeXml parameter value, as follows:

            ChangeXML_Main_4User_Assign_HealthCF

    Following is the changeXml parameter value in the case shown, for updating the Health assignment custom field. Note that the XML value includes the ResID attribute for the Assn element.

    <Changes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <Proj ID="a3e78597-2302-45fc-bb15-7f23d74efdf8">
        <Assn ID="b001d2d9-69eb-49a0-aa9f-6bbe53f9484c"
    ResID="aa3a6f6f-bb70-4d2e-92da-b06580ae6376"> <LookupTableCustomFieldChange IsMultiValued="false"
    CustomFieldType="Text"
    CustomFieldGuid="00004f6d-90a2-439a-8cc2-1c1ef6d2da4f"
    CustomFieldName="Health"> <LookupTableValue
    Guid="0000c45d-8a43-4eb0-9b74-e535b391988a">Late</LookupTableValue> </LookupTableCustomFieldChange> </Assn> </Proj> </Changes>

    You can clear the Run Update check box to just validate the changeXml parameter. For example, manually change one of the elements, attributes, or values in the XML, and see if it still validates. Or, you can check Run Update to validate and run the change.

    When the change is completed, try opening the project in Project Professional. If you are the project manager, you are prompted to review the status change in PWA. If you accept the change in PWA, to see the change, open the project in Project Professional. For example, if you changed the Health assignment custom field, go the the Task Usage view, and then add the Health field to the view.

            WinProj_OpenProject_AssnHealthCF_Changed

    After you save and publish the project, you can also see the change in the Reporting database. For example, run the following query in SQL Server Management Studio for the RDB:

    SELECT TOP 1000 [AssignmentUID]
          , [ResourceUID]
          , [Health_T]
        FROM [ProjectServer_Reporting].[dbo].[MSP_EpmAssignment_UserView]

    Find the correct assignment and resource GUIDs in the Results pane:

    SQLSrv_ReportingDB_EpmAssignment

    The ChangeXML utility is useful for creating and testing values of the changeXml parameter for the UpdateStatus method,
    where
    you can create and test changes for the current user and for other Project Server 2010 users. It also contains code examples
    that show how to check for a security permission of a resource and use statusing methods.

    Updating the ChangeXML utility

    Here are the main steps that were used to update the application from Project Server 2007 to 2010. The user interface had only
    minor tweaks, because that was not an issue for a test tool.

    1. Open in Visual Studio 2010 to update the solution; change the target to .NET Framework 3.5.
    2. Add a reference to the updated ProjectServerServices.dll, which contains a proxy WCF interface of the PSI services.
    3. Remove ASMX initialization; initialize PSI services for WCF (programmatic and/or with app.config). This step is not
      essential, but the WCF interface is recommended for moving forward.
    4. Modify the login dialog box; use the WCFHelpers.dll assembly from ProjTool for login routines. The ProjTool code for
      Project Server 2010 is in the SDK download.
      Note: The logon routines for Forms authentication are not updated in this sample.
    5. Get and display the StatusBrokerPermission value for the current user. Enable the Update for user option if the current
      user has the correct permission.
    6. Get the list of active resources, by using ReadUserList; add the ResourceItem class for combobox display and values.
    7. Refresh the list of items to update, by using ReadStatusForResource.
    8. Add ResID to classes for generating and displaying the changeXml parameter (ChangesProj, ChangesProjAssn,
      ChangesProjTask, and Items).
    9. Remove the empty ResID attribute in the changeXml value for the current user.
    10. Run statusing updates for a selected user, by using SubmitStatusForResource.
    11. Test

    In actuality, testing occurs after each step is completed.

    —Jim Corbin

    ChangeXMLUtility.zip

    Project 2013 Preview SDK and related resources

    $
    0
    0

    The Project 2013 Preview SDK download is published. The conceptual, how-to, and reference documentation in the download closely matches the Project 2013 developer documentation online content published on MSDN. In addition, the download also contains:

    • Ten complete code solutions, including two task pane apps for Project, six client-side object model (CSOM) solutions, and two solutions for querying the ProjectData service for reporting.
    • DLLs and a license for redistribution of the three Project Server CSOM assemblies, JavaScript files for the CSOM, and the Microsoft.Office.Project.Server.Library assembly.

      Note: Project CSOM solutions also require the redistributable DLLs for the SharePoint 2013 CSOM, which are at SharePoint Server 2013 Client Components SDK.

    • Intellisense files for the PSI and CSOM, source code for creating a PSI proxy assembly, and instructions on how to update the PSI proxy files.
    • XML schemas for the Project client, AppProvisioning, and the Statusing PSI.

    The top-level online landing page for the Project SDK is Project for developers (http://msdn.microsoft.com/project).

    For additional Project-related SDK content, see Office for developers (http://msdn.microsoft.com/office), SharePoint for developers (http://msdn.microsoft.com/sharepoint), and Build apps for Office and SharePoint (http://msdn.microsoft.com/office/apps/). The two articles on Task pane apps for Project are in the Apps for Office and SharePoint SDK, and the JavaScript API for Office reference includes information specific for Project, the ProjectDocument object with eleven methods and three events, and four enumerations for Project. Those SDK downloads are now published:

    Want to try out Project 2013?

    1. Sign up for the Project Online Preview with Project Pro for Office 365
    2. Download Project Professional 2013 Preview & Project Server 2013 Preview

    New VBA classes and members in Project Professional 2013 Preview

    $
    0
    0

    The What’s new for developers in the new Project desktop (besides task pane apps) article is available in the Office Developer Blog. The VBA and VSTO object model includes includes classes that support new reports with charts, tables, and Office Art. Other new members in the Project object model support the new task paths feature, cache status, and working with tasks lists in SharePoint 2013.

    Connecting a Project Task Pane App to PWA

    $
    0
    0

    Introduction

    Apps for Office present a great new opportunity to bring data from a variety of sources into Office applications. The new Project specifically offers a very powerful way to surface both SharePoint and Project Web App data in a task pane app in Project Professional. To connect with SharePoint or PWA from the client, we use on-the-fly OAuth flow as presented in the SharePoint 2013 SDK. The App for Project described in this article connects with the same PWA site collection that Project Professional is currently connected to, and displays data about the currently selected task that is not otherwise available from within Project Professional. This will work with all versions of Project Professional (C2R, MSI, On Demand) and with all PWA environments (Project Online, Project Server).

    image

    Setup

    Prerequisites for this project are:

    • Visual Studio 2012
    • IIS or IIS Express configured to allow applications to run on your server (at localhost)
    • Office 2013 and SharePoint 2013 tools for Visual Studio, available here
    • Project Professional 2013
    • Project Online tenant or Project Server

    The first step is to launch Visual Studio 2012. Create a new App for Office 2013 project as shown below. Let’s call it “TaskLastModifiedApp”.

    image

    In the next dialog, make this a Task Pane App for Project.

    We need to add references, as this app will use a number of APIs across Office and SharePoint. These DLLs may be in a different location on your system. Most of these references are automatically added if you use the App for SharePoint template, so if you can’t find these on your system, create a quick App for SharePoint solution and note the reference paths to help you out. You should add:

    • C:\Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5\Microsoft.IdentityModel.dll
    • C:\Windows\Microsoft.NET\assembly\GAC_MSIL\Microsoft.IdentityModel.Extensions\v4.0_2.0.0.0__69c3241e6f0468ca\Microsoft.IdentityModel.Extensions.dll
    • C:\Program Files\Reference Assemblies\Microsoft\Windows Identity Foundation\v3.5\Microsoft.IdentityModel.WindowsTokenService.dll
    • C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.ProjectServer.Client.dll
    • C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.dll
    • C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\ISAPI\Microsoft.SharePoint.Client.Runtime.dll
    • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.IdentityModel.dll
    • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.IdentityModel.Selectors.dll
    • C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.ServiceModel.dll

    Additionally, you will need to add a copy of TokenHelper.cs, which is generated when creating an autohosted or provider-hosted App for SharePoint project.

    Task Pane App Manifest

    The actual task pane app is just an XML manifest. Open up TaskLastModifiedApp.xml from the TaskLastModifiedApp project in your Solution Explorer. Replace its contents with the following:

     1: <?xml version="1.0" encoding="UTF-8"?>
     2: <OfficeApp xmlns="http://schemas.microsoft.com/office/appforoffice/1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="TaskPaneApp">
     3:   <Id>[leave this line alone]</Id>
     4:   <Version>1.0</Version>
     5:   <ProviderName>Microsoft</ProviderName>
     6:   <DefaultLocale>en-US</DefaultLocale>
     7:   <DisplayName DefaultValue="TaskLastModifiedApp" />
     8:   <Description DefaultValue="This app will show you when the selected task was last modified"/>
     9:   <AppDomains>
     10:     <AppDomain>https://localhost:44301/</AppDomain>
     11:   </AppDomains>
     12:   <Capabilities>
     13:     <Capability Name="Project" />
     14:   </Capabilities>
     15:   <DefaultSettings>
     16:     <SourceLocation DefaultValue="https://localhost:44301/pages/URLConstructor.aspx" />
     17:   </DefaultSettings>
     18:   <Permissions>ReadWriteDocument</Permissions>
     19: </OfficeApp>

    Replace the port after localhost (in both instances) with whatever port you have configured IIS to use for SSL. Make sure to toggle the “SSL Enabled” property on the TaskLastModifiedAppWeb project to true. Let whatever ID was originally set in the manifest remain.

    Architecture

    Next, delete the TaskLastModifiedApp.html page – we will need .aspx pages in this project. The basic architecture of the task pane app is as follows:

    • When the task pane app is launched, it loads “URLConstructor.aspx”, which pulls the PWA URL from the client and constructs a call to OAuthAuthorize with the proper tokens to request permissions for the app to access PWA data. This page loads “URLConstructor.js” to interact with the client.
    • OAuthAuthorize is launched in a new window, since we cannot predict the customer’s Project domain. After the user trusts the app, that new window is redirected to “PostOAuth.aspx”, which surfaces the auth code back to URLConstructor.aspx.
    • Once URLConstructor.aspx has the auth code, the task pane app is redirected with this as a token to “Default.aspx”, which has the functional code for the app. This page uses Project CSOM code in its code-behind page to read data from PWA, as well as “TaskLastModifiedApp.js” to interact with the client.

    Constructing the OAuthAuthorize URL

    The complete code for URLConstructor.aspx is as follows:

     1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="URLConstructor.aspx.cs" Inherits="TaskLastModifiedAppWeb.Pages.URLConstructor" %>
     2:  
     3: <!DOCTYPE html>
     4:  
     5: <html xmlns="http://www.w3.org/1999/xhtml">
     6:  
     7: <head runat="server">
     8:     <title>TaskLastModifiedApp</title>
     9:     <meta http-equiv="X-UA-Compatible" content="IE=9" />
     10:     <script type="text/javascript" src="..\Scripts\Office\1.0\MicrosoftAjax.js"></script>
     11:     <script type="text/javascript" src="..\Scripts\Office\1.0\Office.js"></script>
     12:     <script type="text/javascript" src="..\Scripts\URLConstructor.js"></script>
     13:     <script type="text/javascript">
     14:         function getClientId() {
     15:             var clientId = '<%=ConfigurationManager.AppSettings["ClientId"].ToString() %>'; //read the clientID from web.config
     16:             getPwaUrl(clientId); //return to client code
     17:         }</script>
     18: </head>
     19:  
     20: <body>
     21:     Redirecting...
     22: </body>
     23:  
     24: </html>

    This page needs to be an .aspx page in order to read from web.config, but does not need anything in its code-behind. The clientId read from web.config is needed for the authorization flow. getPwaUrl() is a function within URLConstructor.js.

    The complete code for URLConstructor.js is as follows:

     1: var _projDoc;
     2: var pwaUrl;
     3: var oAuthUrl;
     4:  
     5: Office.initialize = function (reason) {
     6:     _projDoc = Office.context.document;
     7:     getClientId(); //on document load, reads the ClientId from web.config first since it is server-side
     8: }
     9:  
     10: function getPwaUrl(clientId) { //uses Office App API to read PWA URL
     11:     _projDoc.getProjectFieldAsync(Office.ProjectProjectFields.ProjectServerUrl,
     12:         function (asyncResult) {
     13:             if (asyncResult.status == Office.AsyncResultStatus.Succeeded) {
     14:                 pwaUrl = asyncResult.value.fieldValue;
     15:                 generateUrl(clientId); //creates the OAuthAuthorize URL with necessary parameters
     16:             }
     17:             else {
     18:                 logMethodError("getProjectFieldAsync", asyncResult.error.name, asyncResult.error.message);
     19:             }
     20:         }
     21:     )
     22: };
     23:  
     24: function generateUrl(clientId) {
     25:     oAuthUrl = pwaUrl + "/_layouts/15/OAuthAuthorize.aspx?IsDlg=1&client_id=" + clientId + "&scope=Projects.Read&response_type=code&redirect_uri=https://localhost:44301/pages/PostOAuth.aspx";
     26:     authWindow = window.open(oAuthUrl);
     27:     codeListener(); //start listening for the auth code
     28: }
     29:  
     30: function codeListener() {
     31:     setTimeout(function () { readCode(); }, 1000); //check for the auth code every one second
     32: }
     33:  
     34: function readCode() {
     35:     try { //if we can actually reach the authCode field on PostOAuth.aspx
     36:         authCode = authWindow.document.getElementById("authCode").value;  //pull the authCode value
     37:         if (authCode != "NA") { //if it is not the default "NA"
     38:             authWindow.close(); //close the new window
     39:             document.location.href = "/Pages/Default.aspx?code=" + authCode; //redirect task pane to the app code with the authCode token
     40:         }
     41:     }
     42:     catch (e) {
     43:         codeListener(); //if we couldn't reach PostOAuth.aspx, wait another second and try again
     44:     }
     45: }

    When the task pane app loads, it first reads web.config from the aspx page, since this is server-side code. Once it has the clientId, we read the PWA URL. We then create the full OAuthAuthorize URL with the parameters specified above. scope=Projects.Read requests read permission to projects on the current PWA site. Make sure to match the SSL port here as well, as before.

    On running the app, a new window will open up outside of Project that prompts the user to login to PWA (if they have not checked “Keep me signed in” previously). They will then be presented with a “Do you trust…” page, the same as if they were installing an App for SharePoint. This is the OAuthAuthorize.aspx page. Once trusted, that new window navigates to PostOAuth.aspx, presented below:

     1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="PostOAuth.aspx.cs" Inherits="TaskLastModifiedAppWeb.Pages.PostOAuth" %>
     2:  
     3: <!DOCTYPE html>
     4:  
     5: <html xmlns="http://www.w3.org/1999/xhtml">
     6: <head runat="server">
     7:     <title></title>
     8: </head>
     9: <body>
     10:     <form id="form1" runat="server">
     11:     <div>
     12:     <asp:HiddenField ID="authCode" runat="server" value="NA"/>
     13:         Closing...
     14:     </div>
     15:     </form>
     16: </body>
     17: </html>

    And PostOAuth.aspx.cs:

     1: using System;
     2: using System.Collections.Generic;
     3: using System.Linq;
     4: using System.Web;
     5: using System.Web.UI;
     6: using System.Web.UI.WebControls;
     7:  
     8: namespace TaskLastModifiedAppWeb.Pages
     9: {
     10:     public partial class PostOAuth : System.Web.UI.Page
     11:     {
     12:         protected void Page_Load(object sender, EventArgs e)
     13:         {
     14:             var code = Request.QueryString["code"];
     15:             authCode.Value = code;
     16:         }
     17:     }
     18: }

    This page saves the auth code token in a hidden field. The task pane app, still on URLConstructor.aspx, waits for this value and then closes the new window. The app then continues on to default.aspx with the proper code token needed to finish the OAuth flow.

    Reading the Last Modified Date of the Selected Task

    The remainder of this article is an example of what you might do in your task pane app now that you have read access to PWA data. This example will show you the Last Modified date and time of the task you have selected. On launch, it shows you data for the selected task, and as you change tasks, the data is updated using an event handler.

    The complete code for Default.aspx is as follows:

     1: <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="TaskLastModifiedAppWeb.Pages.Default" %>
     2:  
     3: <!DOCTYPE html>
     4:  
     5: <html xmlns="http://www.w3.org/1999/xhtml">
     6: <head runat="server">
     7:     <title>TaskLastModifiedApp</title>
     8:     <meta http-equiv="X-UA-Compatible" content="IE=9" />
     9:     <script type="text/javascript" src="..\Scripts\Office\1.0\MicrosoftAjax.js"></script>
     10:     <script type="text/javascript" src="..\Scripts\Office\1.0\Office.js"></script>
     11:     <script type="text/javascript" src="..\Scripts\TaskLastModifiedApp.js"></script>
     12:     
     13: </head>
     14:  
     15: <body>
     16:     <form id="form1" runat="server">
     17:         
     18:         <asp:HiddenField ID="projGuidHF" runat="server" />
     19:         <asp:HiddenField ID="taskGuidHF" runat="server" />
     20:         <asp:HiddenField ID="pwaUrlHF" runat="server" />
     21:  
     22:         <asp:Label ID="TaskLastModLabel" runat="server" Text="Loading..." />
     23:  
     24:         <div style="display: none;">
     25:             <asp:Button ID="hiddenTaskChangedButton" runat="server" OnClick="OnTaskChanged" />
     26:         </div>
     27:  
     28:     </form>
     29:  
     30: </body>
     31: </html>

    This page contains three hidden fields used to pass data back and forth between the client-side code and the server-side code. It also leverages a label to surface the results to the user, and a hidden button that the client-side code uses to call a server-side function, as you will see below.

    The complete code for TaskLastModifiedApp.js is as follows:

     1: var _projDoc;
     2: var taskGuid;
     3: var projGuid;
     4: var pwaUrl;
     5:  
     6: // This runs after every postback
     7: Office.initialize = function (reason) {
     8:     _projDoc = Office.context.document;
     9:     if (document.getElementById("pwaUrlHF").value == "NA") { //if this is the first run
     10:         firstRun();
     11:     }
     12:     manageTaskEventHandler('addHandlerAsync'); //need to re-register event handler after each postback
     13: }
     14:  
     15: // Only need these on the first page load, not on postbacks
     16: function firstRun() {
     17:     getProjGuid();
     18:     _projDoc.getProjectFieldAsync(Office.ProjectProjectFields.ProjectServerUrl,
     19:         function (asyncResult) {
     20:             pwaUrl = asyncResult.value.fieldValue;
     21:             document.getElementById("pwaUrlHF").value = pwaUrl;
     22:         }
     23:     )
     24:     getTaskGuid();
     25: }
     26:  
     27: // Get the GUID of the selected task, comes from SDK
     28: function getTaskGuid() {
     29:     var TaskLastModLabel = document.getElementById("TaskLastModLabel");
     30:     TaskLastModLabel.innerHTML = "Loading...";
     31:     _projDoc.getSelectedTaskAsync(function (asyncResult) {
     32:         taskGuid = asyncResult.value;
     33:         document.getElementById("taskGuidHF").value = taskGuid; //saves the task GUID to a hidden field to pass to the code-behind
     34:         document.getElementById("hiddenTaskChangedButton").click(); //runs the CSOM calls in the aspx.cs file
     35:     });
     36: }
     37:  
     38:  // Get the GUID of the current project.
     39: function getProjGuid() {
     40:     _projDoc.getProjectFieldAsync(Office.ProjectProjectFields.GUID,
     41:         function (asyncResult) {
     42:             projGuid = asyncResult.value.fieldValue;
     43:             document.getElementById("projGuidHF").value = projGuid; //saves the project GUID to a hidden field to pass to the code-behind
     44:         }
     45:     )
     46: }
     47:  
     48: // Task selection changed event handler.
     49: function onTaskSelectionChanged(eventArgs) {
     50:     getTaskGuid();
     51: }
     52:  
     53: // Add or remove a task selection changed event handler.
     54: function manageTaskEventHandler(docMethod) {
     55:     manageEventHandlerAsync(
     56:         Office.EventType.TaskSelectionChanged,      // The task selection changed event.
     57:         onTaskSelectionChanged,                     // The event handler.
     58:         docMethod                // The Office.Document method to add or remove an event handler.
     59:     );
     60: }
     61:  
     62: // Add or remove the specified event handler.
     63: function manageEventHandlerAsync(eventType, handler, operation, onComplete) {
     64:     _projDoc[operation]   //The operation is addHandlerAsync or removeHandlerAsync.
     65:     (
     66:         eventType,
     67:         handler,
     68:         function (asyncResult) {
     69:             // code here runs after event has been registered (or failed)
     70:         }
     71:     );
     72: }

    The first time this code runs, it pulls the PWA URL (just like we did in URLConstructor.js) and saves it to one of our hidden fields, registers a client-side event handler to capture when a new task is selected, and starts the process of connecting to PWA and pulling the data we need, which is mostly done in the code-behind file. After each postback, we do not need to recapture the PWA URL, as our ProjectContext is maintained as a static variable.

    We need to make one quick tweak to TokenHelper.cs first – change GetRealmFromTargetUrl from a private method to a public method.

    The complete code for Default.aspx.cs is as follows:

     1: using System;
     2: using System.Collections.Generic;
     3: using System.Linq;
     4: using System.Web;
     5: using System.Web.UI;
     6: using System.Web.UI.WebControls;
     7: using Microsoft.ProjectServer.Client;
     8: using Microsoft.SharePoint.Client;
     9:  
     10: namespace TaskLastModifiedAppWeb.Pages
     11: {
     12:     public partial class Default : System.Web.UI.Page
     13:     {
     14:         public static ProjectContext projContext;
     15:         public static PublishedProject thisProj;
     16:         public Guid projGuid;
     17:  
     18:         protected void Page_Load(object sender, EventArgs e)
     19:         {
     20:             if (!IsPostBack) //set values of hidden fields if this is the first page load
     21:             {
     22:                 projGuidHF.Value = "NA";
     23:                 taskGuidHF.Value = "NA";
     24:                 pwaUrlHF.Value = "NA";
     25:             }
     26:         }
     27:  
     28:  
     29:         protected void GetContexts()
     30:         {
     31:             var code = Request.QueryString["code"]; //pulls the code token from the request
     32:  
     33:             string targetPwa = pwaUrlHF.Value; //pulls the PWA URL from where the Office app API stored it
     34:  
     35:             Uri targetPwaUri = new Uri(targetPwa);
     36:  
     37:             var tRealm = TokenHelper.GetRealmFromTargetUrl(targetPwaUri);
     38:  
     39:             Uri rUri = new Uri("https://localhost:44301/pages/PostOAuth.aspx"); //hardcoded link to redirect_uri
     40:  
     41:             var clientContext = TokenHelper.GetClientContextWithAuthorizationCode(targetPwa, "00000003-0000-0ff1-ce00-000000000000", code, tRealm, rUri);
     42:  
     43:             projContext = GetProjectContextWithAuthorizationCode(targetPwa, "00000003-0000-0ff1-ce00-000000000000", code, tRealm, rUri);
     44:  
     45:             projGuid = new Guid("{" + projGuidHF.Value + "}"); //loads the current project through CSOM
     46:  
     47:             var projects = projContext.LoadQuery(projContext.Projects.Where(proj => proj.Id == projGuid));
     48:             projContext.ExecuteQuery();
     49:             thisProj = projects.First();
     50:         }
     51:  
     52:         protected void OnTaskChanged(object sender, EventArgs e) //determine the selected task's last modified date
     53:         {
     54:             if (thisProj == null)
     55:             {
     56:                 GetContexts();
     57:             }
     58:             
     59:             var taskGuid = new Guid(taskGuidHF.Value);
     60:  
     61:             var tasks = projContext.LoadQuery(thisProj.Tasks.Where(task => task.Id == taskGuid)); //load the selected task off of the project
     62:             projContext.ExecuteQuery();
     63:             PublishedTask thisTask = tasks.First();
     64:             string dateMod = thisTask.Modified.ToString("D"); //pull out the Modified field on the task
     65:             string timeMod = thisTask.Modified.ToString("t");
     66:             TaskLastModLabel.Text = "The selected task was last modified on " + dateMod + " at " + timeMod + ".";
     67:         }
     68:  
     69:         public static ProjectContext GetProjectContextWithAuthorizationCode(string targetUrl,string targetPrincipalName,string authorizationCode,string targetRealm,Uri redirectUri)
     70:         {
     71:             Uri targetUri = new Uri(targetUrl);
     72:  
     73:             string accessToken =
     74:                 TokenHelper.GetAccessToken(authorizationCode, targetPrincipalName, targetUri.Authority, targetRealm, redirectUri).AccessToken;
     75:  
     76:             return GetProjectContextWithAccessToken(targetUrl, accessToken);
     77:         }
     78:  
     79:         public static ProjectContext GetProjectContextWithAccessToken(string targetUrl, string accessToken)
     80:         {
     81:             Uri targetUri = new Uri(targetUrl);
     82:  
     83:             ProjectContext projContext = new ProjectContext(targetUrl);
     84:  
     85:             projContext.AuthenticationMode = ClientAuthenticationMode.Anonymous;
     86:             projContext.FormDigestHandlingEnabled = false;
     87:             projContext.ExecutingWebRequest +=
     88:                 delegate(object oSender, WebRequestEventArgs webRequestEventArgs)
     89:                 {
     90:                     webRequestEventArgs.WebRequestExecutor.RequestHeaders["Authorization"] =
     91:                         "Bearer " + accessToken;
     92:                 };
     93:  
     94:             return projContext;
     95:         }
     96:     }
     97: }

    PageLoad()

    The first time the page loads, we need to initialize the hidden field values. This enables us to not set them directly in Default.aspx (and thus lose their values after a postback) and lets the client-side code distinguish between a first run load and a postback.

    GetContexts()

    This code also only runs once, assuming the current project remains loaded. This handles the last part of the OAuth flow – we use the code token from OAuthAuthorize to generate a client context and a project context using methods in TokenHelper.cs, as well as slightly modified methods GetProjectContextWithAuthorizationCode() and GetProjectContextWithAccessToken().

    OnTaskChanged()

    This first checks to make sure we have a project loaded from which to pull data. We then read the selected task guid from the hidden field, which was updated client-side before this method was called. We use Project CSOM to load the selected task from PWA and read its Last Modified field, which is then presented to the user in a readable format using the label on Default.aspx.

    Register the App ID and App Secret

    Since we are not submitting this app to the Office Store, we need to register it on our test tenant. On your tenant, navigate to https://[your PWA site]/_layouts/15/appregnew.aspx. Generate a new App Id and App Secret, set the Title to “TaskLastModifiedApp”, set the App Domain to localhost:44301 (or wherever the app code is running), and set the Redirect URI to match the redirect_uri token value in the oAuth URL created in URLConstructor.js.

    image

    Hit Create, and then add the App Id and App Secret to web.config in your Visual Studio solution. It should look like the following when you are done, with your values for ClientId and ClientSecret:

     1: <?xml version="1.0"?>
     2:  
     3: <configuration>
     4:     <system.web>
     5:       <compilation debug="true" targetFramework="4.0" />
     6:     </system.web>
     7:   <appSettings>
     8:     <add key="ClientId" value="a9ce3d5a-bb14-4aad-9c27-41a05c473b4d" />
     9:     <add key="ClientSecret" value="hL0C8wt2PPaBYNYRMZzcUcu3C/Vv0fbm48djGzyIXOw=" />
     10:   </appSettings>
     11: </configuration>

    Time to Test!

    To run the app, just hit F5 in Visual Studio, which will launch Project Professional. Make sure to connect to a PWA profile, then load a published project (or create and publish a new one). From a task view, select the Project tab in the ribbon, hit the dropdown for Apps for Office, and click TaskLastModifiedApp.

    image

    The app will launch in a task pane on the right side of the screen. It’ll prompt you to trust the app, quickly load, and then display the last modified date and time of the selected task.

    image

    Select a different task, and the data will update almost instantly.

    image

    Wrap-Up

    In this blog post, you have learned how to create a task pane app in Project Professional that can display data from PWA that would not normally be visible in the client. The app uses SharePoint’s OAuthAuthorize page to request permissions from PWA and handle the authentication handshake between the app code and your online data. For more on working with OAuth, make sure to check out the relevant node in the SharePoint 2013 SDK. For more information on PWA programmability, check out the Project 2013 SDK. To learn more about writing task pane apps for the new Project, see this node in the Office 2013 SDK.

    TaskLastModifiedApp.zip

    Creating Project Workflows using Visual Studio 2012

    $
    0
    0

    In Project Server 2010, Project developers were able to create Project Workflows using Visual Studio 2010. In Project Server 2013, we enabled creating the workflows with SharePoint Designer, which makes it much easier and faster to create Project Workflows. In that blog post, we showed how we have simplified the workflow creation for Project using SharePoint Designer 2013.

    We are, however, still supporting creating Project Workflows with Visual Studio for the more complex set of workflows, and in fact, have also made it easier to create Project Workflows with Visual Studio 2012. Below, we are going to use a sample two-stage workflow to show how you can create workflows with Visual Studio 2012:

    1. Creating the Workflow solution: File Menu>New>Project>Office/SharePoint>SharePoint solutions > SharePoint 2013 Project. Give this project a name, and hit OK:
    clip_image002

    In the customization wizard, enter the address of the PWA web you’d like this workflow to be published to. Then, pick the sandboxed solution option to limit this workflow to this particular PWA web:
    clip_image004

    2. At this point, the project you’ll see the empty canvas. In the Project Menu, click on the Add New Item, and from the Office/SharePoint tab, select Workflow, enter a name, and hit Add:
    clip_image006

    Then, in the customization wizard, pick Site workflow:
    clip_image008

    Then, pick the history list and the workflow tasks list from that site. We recommend that you use the default lists since a number of PWA UI entry points, use these default lists. Then, hit Finish:
    clip_image009

    3. Now, we need to set up the environment to use the Project Server activities. In the toolbox, right click and click on “add tab”, and call the new tab “project server”:
    clip_image011

    Then, right click on the “project server” tab and click on “choose items” from the menu, and you’ll see this dialog:
    clip_image013

    In the dialog click on Browse, and navigate to where the workflow dlls are located. They are usually located in C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\15\TEMPLATE\WorkflowActivities
    You’ll see two activities dll there. Open the project server one (Microsoft.Office.Project.Server.WorkflowActivities.dll), and hit OK. You are now taken back to the “toolbox items” dialog, and highlights the selected corresponding activities. Hit OK to continue.
    clip_image015

    4. You might see a “sequence” in the canvas. Delete that, and from the toolbox, pick Flowchart and add it by dragging it into the main area. This flowchart will be the main container of all the stages of the workflow:
    image

    In the toolbox, click on Control flow, and add the sequence inside that flowchart. Throughout this sample workflow, we will use sequence to represent workflow stages in Visual Studio. This is similar to how SharePoint Designer handles each stage, i.e. each stage is equivalent to a separate sequence in Visual Studio:
    clip_image019

    Rename the sequence to “Create_Stage” by clicking on the “Sequence” and start typing to change the name. Drag the line from start to “Create_Stage” to connect them together:
    clip_image021

     

    5. Double click on the “Create_Stage” to drill into this sequence

    a. Under project server in toolbox, add the “EnterProjectStage” and “ExitProjectStageGate” activities to the sequence. These two activities are required in any of the PWA stages in Visual Studio.

    b. In the properties of “EnterProjectStage”, change the StageID to the Stage ID of the particular stage you’d want this sequence to represent. You can find the stage ID in the URL of that stage, and is available if you navigate to that stage in PWA Settings > Workflow Stages, and then click on the particular stage. Since stageID is a string, the ID should be provided in quotation marks.

    c. Put another sequence between “EnterProjectStage” and “ExitProjectStageGate”. Essentially, everything in this sequence is what is represented in the text-based designer in SharePoint Designer stage definition.

    d. From project server item in the toolbox, drop the “waitForProjEvent” activity in that sequence:
    clip_image022

    e. Change the EventName property to “OnProjectSubmit”. The other supported Event Names are “OnProjectCommit” and “OnProjectCheckIn”

    6. In the breadcrumb, click on Flowchart to go one level up. Add another sequence after Create_Stage and call it Finished_Stage, and connect the wire from Create_Stage to the Finished_Stage:
    clip_image023

    7. Similar to the Create_Stage, add the EnterProectStage and ExitProjectStageGate activities to the sequence as well as the WaitForProjectEvent activity in the middle, and set the properties accordingly:
    clip_image024

     

     

    8. This completes building the workflow in Visual Studio. However, in order to make sure that the workflow can be properly published to the PWA, we need to make a few more changes in the xaml files of the project: From solution explorer, pick “Elements.xaml” under the workflow node

    a. Replace the WSEventSourceGUID with the following so that the workflow is correctly identifies as a project workflow:
    <Property Name=”WSEventSourceGUID” Value=”5122D555-E672-4E5D-A7C4-8084E694A257″ />

    b. Inject the following properties under the “Url = WorkflowStartAssociation”:
          <Property Name=”Microsoft.ProjectServer.ActivationProperties.ProjectId” Value=”” />
          <Property Name=”Microsoft.ProjectServer.ActivationProperties.CurrentStageId” Value=”” />
          <Property Name=”Microsoft.ProjectServer.ActivationProperties.RequestedStageId” Value=”” />
          <Property Name=”WSEventContextKeys” Value=”Microsoft.ProjectServer.ActivationProperties.CurrentStageId;#Instance&#xA;Microsoft.ProjectServer.ActivationProperties.ProjectId;#Instance&#xA;Microsoft.ProjectServer.ActivationProperties.RequestedStageId;#Instance&#xA;” />

    9. Now that everything is set, and the workflow is ready for publishing, click on the “Build Solution” under the Build menu, and then click on the “Deploy Solution” under the Build menu. The wsp file is now deployed to the site. You can also find a copy of the wsp file in the file system, under [project name]>bin>debug

    Now, the workflow will show up in PWA. If you navigate to PWA Settings > Enterprise Project Types, and create a new Enterprise Project Type, you will see this workflow as one of the options in the workflow dropdown list.

    For more information, see Getting started developing Project Server 2013 workflows in the Project 2013 SDK.

    Installing the Project 2013 SDK download on Windows 8

    $
    0
    0

    The Project 2013 SDK download is updated for the RTM release of Project 2013. In addition to articles, references, and code samples that are updated from the July release of Project 2013 Preview, the SDK also includes a local copy of VBA Help for Project Standard and Project Professional.

    You can install the downloaded Project2013SDK.msi file on computers that are running Windows 8, Windows 7 (and a couple of earlier Windows releases), Windows Server 2008 R2, and Windows Server 2012. When you install the SDK on a Windows 7 machine, the SDK contents are accessible from the Start menu. Figure 1 shows, for example, that the Microsoft SDKs folder contains the Project 2013 SDK folder, which contains links to three files. From the hierarchical context of the Start menu, it is clear that the Documentation node is contained in the Project 2013 SDK folder.

    Similarly, if you install the SharePoint 2013 SDK download and the Apps for Office and SharePoint SDK download, they each create a folder in Microsoft SDKs, and each SDK has a Documentation node within its folder.

    Figure 1. Using the Project 2013 SDK from the Windows 7 Start menu

    PJ15SDK_Start_Win7

    The problem

    Windows 8 does not have a Start menu, it has two related Start screens. After you install the Project 2013 SDK download, and scroll the main Start screen to the links for the installed files, you can see the same three links as in Windows 7. (To see the Welcome Guide on the Start screen, you can search for Welcome.rtf, open it in Internet Explorer, and then pin Welcome Guide to the Start screen.) But, the Start screen in Windows 8 is not arranged in hierarchical folders. In Figure 2, it is not clear what the Documentation link is for.

    Figure 2. Using the Documentation link to the Project 2013 SDK, on the Windows 8 Start screen

    Win8_StartScreen_Documentation

    The problem is worse if you also install the SharePoint 2013 SDK and the Apps for Office and SharePoint 2013 SDK. You would then have three Documentation links and three Welcome Guide links, each of which goes to a different SDK.

    If you right-click one of the Start screen icons, the icon shows a check mark, and the Start screen shows options at the bottom (see Figure 2). If you choose All apps at the bottom right of the screen, Windows 8 shows lists of installed apps within top-level groups. For example, the Microsoft SDKs group contains links for all of the Office, Project, and SharePoint SDKs that you install; there are no subfolders to distinguish which links go to which SDK. In Figure 3, only the Project 2013 SDK is installed, and the links have the same names as in Figure 2.

    Figure 3. Using the Project 2013 SDK links in the Apps view, in Windows 8

    Win8_AllApps_MicrosoftSDKs

    The workaround (for now)

    On a machine with Windows 8, you can install one SDK at a time, and then rename the links on the Start screen, before installing another SDK.

    To install Office, Project, and SharePoint SDKs on Windows 8

    1. Log on to Windows 8 as an administrator.
    2. Install, for example, the Project 2013 SDK.
    3. On the Start screen, right-click the Documentation icon, and then choose Open file location at the bottom of the screen.
    4. On the Windows Desktop, rename the Documentation link as Project 2013 SDK Documentation, and then choose Continue in the File Access Denied dialog box (see Figure 4).

      Figure 4. Renaming the Project 2013 SDK links in the Desktop view
      Win8_Rename_Documentation
    5. Similarly, rename the VBA Reference link as Project 2013 VBA Reference, and rename the Welcome Guide link as Project 2013 Welcome Guide.
    6. With the mouse pointer in the lower-left corner of the screen, choose the Start pop-up icon, and then scroll to the Project 2013 SDK icons (see Figure 5).

      Figure 5. Using the renamed links in the Start view
      Win8_StartScreen_ProjectSDK_Renamed

    7. Install the Apps for Office and SharePoint 2013 SDK, and similarly rename the Start screen links.
    8. Install the SharePoint 2013 SDK, and similarly rename the Start screen links. Figure 6 shows the Microsoft SDKs group with the renamed links in the All apps view.

    Figure 6. Using the renamed links for all three SDKs in the All apps view

    Win8_AllApps_3SDKs_Renamed

    In future releases, the Office, SharePoint, and Project SDK downloads will be reconfigured so that they install with non-conflicting link names on Windows 8.

     


    Building an app for Project Server 2013

    $
    0
    0

    Alex Burton, a Project MVP, has published a series of posts titled Building your first Project Server app on the EPMSource blog. The app is named Publish All; it publishes all enterprise projects for the PWA instance where the app is installed. The Publish All app is developed by using the Project Server JavaScript object model (JSOM) with “Napa” Office 365 Development Tools, and can be deployed to Project Online and to an on-premises installation of Project Server 2013.

    The blog series includes the following parts:

    Alex has even gone so far as to add a support page for the Publish All app, at http://epmsource.com/2013-apps/. It looks to be a very useful series.

    For more information about the Napa tools, see How to: Create a basic app for SharePoint by using Office 365 Development Tools on MSDN. For information about using Visual Studio 2012 with the JSOM for Project Server, see Getting started with the Project Server 2013 JavaScript object model.

    Project Server 2013 reporting database (RDB) schema reference

    $
    0
    0

    The attached Project2013Reporting.exe file contains a draft release of the schema reference for the reporting tables and views in Project Server 2013. To install the files, run Project2013Reporting.exe. The next release of the Project 2013 SDK download will also include the reporting schema reference; that will be announced here when the Project 2013 SDK update is published.

    The Project Server 2013 RDB and OLAP cubes are accessible only with an on-premises installation of Project Server. For Project Online, you can use REST queries of the ProjectData OData service. The ProjectData service is also available with on-premises installations. For more information, see ProjectData – Project 2013 OData service reference in the Project 2013 SDK.

    The attached file includes the following:

    • ProjectServer2013_ReportingDB.chm is the HTML Help build of the RDB reference. It includes only the tables, views, stored procedures (SProcs), and user-defined functions (UDFs) that are in the dbo user namespace of the Project Server database. 

    Note: The draft, published, and archive database objects are not documented. Project Server 2013 combines objects from the four Project Server 2010 databases into one database. The default name of the database is ProjectService; different Project Web App instances can have different database names.

    • OLAPCubeSchemas2013.xlsx includes a worksheet for each of the 14 OLAP cubes that are available to build with Project Server 2013. Each worksheet lists the dimensions, measures, and properties that are available in the cube.

    The Project Server 2013 RDB includes three new tables, 27 new views, and a total of 33 tables and views that include new fields. You can easily find the new items by searching, for example, for “New field” (with quotes). The following screenshot shows the new ProjectVisibilityMode field in the dbo.MSP_EpmProject_UserView view:

    imgSearchNewField_84 

    Project2013Reporting.exe

    MSDN Webcast: Project 2010 JS Grid Extensibility: Project Web App

    $
    0
    0

    Pat Malatack (Program Manager, Microsoft Corporation) has a comprehensive series of webcasts on extending the JS Grid in Project Web App.

    Note:  This blog post was originally created Monday, April 19, 2010. The webcasts were missing for the past several months, but have been reinstated on the Microsoft Events site (https://msevents.microsoft.com/).

    MSDN Webcast: Project 2010 JS Grid Extensibility: Project Web App (Part 1 of 3) (Level 400)
    Tuesday, April 20, 2010
    1:00 P.M.-2:00 P.M. Pacific Time
    This is the first webcast in a three-part series on extending grid pages in Microsoft Office Project Web App. In this webcast, we focus on initializing custom grid code and interactions between the grid and the Project Web App Ribbon. In particular, we show you how to add additional functionality to the Project Center.
     
    MSDN Webcast: Project 2010 JS Grid Extensibility: Project Web App (Part 2 of 3) (Level 400)
    Thursday, April 22, 2010
    1:00 P.M.-2:00 P.M. Pacific Time
    This is the second webcast in a three-part series on extending grid pages in Microsoft Office Project Web App. In this webcast, we focus on the use of events and delegates to interact with the timesheet grid in a way that allows for the addition of custom features and functionality to that page.
     
    MSDN Webcast: Project 2010 JS Grid Extensibility: Project Web App (Part 3 of 3) (Level 400)
    Tuesday, April 27, 2010
    1:00 P.M.-2:00 P.M. Pacific Time
    This is the third webcast in a three-part series on extending grid pages in Microsoft Office Project Web App. In this webcast, we walk you through more grid customizations, including adding custom commands to the column header dropdown and custom row header states.

    March 2013 update of the Project 2013 SDK download file

    $
    0
    0

    The Project 2013 SDK download is updated. The conceptual, how-to, and reference documentation in the download closely matches the Project 2013 developer documentation online content published on MSDN.

    The Project2013SDK.msi download file now installs properly on Windows 8 and Windows Server 2012.

    The Project 2013 SDK download contains:

    • The on-premises Reporting database schema reference, ProjectServer2013_ReportingDB.chm, and the OLAP cube schema reference. 
    • Updated VBA Help for local use. Objects such as Chart, Report, Series, and Shape now show correct members tables, properties, and methods topics.
    • Basic reference topics for the JavaScript client-side object model (JSOM), which includes REST endpoints and HTTP request syntax. You can use the JSOM for development of Project Online solutions for cross-browser web apps and for non-Windows platforms.
    • Sixteen complete code solutions, including two task pane apps (with minor updates) for Project, the QuickStatus app sample for Project Server and Project Online, eight client-side object model (CSOM) solutions, two solutions for querying the ProjectData service for reporting, and three updated legacy PSI solutions.
    • DLLs and a license for redistribution of the Project Server CSOM assemblies, JavaScript files for the CSOM, the Microsoft.Office.Project.Server.Library assembly, and the Microsoft.Office.Project.Server.Events.Receivers library for on-premises development.
      Notes:   1. The attached REDIST.zip file contains the RTM build 15.0.4420.1017 of the Project Server assemblies for redistribution.
                    2. The REDIST.zip file also includes the Microsoft.Office.Project.Schema.dll assembly, for developing event handlers.
                    3. Project CSOM solutions also require the redistributable DLLs for the SharePoint 2013 CSOM, 
                        which are at SharePoint Server 2013 Client Components SDK.
    • Updated Intellisense files for the PSI and CSOM, source code for creating a PSI proxy assembly, and instructions on how to update the PSI proxy files.
    • XML schemas for the Project client, AppProvisioning, and the Statusing PSI.

    The top-level online landing page for the Project SDK is Project for developers (http://msdn.microsoft.com/project).

    For additional Project-related SDK content, see Office for developers (http://msdn.microsoft.com/office), SharePoint for developers (http://msdn.microsoft.com/sharepoint), and Build apps for Office and SharePoint (http://msdn.microsoft.com/office/apps/). The two articles on Task pane apps for Project are in the Apps for Office and SharePoint SDK, and the JavaScript API for Office reference includes information specific for Project, the ProjectDocument object with eleven methods and three events, and four enumerations for Project.

    Want to try out Project 2013?

    1. Sign up for Project Online and Project Pro for Office 365
    2. Download Project Professional 2013 and Project Server 2013

    –Jim

    REDIST.zip

    Viewing all 19 articles
    Browse latest View live


    <script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>