We managed to solve this problem. You have to create a STA thread on
the server and run it in. The exception we got when doing this is
specific to framework 3.5 SP1 and have been solved in a hotfix which
is avilable here:
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361469
Below is a small web sample of doing the STA thread. It should be
noted that using this sample you will probably get memory leaks
because Micrsoft does not support using WPF object server-side. We are
doing some more WPF stuff server-side like scaling and converting
bitmap images so we have created classes to load WPF in a separate
AppDomain which then can be unloaded to avoid the memory leak issues.
This is not included in the sample.
It would still be very nice if Ab2d.ReaderSvg could support a WPF-less
mode where we could work only with strings because then we did not
have to do all these work-arounds.
Here is the sample. To use it just create a new web application in
visual studio (using framework 3.5), add references to
PresentationCore, PresentationFramework, WindowsBase, Ab2d.ReaderSvg
and put this in the code-behind of the default.aspx page:
protected void Page_Load(object sender, EventArgs e)
{
string svgFileName = @"C:\Test1.svg";
string xamlFileName = @"C:\Test1.xaml";
object[] threadParameter = { svgFileName, xamlFileName };
// Enable this to see exception "The calling thread must be STA,
because many UI components require this."
//ConvertToXAML(threadParameter);
RunUIMethodInSTAThread(ConvertToXAML, threadParameter);
Response.Write("DONE!");
}
public static void RunUIMethodInSTAThread(ParameterizedThreadStart
uiMethodToRun, object[] threadParameter)
{
Thread t = new Thread(uiMethodToRun);
t.SetApartmentState(ApartmentState.STA);
t.Start(threadParameter);
// Wait for thread to complete
if (!t.Join(30000))
{
t.Abort();
throw new ApplicationException("UI thread aborted due to
timeout");
}
}
private void ConvertToXAML(object parameter)
{
// Get params
object[] parameters = (object[])parameter;
string svgFileName = (string)parameters[0];
string xamlFileName = (string)parameters[1];
// Read Svg
byte[] bytes = File.ReadAllBytes(svgFileName);
MemoryStream svgStream = new MemoryStream(bytes);
Viewbox importedViewbox = Ab2d.ReaderSvg.Instance.Read
(svgStream);
UIElement innerCanvas = importedViewbox.Child;
// Write XAML file
FileStream fs = new FileStream(xamlFileName, FileMode.Create);
XamlWriter.Save(innerCanvas, fs);
fs.Dispose();