Het lijkt erop dat dit bestand een binaire geserialiseerde versie is van Microsoft.SqlServer.Management.UserSettings.SqlStudio
klasse gedefinieerd in de Microsoft.SqlServer.Management.UserSettings, Version=10.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91 assembly (te vinden op c:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Microsoft.SqlServer.Management.UserSettings.dll ).
Met een beetje ontwikkelvaardigheid (Visual Studio of zelfs Powershell) kun je dit bestand deserialiseren naar de originele klasse, de items vinden die je wilt verwijderen en het bestand opnieuw serialiseren.
Dit zou je een idee moeten geven (werken aan een kopie van het .bin-bestand)...
var binaryFormatter = new BinaryFormatter();
var inStream = new MemoryStream(File.ReadAllBytes(@"c:\temp\SqlStudio.bin"));
var settings = (SqlStudio) binaryFormatter.Deserialize(inStream);
foreach (var pair in settings.SSMS.ConnectionOptions.ServerTypes)
{
ServerTypeItem serverTypeItem = pair.Value;
List<ServerConnectionItem> toRemove = new List<ServerConnectionItem>();
foreach (ServerConnectionItem server in serverTypeItem.Servers)
{
if (server.Instance != "the server you want to remove")
{
continue;
}
toRemove.Add(server);
}
foreach (ServerConnectionItem serverConnectionItem in toRemove)
{
serverTypeItem.Servers.RemoveItem(serverConnectionItem);
}
}
MemoryStream outStream = new MemoryStream();
binaryFormatter.Serialize(outStream, settings);
byte[] outBytes = new byte[outStream.Length];
outStream.Position = 0;
outStream.Read(outBytes, 0, outBytes.Length);
File.WriteAllBytes(@"c:\temp\SqlStudio.bin", outBytes);
Na de vraag van Adrian probeerde ik dit opnieuw op een Win7 x64-box met Visual Studio 2010. Ik vond dezelfde fout, dus na wat graven ontdekte ik dat er een aantal stappen nodig waren om het op te lossen.
- Stel het Platform-doel in op 'x86' in de projecteigenschappen
- voeg een verwijzing toe naar Microsoft.SqlServer.Management.SDK.SqlStudio (op mijn box was dit in c:\Program Files\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\Microsoft.SqlServer.Management .Sdk.SqlStudio.dll)
- voeg een verwijzing toe naar Microsoft.SqlServer.Management.UserSettings (in dezelfde map als de vorige)
- voer aangepaste montageresolutie uit
De aangepaste assembly-resolutie kostte wat moeite, omdat het niet duidelijk was (voor mij althans) waarom de CLR de assembly niet gewoon correct zou oplossen en waarom Visual Studio me niet zou toestaan om de referentie handmatig toe te voegen. Ik heb het over de SqlWorkbench.Interfaces.dll.
De bijgewerkte code ziet er als volgt uit:
internal class Program
{
static void Main(string[] args)
{
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
var binaryFormatter = new BinaryFormatter();
var inStream = new MemoryStream(File.ReadAllBytes(@"c:\temp\SqlStudio.bin"));
var settings = (SqlStudio) binaryFormatter.Deserialize(inStream);
foreach (var pair in settings.SSMS.ConnectionOptions.ServerTypes)
{
ServerTypeItem serverTypeItem = pair.Value;
List<ServerConnectionItem> toRemove = new List<ServerConnectionItem>();
foreach (ServerConnectionItem server in serverTypeItem.Servers)
{
if (server.Instance != "the server you want to remove")
{
continue;
}
toRemove.Add(server);
}
foreach (ServerConnectionItem serverConnectionItem in toRemove)
{
serverTypeItem.Servers.RemoveItem(serverConnectionItem);
}
}
MemoryStream outStream = new MemoryStream();
binaryFormatter.Serialize(outStream, settings);
byte[] outBytes = new byte[outStream.Length];
outStream.Position = 0;
outStream.Read(outBytes, 0, outBytes.Length);
File.WriteAllBytes(@"c:\temp\SqlStudio.bin", outBytes);
}
private static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
{
Debug.WriteLine(args.Name);
if (args.Name.StartsWith("SqlWorkbench.Interfaces"))
{
return Assembly.LoadFrom(@"C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\VSShell\Common7\IDE\SqlWorkbench.Interfaces.dll");
}
return Assembly.Load(args.Name);
}
}