Wednesday, August 08, 2007

MOSS GetUserProfileByIndex(int index) unexpected behaviour

We are trying to get a list of user profiles from MOSS using the UserProfile WebService. We were assuming that as each user gets created the index is incremented by one, so we could do a for next loop to get them all, however this gives errors.

Here is the solution from Microsoft:
------------------
We are using the GetUserProfileByIndex(int index) method in a for loop looping from index = 0 to index = (GetUserProfileCount() -1) value.

This is however not the right approach.

While the profiles are created and deleted the profile list does not keep continuous indexing (e.g. if you have 10 profiles indexed from 0 to 9 and then you delete profiles (5) and (6) there will be a gap - indexes 5 and 6 will not be used. Adding new profiles to the list will not insert them into the gap, but will append them to the end of the list. So, if after deleting profiles (5) and (6) you add 3 new profiles the indexes will be as follows {0, 1, 2, 3, 4, 7, 8, 9, 10, 11, 12}). If you would run a for loop for this list for the indexes 0 to (GetUserProfileCount() -1), so 0 to 10, you would never get the profiles (11) and (12) returned and you would get the profile (7) returned 3 times (if a profile under a given index is missing the function returns the next available one).

The right approach is to use the NextValue field of the GetUserProfileByIndexResult object returned by the GetUserProfileByIndex(int index) function. This field contains a string value indicating the next valid index in the profile list. The string value needs to be converted into an integer and then used in the next call of the GetUserProfileByIndex(int index) function as the index. The fist value in the list can be obtained by using an index <= 0.
The pseudo code for extracting all the user profiles:

p = GetUserProfileByIndex(-1); // gets the first profile on the list
While (p.UserProfile != null)
{
// do what you want with the User Profile
.....
.....
.....
int nextValue = ConvertToInteger(p.NextValue);
p = GetUserProfileByIndex(nextValue);
}

Tuesday, August 07, 2007

Updated Fiddler2 Extensions

Fiddler is a really usefull debugging tool to see what is really happening between Internet Explorer and applications. Updated Fiddler2 Extensions shows new extension
MSDN link to Fiddler

Sunday, August 05, 2007

VSTO 2005 SE Outlook Addin Deployment problems

I was initially impressed by how easy it was to create and Outlook 2007 addin using VSTO2005 SE. The addin works fine on the development machine, however trying to deploy it has been a nightmare.

On the machine which you are deploying to, the first thing was (I didnt realise probably because I didnt read the instruction manual closely enough) that you must install the VSTO2005 SE run time, however you should only do this after you make sure that the Office PIAs are installed. Apparently this is because the VSTO2005 run time updates one of the Office PIA DLLs. You should also initially make sure that dotNet 2.0 is installed otherwise VSTO2005 SE wont run.

The next issue is to get your custom DLL trusted by dotNet. This is a lot easier said than done.


Identifying the problem
The first problem I had was actually finding out why my Outlook addin would run. It would run fine on my VS dev. machine, however Outlook just kept disabling it. I found a really helpful forum post here which says that if you set the environment variable VSTO_SUPPRESSDISPLAYALERTS to 0 (zero) then VST will display all errors that occur during startup. You can also get the errors logged to a file by setting the environment variable VSTO_LOGALERTS variable to 1 (one). This creates the log file in the folder that contains the application manifest. The default name is .manifest.log. (See MS Article Debugging in Application-Level Projects)

Debugging the problem

The startup error I found was "Failed to grant permission to execute." Basically this means that dotNet is not trusting your assembly on the deployment machine. (Note: once Office starts with and Addin error, it helpfully disables it for you. To re-enable it update the registry key HKCU\Software\Microsoft\Office\Outlook\Addins\youraddin.connect\LoadBehavior = 3. After a failed load Outlook will have set it to 2)

To enable security on the DLLs, there is an MSDN article on adding a SetSecurity project to your existing project (available from MS here). You then update the setup deployment project for the custom action data for the Install method (full info here)- I couldnt get this to work.

Some people suggested trying to bypass the windows CAS and give enough security-level to the addin. You could use CASPOL or add the assembly to the GAC (dragging and dropping it at c:\windows\assembly) - however I cant get either of these to work in Vista. Adding the assembly to the GAC on XP fixes the addin load permissions problem. (To add your assembly to the GAC you will need to sign it with a key in VS2005 to make it a strong assembly).

So after more than a days work trying to deploy my Outlook addin - I have a workaround with XP where I can use the GAC and have made no progress on getting it deployed using SetSecurity or on Vista!

References
Deploying Visual Studio 2005 Tools for Office Second Edition Solutions Using Windows Installer
Visual Studio Developer Center - Debugging in Application-Level Projects
Microsoft .Net Framework 2.0
Microsoft Office 2007 Primary Interop Assemblies
Microsoft Visual Studio Tools for Office 2005 Second edition runtime

Outlook 2007 Free/Busy FTP Publisher
Outlook Redemption