How to: Log on to Project Server Programmatically

This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.

Microsoft Office Project Server 2007 must authenticate the user of any application that integrates with the Project Server Interface (PSI). This article does the following:

  • Shows how to use the Project Server logon Web services to authenticate users with either Microsoft Windows credentials or a Project Server logon cookie.

  • Describes the key steps to create a sample application that demonstrates programmatic logon.

  • Shows how to handle SOAP errors and return error information.

  • Shows how to persist user settings using features in Microsoft Visual Studio 2005 and the .NET Framework 2.0.

Authentication verifies the identity of a user and is the first gate of entry into a system. Project Server supports two modes of authentication, Windows (NTLM) and Project Server authentication. There is a logon Web service for each authentication mode.

Authorization determines if a user has permission to perform a specified action or access data. After Project Server authenticates a user, it checks the user's permissions for every PSI request. For a general introduction to authentication, authorization, and Project Server permissions, see Project Server Security Primer.

To create a Windows sample application for programmatic logon, use the following procedures:

  1. Start a Visual Studio project and set the references and namespaces.

  2. Develop the Windows authentication code.

  3. Develop the Forms authentication code.

  4. Test the application using PSI methods.

  5. Install the application on a remote computer.

For a summary of key parts of the code described in the tables of procedures, see the Example section. The sample code uses the Login and Logoff methods of the LoginWindows and LoginForms Web services. It is not necessary for all applications to log on Project Server. For more information, see the code comments at the end of this article.

The complete source code of the sample application is available in the Project 2007 SDK Samples download.

Important noteImportant

You can develop Project Server applications either on a local Project Server computer or on a remote computer. In either case, you should use only a test Project Server installation, not a production server, to develop, test, and debug Project Server applications.

Windows Authentication

When a network user tries to connect with Project Server, Project Server validates the account name with the user's default credentials through the System.Net.CredentialCache object. Project Server integrates logon security with the Windows operating system by using the security attributes of an authenticated user on the network. Windows establishes a user's network security credentials at logon time by validating the credentials with a Windows domain controller.

Project Server determines the validated network user name and then permits or denies access without requiring the user to enter a logon name and password.

The following procedure explains how to set references in a PSI-based application for Project Server that uses Windows authentication.

Procedure 1. To start a project and set the references and namespaces:

  1. Create a new Windows application in Visual Studio 2005. For example, name the solution LoginDemo.

  2. Rename the default Form1.cs, for example, LogonProjectServer.cs.

  3. If you are developing on a separate computer, copy the Microsoft.Office.Project.Server.Library.dll assembly from the [Program Files]\Microsoft Office Servers\12.0\Bin directory on the Project Server computer to a convenient directory on your development computer. You use classes in the Microsoft.Office.Project.Server.Library namespace for many PSI calls. When you try to add a reference to some Project Server assemblies in Visual Studio, you may not see them on the .NET tab in the Add Reference dialog box.

    Note

    You can also unregister shfusion.dll to disable the Assembly Cache Viewer and copy assemblies from the [Windows]\assembly global assembly cache. Use the following command: Regsvr32 /u [Windows]\Microsoft.NET\Framework\v2.0.50727\shfusion.dll. You should re-register shfusion.dll when you have completed compiling the application, or have copied the assemblies you need to your development computer.

  4. In the Add Reference dialog box of Visual Studio Solution Explorer, click the Browse tab, browse to the Microsoft.Office.Project.Server.Library.dll, and then click OK.

  5. Add the following line to the global references in the LogonProjectServer.cs code:

    using PSLibrary = Microsoft.Office.Project.Server.Library;
    

    The Microsoft.Office.Project.Server.Library namespace includes the ProjectType enumeration used in the PSI call for creating new projects.

  6. Add the following global references to allow creating a CookieContainer object and to use the Sleep method:

    using System.Net;
    using System.Threading;
    
  7. Add a Web reference for the LoginWindows Web service.

    1. Right-click the References node in Solution Explorer, and click Add Web Reference.

    2. In the Add Web Reference dialog box, type the URL of each Web reference you need on the Project Server computer, and then click Go.

      http://ServerName/ProjectServerName/_vti_bin/PSI/LoginWindows.asmx
      

      Note

      The _vti_bin\PSI\ path works with the PSI Forwarder in installations where there are multiple Project Web Access servers.

    3. Add a Web references for each PSI Web service you need for the application. For example, add a reference to the Project Web service.

      http://ServerName/ProjectServerName/_vti_bin/PSI/Project.asmx
      
  8. Create static Web service objects to maintain the object data in memory. For example:

    namespace LoginDemo
    {
        public partial class LogonProjectServer : Form
        {
            . . .
            public static WebSvcLoginWindows.LoginWindows loginWindows = 
                new WebSvcLoginWindows.LoginWindows();
            public static CookieContainer cookies = new CookieContainer();
    
            public static WebSvcProject.Project project = 
                new LoginDemo.WebSvcProject.Project();
            . . .
    
  9. Add string constants and variables you need for the Web services and logon information. For example:

        private const string PROJECTWEBSERVICE = "_vti_bin/PSI/Project.asmx";
        private string baseUrl; // Example: http://ServerName/ProjectServer/
    

Procedure 2. To develop the Windows authentication code:

  1. Create a logon method that you can call from other methods or reuse in other applications. For example:

    public bool LogonPS(bool useWinLogon, string baseUrl, 
        string userName, string password)
    {
        const string LOGINWINDOWS = "_vti_bin/PSI/LoginWindows.asmx";
        const string LOGINFORMS = "_vti_bin/PSI/LoginForms.asmx";
        bool logonSucceeded = false;
    
        try
        {
            if (useWinLogon)
            {
                loginWindows.Url = baseUrl + LOGINWINDOWS;
                loginWindows.Credentials = CredentialCache.DefaultCredentials;
                if (loginWindows.Login()) logonSucceeded = true;
            }
        }
        // Catch statements
        return logonSucceeded;
    }
    
  2. Add catch statements for specific exceptions, such as the following:

    catch (System.Web.Services.Protocols.SoapException ex)
    {
        MessageBox.Show(ex.Message.ToString(), "Logon Error", 
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    catch (System.Net.WebException ex)
    {
        MessageBox.Show(ex.Message.ToString(), "Logon Error", 
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    
  3. Add a method that configures each of the PSI Web services you are using with the URL of the PSI Web service and the user's credentials or the Project Server logon cookie. For example, add a call to the AddContextInfo method from the LogonPS method.

    NoteNote

    In some cases, if you set the project.Url property after the project.CookieContainer object is loaded, the Project Web service does not initialize correctly and you must click the Log On button twice. If you move the project.Url statement before you set the other properties, the application works properly.

    public void AddContextInfo()
    {
        // Add the Url property first.
        project.Url = loginUtils.BaseUrl + PROJECTWEBSERVICE;
    
        if (winLogon) // Add Windows credentials
        {
            project.Credentials = CredentialCache.DefaultCredentials;
        }
    }
    
  4. If you want the application to allow users to explicitly log off, add a method such as LogoffPS. Make a call to a method that removes the credentials and cookies from the PSI Web service objects. There is no need to remove the Url property. For example, add the method RemoveContextInfo.

    public bool LogoffPS(bool useWinLogon)
    {
        bool loggedOff = true;
        try
        {
            if (useWinLogon) loginWindows.Logoff();
            else loginForms.Logoff();
        }
        // Add catch statements similar to the LogonPS catch statements,
        // and set loggedOff = false.
        }
        if (loggedOff) RemoveContextInfo()
        return loggedOff;
    }
    public void RemoveContextInfo()
    {
        if (useWinLogon)
        {
            project.Credentials = null;
        }
        else
        {
            project.CookieContainer = null;
        }
    }
    

Project Server (Forms) Authentication

The architecture of Windows SharePoint Services 3.0 enables the addition of custom membership providers for authentication. Two of the default membership providers are for Windows authentication and Basic authentication. Project Server 2007 does not use Basic authentication. A Project Server administrator can add a custom membership provider for authenticating users on both Project Server and Windows SharePoint Services.

NoteNote

The procedure for creating resources with Project Server credentials, where users log on with Project Server authentication, is different in Project Server 2007 than in earlier versions. Preparation includes creating a Microsoft SQL Server database (usually aspnetdb) for the membership provider, creating a Windows SharePoint Services site to use Forms authentication with the AspNetSqlMembershipProvider custom provider, and adding each user to three databases: Windows SharePoint Services, Project Server, and the SQL membership provider table.

When you use Project Web Access to add a Project Server user, it adds the user to the MSP_RESOURCE table in the Published database; it does not configure Windows SharePoint Services to use the SQL membership provider or create a SQL membership provider database. To help add or update resources for Project Server (Forms) authentication, the supplementary PjFormsAuthUpgrade.exe tool is installed with Project Server 2007 in the C:\Program Files\Microsoft Office Servers\12.0\Bin directory. For more information about setting up Forms authentication, see the Microsoft TechNet article Project Server 2007 Authentication.

The user credentials are stored in the Windows SharePoint Services content database, not in any of the Project Server databases. Windows SharePoint Services supports the membership providers for Windows authentication and Forms authentication with different Web application instances that use the same content database. For example, if the Project Server administrator has set up Forms authentication on port 81, the Project Server URL for logon would be http://ServerName:81/ProjectServerName/.

Authentication Cookie When a user provides the logon name and password for a Project Server user, Project Server calls the custom membership provider and verifies if the user is valid. If Windows SharePoint Services successfully authenticates a user, Project Server downloads a Project authentication cookie to the user's computer. The cookie is active only for a single session and times out after 20 minutes of inactivity. If the cookie expires, the user must log on to Project Server again.

On the Project Server computer, the Authenticate_Request method in global.asax checks if the user has a Project Server cookie. If so, Authenticate_Request takes no action; if not, it checks the Project Server membership provider for the user account. If the membership provider check fails, the user is redirected to the Project Server Request Access page.

The following procedure adds Forms authentication code to the application described in the previous procedures for Windows authentication.

Procedure 3. To develop the Forms authentication code

  1. Add a Web reference for the LoginForms Web service, the same way you added the LoginWindows Web reference.

    http://[ServerName]/[ProjectServerName]/_vti_bin/PSI/LoginForms.asmx
    
  2. Create a static LoginForms object:

    public static WebSvcLoginForms.LoginForms loginForms = 
        new WebSvcLoginForms.LoginForms();
    
  3. Add string variables for user name and password, and initialize the strings in your application. For example, the userName and password strings are class variables that you can initialize in user interface click event handlers.

        private string userName;
        private string password;
    
  4. Add a Forms logon option to the logon method you created for Windows logon. For example, add the following to the LogonPS method.

        if (useWinLogon)
        { . . . }
        else  // Use LoginForms
        {
            loginForms.Url = baseUrl + LOGINFORMS;
            loginForms.CookieContainer = cookies;
            if (loginForms.Login(userName, password)) 
                logonSucceeded = true;
        }     
    
  5. Add a Forms option to the log off method. For example, edit LogoffPS as follows.

        try
        {
            if (useWinLogon) loginWindows.Logoff();
            else loginForms.Logoff();
        }
    
  6. Add the Forms alternatives to the AddContextInfo and RemoveContextInfo methods as follows:

    public void AddContextInfo()
    {
        // Add the Url property first.
        . . .
        if (useWinLogon)  // Add Windows credentials
        { . . .}
        else     // Add Project Server logon cookie for Forms logon
        {
            project.CookieContainer = loginUtils.Cookies;
        }
    }
    
    public void RemoveContextInfo()
    {
        if (useWinLogon)
        { . . . }
        else
        {
            project.CookieContainer = null;
        }
    }
    

Testing Windows and Forms Authentication

The LoginDemo.exe sample application allows you to log on and log off a specified Project Server URL. The Create Project button click event handler includes a reference to the Project Web service and code to create and publish a project. Figure 1 shows the user interface of the sample LoginDemo.exe application.

You can try to create a project when you are logged on or when you are logged off. However, you should get an Unauthorized (HTTP 401) error if you try to create a project when you are logged off.

Figure 1. Test application for programmatic logon

Test application for programmatic logon

For more information about using a ProjectDataSet and the code for creating and publishing a project, see Using Project Server DataSet Objects.

Procedure 4. To test the sample application using PSI methods:

  1. Add a user interface element that calls a PSI method. For example, add the code to create a project in the btnCreateProject_Click event handler.

    private void btnCreateProject_Click(object sender, EventArgs e)
    {
        . . .
        try
        {
            WebSvcProject.ProjectDataSet dsProject = 
                new WebSvcProject.ProjectDataSet();
            WebSvcProject.ProjectDataSet.ProjectRow projectRow = 
                dsProject.Project.NewProjectRow();
    
            Guid projectGuid = Guid.NewGuid();
            projectRow.PROJ_UID = projectGuid;
            projectRow.PROJ_NAME = this.txtProjectName.Text;
            projectRow.PROJ_TYPE = 
                Convert.ToInt32(PSLibrary.Project.ProjectType.Project);
    
            dsProject.Project.AddProjectRow(projectRow);
    
            Guid jobGuid = Guid.NewGuid();
            bool validateOnly = false;
            project.QueueCreateProject(jobGuid, dsProject, validateOnly);
    
            // Wait 3 seconds (more or less) for Queue job to complete.
            // Or, add a routine that checks the QueueSystem for job completion.
            System.Threading.Thread.Sleep(3000);
    
            WebSvcProject.ProjectRelationsDataSet dsProjectRelations =
                new WebSvcProject.ProjectRelationsDataSet();
    
            jobGuid = Guid.NewGuid();
            // Set wssUrl = "" for the default WSS project workspace
            string wssUrl = "";
            bool fullPublish = true;
            dsProjectRelations = project.QueuePublish(jobGuid, 
                projectGuid, fullPublish, wssUrl);
        }
        // Add catch statements
    }
    

    The QueueCreateProject method saves a new project in the Draft database. The QueuePublish method publishes the draft project to the Published database.

    NoteNote

    The Project Server Queuing service may not immediately save the project data to the Draft or Published databases. The Queuing Service is an asynchronous process.

    For a sample method that uses the QueueSystem methods to wait for a queue job to complete, see How to: Use the QueueSystem Web Service.

  2. Add specific catch statements for the cases when you are logged off (a WebException), or when there is a connection error (a SoapException).

    catch (System.Web.Services.Protocols.SoapException ex)
    {
        string errMess = "";
        PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
        PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();
    
        for (int j = 0; j < errors.Length; j++)
            errMess = errMess + errors[j].ErrId.ToString() + "\n";
        errMess = errMess + "\n" + ex.Message.ToString();
    
        MessageBox.Show(errMess, "Error", MessageBoxButtons.OK,
            MessageBoxIcon.Error);
    }
    catch (WebException ex)
    {
        string message = ex.Message.ToString() +
            "\n\nLog on, or check the Project Server Queuing Service";
        MessageBox.Show(message, "Project Creation Error", 
            MessageBoxButtons.OK, MessageBoxIcon.Error);
    }
    
  3. Run the sample application and type the correct value in the Project Server URL text box(see Figure 1). For Forms authentication, be sure to include the correct port, for example, http://ServerName:81/ProjectServerName/. If you do not include the port for a Forms authentication logon, the user gets a 401 error.

  4. Click Save URL to save the value to your user.config file. For information about the .NET Framework 2.0 application and user configuration properties, see the code comments at the end of this article.

  5. Click Log On. After some time, if the logon is successful, you should see the label Logon Succeeded.

  6. Try creating a project when you are logged on, and when you are logged off. If you are on a remote computer, you get the WebException exception handler message when you are logged off.

Procedure 5. To install the application on a remote computer:

  1. Copy the compiled executable file and the application configuration files to the same directory on the remote computer. For the sample application, copy the following files:

    • LoginDemo.exe

    • LoginDemo.exe.config

  2. Copy the Project Server assemblies that the application references to the same directory as the application on the remote computer. For the sample application, copy the following:

    Microsoft.Office.Project.Server.Library.dll

  3. Alternately, you can create a setup project for the application using Visual Studio. For more information, see Setup and Deployment Projects in Visual Studio Help.

Example

The following code sample shows the key parts of the sample application described in the previous procedures. The code sample does not show all methods, event handlers, or variables related to operation of the LoginDemo.exe application user interface. For the complete Visual Studio 2005 solution source code, see the LoginDemo sample in the Project 2007 SDK download.

using System;
using System.Net;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Web.Services.Protocols;
using System.Threading;
using PSLibrary = Microsoft.Office.Project.Server.Library;

namespace LoginDemo
{
    public partial class LogonProjectServer : Form
    {
        . . .
        private const string PROJECTWEBSERVICE = "_vti_bin/PSI/Project.asmx";
        private string baseUrl; // Example: http://ServerName/ProjectServer/
        private string userName;
        private string password;
        . . .
        public static WebSvcLoginWindows.LoginWindows loginWindows = 
            new WebSvcLoginWindows.LoginWindows();
        public static WebSvcLoginForms.LoginForms loginForms = 
            new WebSvcLoginForms.LoginForms();
        public static CookieContainer cookies = new CookieContainer();

        public static WebSvcProject.Project project = 
            new LoginDemo.WebSvcProject.Project();

        public LogonProjectServer()
        {
            InitializeComponent();
            . . .
            //Get the user.config or the default for the 
            //  ProjectServerUrl property setting
            txtProjectServerUrl.Text = Properties.Settings.Default.ProjectServerUrl;
        }
    /*
       Additional code for user interface operation goes here
    */
        private void btnLogon_Click(object sender, EventArgs e)
        {
            baseUrl = txtProjectServerUrl.Text;
            . . .
            loggedOn = LogonPS(winLogon, baseUrl, userName, password);
            . . .
        }

        private void btnLogOff_Click(object sender, EventArgs e)
        {
            if (LogoffPS(winLogon))
            {
                // Add user interface actions here 
            }
        }

        private void btnSaveUrl_Click(object sender, EventArgs e)
        {
            //Save the ProjectServerUrl property to the user.config file.
            Properties.Settings.Default.ProjectServerUrl = txtProjectServerUrl.Text;
            Properties.Settings.Default.Save();
        }

        /// <summary>
        /// Log on Project Server
        /// </summary>
        /// <param name="useWinLogon"></param>
        /// <param name="baseUrl"></param>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns>true for successful logon</returns>
        public bool LogonPS(bool useWinLogon, string baseUrl, 
            string userName, string password)
        {
            const string LOGINWINDOWS = "_vti_bin/PSI/LoginWindows.asmx";
            const string LOGINFORMS = "_vti_bin/PSI/LoginForms.asmx";
            bool logonSucceeded = false;

            try
            {
                if (useWinLogon)
                {
                    loginWindows.Url = baseUrl + LOGINWINDOWS;

                    loginWindows.Credentials = CredentialCache.DefaultCredentials;

                    if (loginWindows.Login()) logonSucceeded = true;
                }
                else  // Use LoginForms
                {
                    loginForms.Url = baseUrl + LOGINFORMS;
                    loginForms.CookieContainer = cookies;

                    if (loginForms.Login(userName, password)) logonSucceeded = true;
                }
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Logon Error", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            catch (System.Net.WebException ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Logon Error", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            if (logonSucceeded) AddContextInfo();
            return logonSucceeded;
        }

        /// <summary>
        /// Log off Project Server
        /// </summary>
        /// <param name="useWinLogon"></param>
        /// <returns>true for successful logoff</returns>
        public bool LogoffPS(bool useWinLogon)
        {
            bool loggedOff = true;
            try
            {
                if (useWinLogon)                     loginWindows.Logoff();
                else loginForms.Logoff();
            }
            catch (System.Web.Services.Protocols.SoapException ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Logon Error", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                loggedOff = false;
            }
            catch (System.Net.WebException ex)
            {
                MessageBox.Show(ex.Message.ToString(), "Logoff Error", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
                loggedOff = false;
            }
            if (loggedOff) RemoveContextInfo();
           return loggedOff;
        }

        /// <summary>
        /// Add the URL, and the user credentials or logon cookie, to each 
        /// PSI Web service object in the application.
        /// </summary>
        public void AddContextInfo()
        {
            // Add the Url property first.
            project.Url = loginUtils.BaseUrl + PROJECTWEBSERVICE;

            if (winLogon)   // Add Windows credentials
            {
                project.Credentials = CredentialCache.DefaultCredentials;
            }
            else            // Add Project Server logon cookie for Forms logon
            {
                project.CookieContainer = loginUtils.Cookies;
            }
        }

        /// <summary>
        /// Remove the user credentials or logon cookie from each PSI Web service object.
        /// </summary>
        public void RemoveContextInfo()
        {
            if (winLogon)
            {
                project.Credentials = null;
            }
            else
            {
                project.CookieContainer = null;
            }
        }
        /// <summary>
        /// Test the application with a PSI call. For example, create a project. 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void btnCreateProject_Click(object sender, EventArgs e)
        {
            string projectCreatedLabel = "Project created!";
            lblProjectCreated.Text = "";
            this.Cursor = Cursors.WaitCursor;

            try
            {
                WebSvcProject.ProjectDataSet dsProject = 
                    new WebSvcProject.ProjectDataSet();
                WebSvcProject.ProjectDataSet.ProjectRow projectRow = 
                    dsProject.Project.NewProjectRow();

                Guid projectGuid = Guid.NewGuid();
                projectRow.PROJ_UID = projectGuid();
                projectRow.PROJ_NAME = this.txtProjectName.Text;
                projectRow.PROJ_TYPE = Convert.ToInt32(PSLibrary.Project.ProjectType.Project);

                dsProject.Project.AddProjectRow(projectRow);

                Guid jobGuid = Guid.NewGuid();
                bool validateOnly = false;
                project.QueueCreateProject(jobGuid, dsProject, validateOnly);

                // Wait 3 seconds (more or less) for Queue job to complete.
                // Or, add a routine that checks the QueueSystem for job completion.
                System.Threading.Thread.Sleep(3000);
                WebSvcProject.ProjectRelationsDataSet dsProjectRelations =
                    new WebSvcProject.ProjectRelationsDataSet();

                jobGuid = Guid.NewGuid();
                // Set wssUrl = "" to have default WSS project workspace
                string wssUrl = "";
                bool fullPublish = true;
                dsProjectRelations = project.QueuePublish(jobGuid, 
                    projectGuid, fullPublish, wssUrl);
            }
            catch (SoapException ex)
            {
                string errMess = "";
                PSLibrary.PSClientError error = new PSLibrary.PSClientError(ex);
                PSLibrary.PSErrorInfo[] errors = error.GetAllErrors();

                for (int j = 0; j < errors.Length; j++)
                {
                    errMess = errMess + errors[j].ErrId.ToString() + "\n";
                }
                errMess = errMess + "\n" + ex.Message.ToString();

                MessageBox.Show(errMess, "Error", MessageBoxButtons.OK,
                    MessageBoxIcon.Error);
            }
            catch (WebException ex)
            {
                string message = ex.Message.ToString() +
                    "\n\nLog on, or check the Project Server Queuing Service";
                MessageBox.Show(message, "Project Creation Error", 
                    MessageBoxButtons.OK, MessageBoxIcon.Error);
            }            this.Cursor = Cursors.Default;
            lblProjectCreated.Text = projectCreatedLabel;
            lblProjectCreated.Visible = true;
        }
    }
}
NoteNote

It is not necessary to use the Login method of LoginWindows or LoginForms in all cases. For example, if a custom Web Part runs only within Project Web Access, the user is already logged on. You can set the Url, Credentials, and CookieContainer properties of a PSI object such as ProjectWebSvc.Project, and use the object methods, as long as the user has a Project Server account and the necessary permissions. Using the Login method simply allows you to check whether the user is valid before calling other PSI methods.

The LogonProjectServer class constructor includes the following line to initialize the Project Server URL text box contents.

txtProjectServerUrl.Text = Properties.Settings.Default.ProjectServerUrl;

Visual Studio 2005 supports the Properties.Settings class in the .NET Framework 2.0. Visual Studio makes it easy to manage default application settings as well as user settings in the new XML schema for the app.config file.

In the Project 2007 SDK\Code Samples\LoginDemo directory of the SDK Samples download, open LoginDemo.sln. Expand the Properties node in Solution Explorer, and then double-click Settings.settings. You can see ProjectServerUrl is a user setting and DefaultProjectServerUrl is an application setting.

The sample application has a Save URL button (Figure 1) with the following event handler:

private void btnSaveUrl_Click(object sender, EventArgs e)
{
    //Save the ProjectServerUrl property to the user.config file.
    Properties.Settings.Default.ProjectServerUrl = txtProjectServerUrl.Text;
    Properties.Settings.Default.Save();
}

When a user clicks Save URL, the Save method in the .NET Framework default properties manager creates a user.config file and saves the information in the ProjectServerUrl property. The user.config file is in a Documents and Settings directory such as the following (where [UserName] is the user's logon name):

C:\Documents and Settings\[UserName]\Local Settings\Application Data\Microsoft\LoginDemo.exe_Url_ugtthxn0gpg3wlqcjobeszfplyyrreqo\1.0.0.0

The properties manager is a security improvement in the .NET Framework 2.0, where user settings are kept separate from each other on the same computer and separate from global application settings. For example, the user.config file of the sample application contains the following data:

<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <userSettings>
        <LoginDemo.Properties.Settings>
            <setting name="ProjectServerUrl" serializeAs="String">
                <value>http://UsersServerName/ProjectServer/</value>
            </setting>
        </LoginDemo.Properties.Settings>
    </userSettings>
</configuration>

See Also

Tasks

How to: Use the QueueSystem Web Service

Concepts

Using the PSI in Visual Studio

Project Server Security Primer

Using Project Server DataSet Objects

Other Resources

Project Server Interface (PSI) Overview

Assembly Cache Viewer

Project Server 2007 Authentication