Skip to content
Mar 4 / Michaël Hompus

"CS0122: 'x' is inaccessible due to its protection level" but you don't want to go public

Sometimes you have to split your code into different assemblies. For example when I created a custom Admin Page which inherits from WebAdminPageBase (Microsoft.SharePoint.ApplicationPages). The problem with Microsoft.SharePoint.ApplicationPages is that it’s not deployed to the GAC.

Putting a reference to this assembly from my assembly, also containing custom webparts and other controls which have to be registered as SafeControls in the web.config, will result in deployment troubles when you use a WSP file. The problem is when SharePoint is going to register the safecontrols it will reflect your assemby and won’t be able to access the Microsoft.SharePoint.ApplicationPages assembly because it’s not available in the GAC. The same problem can be found using the Content Deployment option.

So you split your code in 2 assemblies, for example foo.bar and foo.bar.ApplicationPages. But when your custom application page is depending on an internal type declared in foo.bar you are in trouble. When compiling you will get the following message:

"CS0122: 'foo.bar.x' is inaccessible due to its protection level"

No you have only one choice: make x public. Or not?

It’s also possible to make your assembly share it’s internals with other assemblies. Add the following to you code (in foo.bar):

[assembly: InternalsVisibleTo("foo.bar.ApplicationPages,
PublicKey=0a240a ... c2f34c7")]

But the public key is not your public key token. Thanks to Burt Harris’s comment at the InternalsVisibleToAttribute Class you can find your real public key using the following command:

sn.exe -Tp foo.bar.dll

Now compile your project and there you go!

Oct 31 / Michaël Hompus

Project Conference 2007

It’s been a while having time and content to post on this blog but I’m back again. :)

I’m currently at the Project Conference 2007 in Seattle and by visiting the sessions and talking to the guys at Microsoft developing the solution I got a lot of answers for things I couldn’t find on the web or in the SDK.
The next couple of weeks I will try to post the things I found out.

Also Prometric was present so you could do the official Project exams. Being bold I just entered the “Managing Projects with Microsoft Office Project Server” exam and guess what, I’m now a Microsoft Certified Technology Specialist!

Sep 7 / Michaël Hompus

Pitfall: Using the SiteData WS to get the SiteGuid

When you want to use the PSI interface you need to have a PSContextInfo object. Inside a Project Server event this will be provided so you don’t need to worry about it’s contents (except when you want to impersonate as a different user). But outside the event you will need to create one from scratch.
One of the properties you need is the SiteGuid. According to the SDK you can get this value in your code using three different methods:

  1. Hard-code the Guid (Not very flexible)
  2. Use the Windows SharePoint Services SPSite.ID property in the Windows SharePoint Services (Very heavy on resources)
  3. Call the sitedata web service with the PWA URL (The best solution if you ask me)

I use the third option in my application, but it returned the wrong Guid. After some debugging I finally found the problem, I requested the URL “http://localhost/PWA/” and there I made my mistake. The trailing / results in getting the Guid of the root site, not the PWA site!

I’m sure I’m not the first one falling in this pitfall, but I’m writting this to prevent you from doing the same. :)

Sep 7 / Michaël Hompus

An addition to the Project Server 2007 SDK (Part 2)

I was browsing through the TimePeriodDataSet.TimePeriodsRow Members and found the following empty entries I could fill:

Name

Description

Enumeration

RES_TIMESHEET_MGR_UID

Specifies the resource unique identifier of the (next) enterprise resource reviewing on this timesheet.

 

TS_WEEK_STARTS_ON

Specifies the first day of the week for this timesheet.

0 = Sunday
1 = Monday
2 = Tuesday
3 = Wednesday
4 = Thursday
5 = Friday
6 = Saturday

WPRD_UID

Specifies the period unique identifier of the timeperiod.

 
Sep 7 / Michaël Hompus

Installer Application Folder

To deploy our code we create MSI installers using Visual Studio. One problem I encountered is that there is no property available in code to know where the user has chosen to install the application.
After some searching and testing I now use the following code to get the installation path:

 

// Installer Application Folderstring installPath = Context.Parameters["assemblypath"];installPath = installPath.Substring(0, installPath.LastIndexOf("\\"));

if (!installPath.EndsWith("\\")){    installPath += "\\";}

 

That’s all.

Sep 4 / Michaël Hompus

Using app.config with Project Server Events

When building custom Project Server Event Receivers the result is a dll file. Using app.config and the ConfigurationManagement class will not work.
Well actually it’s possible!

The “Microsoft Office Project Server Events Service” executable has it’s own app.config where you can add entries. If you go to the Project Server bin directory (default: C:\Program Files\Microsoft Office Servers\12.0\Bin) you will find the config file named “Microsoft.Office.Project.Server.Eventing.exe.config”.

Add the appSettings section like this:

<configuration>   <runtime>      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">         <probing privatePath="ProjectServerEventHandlers"/>      </assemblyBinding>   </runtime>   <appSettings>      <add key="SSP Location" value="http://localhost:56737/SharedServices1" />   </appSettings></configuration>

and your application can happily use the following syntax:

ConfigurationManager.AppSettings["SSP Location"]

This can make your event just a bit easier to deploy in different configurations without the recompiling or use of extra configuration libraries.

Sep 4 / Michaël Hompus

Textbox “Process Accounts with Access to the SSP” doesn’t exist

I had a lot of trouble using impersonation with the PSI webservices in Project Server 2007. I found some posts on the web suggesting that you need to add the account to the “Process Accounts with Access to the SSP” textbox, but guess what? That box was nowhere to find!

I found one post in the “Setup/Installation Related FAQ’s” of the “Project Server 2007 VSTS Connector” on codeplex. It says:

Sometimes the textbox for “Process Accounts with Access to the SSP” will not exist on the web page. To add the account in this circumstance, go to the command line, navigate to Program Files\Common Files\Microsoft Shared\web server extensions\12\BIN and run:

stsadm.exe -o editssp -title <sspname> -setaccounts <accounts>

So since my SSP is called “SharedServices1″ to following line did miracles:

stsadm.exe -o editssp -title SharedServices1 -setaccounts domain\user

Reading the documentation of the stsadm application, it mentiones that “New process accounts should be appended to the existing list”. So if you execute the above line any existing configuration of accounts will be gone.

To view a list of current configured account you can use the -enumssp option:

stsadm.exe -o enumssp -title SharedServices1

This will return the details of the SSP (in XML):

<ssps>  <ssp name="SharedServices1" default="true" ssl="False" status="Online">    <account username="NT AUTHORITY\NETWORK SERVICE" />    <site type="Administration" url="http://server:4389/ssp/admin" />    <database type="ServiceDatabase" server="server\OfficeServers" name="SharedServices1_DB_2b6d2c6a-2374-4f0f-8d1e-e4577988aa80" authentication="Windows">    <processaccounts>      <account username="domain\user">    </processaccounts>    <associatedwebapplications>      <webapplication name="SharePoint - 4389" url="http://server:4389/" />      <webapplication name="SharePoint - 80" url="http://server/" />    </associatedwebapplications>  </ssp></ssps>
Aug 31 / Michaël Hompus

An addition to the Project Server 2007 SDK

Currently I’m working on a project which uses Microsoft Project Server 2007. However the SDK is poorly documented. Today I was looking at the Admin web service which can be used to configure settings on the server. In this post I’m not going in to detail how to do this, but I’ll share with you what I’ve discovered.

I’ve researched the connection between PWA’s “Task Settings and Display” page and the properties on the StatusingSettingsRow class which were not described. See the following image:

 
So in addition to the SDK:

Name

Description

Enumeration

WADMIN_DEFAULT_TRACKING_METHOD

Specify the default method for reporting progress or tasks, and whether the tracking mode should be enforced on all projects.

1 = Hours of work done per period.

2 = Percent of work complete.

3 = Actual work done and work remaining.

WADMIN_IS_TRACKING_METHOD_LOCKED

Force project managers to use the progress reporting method specified above for all projects.

 

WADMIN_PROTECT_ACTUALS

Restrict updates to Project Web Access.

 

WADMIN_STAT_ENABLE_DOWNLOAD

Enable ActiveX Gantt view for all users.

 

WADMIN_STAT_LOOK_AHEAD

Current tasks are those tasks which are not older than or further in the future more than this amount of days.

 

WADMIN_STAT_TIMESHEET_TIED

Time entry by Timesheet only. Users will sync to update tasks.

 

WADMIN_TS_DEF_ENTRY_MODE_ENUM

Specify how you want resources to report their hours.

0 = Resources should report their hours worked every day.

1 = Resources should report their total hours worked for a week.

WADMIN_WEEK_START_ON_ENUM

Week starts on this day.

0 = Sunday
1 = Monday
2 = Tuesday
3 = Wednesday
4 = Thursday
5 = Friday
6 = Saturday