I'm trying to write a little utility to update encrypted passwords in MSD files. I would like to do this directly without updating the MXD and re-saving the MSD.
So far this is what I've tried... I extracted and updated the MSD (zip) by editing the WorkspaceConnectionString (see below) with a new encrypted password from IWorkspaceName2.
This is the connection string from inside the MSD -
>
<DataConnection xsi:type="typens:CIMStandardDataConnection"><WorkspaceConnectionString>ENCRYPTED_PASSWORD=...;SERVER=localhost;INSTANCE=sde:postgresql:localhost;DATABASE=sde;USER=sde;VERSION=sde.DEFAULT;AUTHENTICATION_MODE=DBMS</WorkspaceConnectionString><WorkspaceFactory>SDE</WorkspaceFactory><Dataset>sde.sde.bldg</Dataset></DataConnection>
This is the code I have to encrypt the password - I can swap out the ENCRYPTED_PASSWORD in the connection string for PASSWORD="swordfish" and pass it as ConnectionString to this. Unfortunately it first has to use OpenFromString which attempts to make an SDE connection. When it fails to connect I can't get the new ConnectionString.
private string GetSecureConnStr(string ConnectionString)
{
Type factoryType = Type.GetTypeFromProgID("esriDataSourcesGDB.SdeWorkspaceFactory");
IWorkspaceFactory2 workspaceFactory2 = (IWorkspaceFactory2)Activator.CreateInstance(factoryType);
IWorkspace ws = workspaceFactory2.OpenFromString(ConnectionString, 0);
IDataset dataset = (IDataset)ws;
IWorkspaceName2 wsName2 = (IWorkspaceName2)dataset.FullName;
return wsName2.ConnectionString;
}
After I get the updated connection string I can store it in the MSD with this -
private const bool UseRelativePath = false;
private const bool ValidateLayerConnection = false;
IMSDHelper helper = new MSDHelper();
helper.Open(msdFilePath);
var maps = helper.GetMaps();
for (var i = 0; i < maps.Count; i++)
{
var layers = helper.GetLayers(maps.Element);
for (var j = 0; j < layers.Count; j++)
{
helper.PutWorkspaceConnectionStringInLayer(layers.Element
}
}
helper.SaveAs(resultMsdFile, UseRelativePath);
}