Using ReaderSvg server-side

7 views
Skip to first unread message

ke...@home.se

unread,
Feb 6, 2009, 11:08:08 AM2/6/09
to WPF Graphics Site group
We need to convert svg to XAML in a webservice. Trying to call

UIElement importedElement = Ab2d.ReaderSvg.Instance.Read(@"C:
\filename.svg");

in the webservice results in exception:

The calling thread must be STA, because many UI components require
this.

To get rid of this we tried to create a new STA thread just to run the
conversion but then the above line results in exception:

The program issued a command but the command length is incorrect.
(Exception from HRESULT: 0x80070018)

I understand that the result creates WPF ViewBox objects etc. which
require STA thread but would it be possible to add a method to just
get the resulting XAML as a string? Then we could have input SVG as
string and get output XAML as string and use it all server-side. We
think ReaderSvg is an excellent product and if this functionality
could be added we will purchase it immediately!

ke...@home.se

unread,
Feb 20, 2009, 2:59:48 AM2/20/09
to WPF Graphics Site group
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();

Andrej Benedik

unread,
Feb 22, 2009, 2:42:11 PM2/22/09
to wpf-gr...@googlegroups.com
Mr.Kello,
 
thank you very much for sharing this with us.
 
I really did not expect such troubles on the server.
 
I would be possible to create a WPF-less version of ReaderSvg. But this would probably take quite a lot of time and time is a thing I do not have much.
 
Andrej

Reply all
Reply to author
Forward
0 new messages