DoubleJ's Sharepoint Blog
SharePoint 2007 - Getting the Document Conversion Services Started

I was recently trying to get the document conversion services started on my SharePoint farm, and noticed that I was getting errors in the windows event log.

Event ID: 6102, LoadBalancer.RegisterLauncher failed:  Unable to connect to the remote server

Event ID: 6066, Couldn't Register with Load Balancer:  Unable to connect to the remote server

Event ID: 6072, Failed to create the protected output directory

Event ID: 6062, Found 2 valid ip addresses for this machine.  Choosing this one:  x.x.x.x

Solving Event 6072

This error happens when the account running the launcher service can’t create a cache folder in C:\Program Files\Microsoft Office Servers\12.0\Bin. The folder that it’s trying to create is called HtmlTrLauncher.

Each time the service is started, this folder gets delete and re-created, to the service account needs to be able to create folders in the bin folder.

To do this, first check what account is running the launcher service. In Central Administration, go to operationsàService Accounts and select “document conversions launcher service” in the windows service drop down box. (alternatively, you can look in at the Office Document Conversions Launcher Service in the windows service console)

Check what account it is using to start the service. (in my case it was network service)

Go to the folder C:\Program Files\Microsoft Office Servers\12.0\Bin and right click and select “sharing and security”. Click the security tab and click add.

Add the user “Network Service” (or what every user you are using to start the service) and grant it “Modify” permissions.

Solving Event 6062

Open the Launcher and Load Balancer .config files in the office server bin folder (usually C:\Program Files\Microsoft Office Servers\12.0\Bin)

In the launcher file (Microsoft.Office.Server.Conversions.Launcher.exe.config) comment in the key "keyIPExclude" and set the value to the ip address(s) that you want to exclude. For example,

<add key="keyIPExclude" value="192\.168\.115\.14" />

In the load balancer file (Microsoft.Office.Server.Conversions.LoadBalancer.exe.config) add the ip exclude key to the <LoadBalancerSettings> section. For example,

<add key="keyIPExclude" value="192\.168\.115\.14" />

If you have multiple IP’s that you want to exclude use the following syntax for the key value

<add key="keyIPExclude" value=" (192\.168\.115\.14)|( 192\.168\.115\.15)” />

 

Solving Event 6102 and 6066

This error is seems to occur when the load balancer and the launcher servers are started on the same server. They are occurring because the launcher is starting before the load balancer. To solve this, we simply need to add a service dependency in windows.

1.       Run regedit

2.       Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services and locate the service (usually called DCLauncher)

3.       Open the 'DependOnService' key on the right side. If the service does not have a 'DependOnService' key, then create one by right-clicking and selecting New > Multi-String Value.

4.       In the value field, enter the string DCLoadBalancer (the name of the load balancer service)

5.       Click OK, close your registry and restart your machine.  

 

 

SharePoint Minesweeper...

I wanted to add something "fun" to my moss site Smile, and couldn't find any free stuff that even remotely fit the bill.

So, for some odd reason. I choose to port mine sweeper.

Here it is (incase your in the same boat as me)

Mine sweeper for sharepoint

(you'll have to have the following in your farm to make it work : targeted to .net 3.5, AJAX and session sate enabled)

 

Connection Strings in SharePoint 2007 with SSO

When writing ASP.NET applications, the question of where to save connection strings was quite straight forward, encrypted in the registry or in one of the .config files on the IIS server. So the question is where to save connection strings when you are developing for SharePoint?

Just to be clear, the methods we are all used to will still work, but they have their limitations... especially if there is more than one FE server in your farm. When you've got more than one FE sever, you need to make sure that the connection strings are the same across all the servers. Not really a problem when you only have one FE server... but add a couple more and you'll start having headaches.

So, this is where the Microsoft SSO service strolls onto the scene. They advertise is as a central credential store where we can keep all our sensitive username/password details. Hooray! If only it were that simple.

In this post, I'll explain how to save your connection strings in SSO.

Step One: Setup SSO

Setup SSO in your Farm. Ok, easier said than done! But that's a topic for another day.

Step Two: Create an Enterprise Application Definition (EAD)

  1. Load the Central Administration Console and navigate to Operationsà Manager Settings for Single Sign-on
  2. Click "Manage settings for enterprise application definitions" and then "New Item"
  3. In the form that opens, enter a 
    1. display name 
    2. application name (this is the name you'll use in code, so keep it simple), for this example, I'll use "Connection_myDB"
    3. any old email address 
    4. select "group"
    5. tick "windows authentication"
  4. In the logon account information, add an additional field call "connection string". The reason for this is so we can manage the other properties of the connection string outside of the code (server name, catalogue name, etc...)
  5. Click Ok

Step Three: Add Account Information

  1. Click on "Manage account information for enterprise application definitions" and select your EAD in the drop down box
  2. Enter "NT AUTHORITY\Authenticated Users" into the group account name
  3. Make sure "update account information" is selected and then click "set"
  4. Now you need to enter the details of the connection string, so for example
    1. Username = "my_db_user"
    2. Password = "my_secure_password"
    3. Connection String = "Application Name=App;Data Source=dbserver;Initial Catalog=mydb"
  5. Click Ok

Right, so now you have an EAD setup in SharePoint. Now let's use it in code.

Step Four: Coding

First, we'll need to add some assembly references and add the relevant using statements.

Windows® SharePoint® Services
(C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.dll)

Microsoft® Office SharePoint® Server component
(C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\ISAPI\Microsoft.SharePoint.Portal.SingleSignon.dll)

using Microsoft.SharePoint;
using Microsoft.SharePoint.Portal.SingleSignon;

Now, to get the details out of the SSO credential store we need to add the following code. I’ve implemented it as an assessor, but you can do as you please. Also, this assumes that the field names retrieved from the ApplicationField array will be in the same order as the fields in the Evidence array. It works for me, but it still needs more testing.

/// <summary>
/// Get the connection string from SSO
/// </summary>
private string ConnectionString
{
  get
    {
      try
        {
          StringBuilder lConnectionString = new StringBuilder("<conn>;User Id=<username>;Password=<pass>"); 

          //get credentials
          ISsoProvider lSSOProvider = SsoProviderFactory.GetSsoProvider();
          SsoCredentials lCredentials = lSSOProvider.GetCredentials("Connection_myDB");
          Application.ApplicationField[] lAppFields = lSSOProvider.GetApplicationFields("Connection_myDB");

          //build connection string
          for (int j = 0; j < lAppFields.Length; j++)
            {
               Application.ApplicationField lField = lAppFields[j];
               switch (lField.Field.ToLower().Replace(" ", ""))
               {
                  case "username" :
                     lConnectionString.Replace(
"<username>", convertToString(lCredentials.Evidence[j]));
                     break;
                  case "password":
                     lConnectionString.Replace(
"<pass>", convertToString(lCredentials.Evidence[j]));
                     break;
                  case "connectionstring":
                     lConnectionString.Replace(
"<conn>", convertToString(lCredentials.Evidence[j]));
                     break;
                 default:
                     lConnectionString.Append(lField.ToString());
                    break;
              }
            }
            //return connection string
           return lConnectionString.ToString();
       }
       catch (SingleSignonCredsNotFoundException ex)
       {
           return "Credentials Not Found in SSO Provider\n" + ex.Message;
       } 
       catch (SingleSignonException ex)
       {
       return ex.Message;
     }
   }
}

You’ll also need to add this function that converts a SecureString to a String. To be honest, this feels like a bit of a hack, so if you’ve got a better way please let me know.


/// <summary> /// Converts a System.Security.SecureString to System.String
/// </summary>
/// <param name="pValue"></param>
/// <returns></returns>
private string convertToString(System.Security.SecureString pValue)
{
    IntPtr lValuePointer = IntPtr.Zero;
    string lValueAsString;
    try
    {
        lValuePointer = System.Runtime.InteropServices.
Marshal.SecureStringToBSTR(pValue);
        lValueAsString = System.Runtime.InteropServices.
Marshal.PtrToStringBSTR(lValuePointer);
    }
    catch (Exception ex)
    {
        lValueAsString = ex.Message;
    }
    finally
    {
        if (lValuePointer != IntPtr.Zero) System.Runtime.InteropServices.Marshal.ZeroFreeBSTR(lValuePointer);
    }

    return lValueAsString;
}

That's it. you should now have a connection string stored in the SSO credential store.

My First Blog

Hey, this is my first blog. blah blah and all that jazz.

I suppose it's about time that i got around to having a blog, so here it is. yay. No thoughts, tips or, in fact, any even remotely useful or thought provoking for my first post. soz!