Exception thrown by Microsoft.Glee.GraphViewerGdi.GViewer on Azure

791 Views Asked by At

Before asking the question that I want to ask, let me introduce you to my problem.

My company works on a website that we are developing in ASP.NET MVC. One of the pages needs to display an image showing a directed graph (the graph is created using the Microsoft.Glee graph library). The method that creates the graph is given below:

private bool CreateGraph(XDocument document, string graphPath)
{
        try
        {
            if (document.Descendants("Nodes").Count() == 0)
                return false;

            Microsoft.Glee.Drawing.Graph graph = new Microsoft.Glee.Drawing.Graph("graph");

            string id, parent;
            foreach (var node in document.Descendants("Nodes"))
            {
                id = node.Attribute("Id").Value;
                parent = node.Attribute("Parent").Value;

                Microsoft.Glee.Drawing.Edge edge = graph.AddEdge(parent, id);

                edge.TargetNode.Attr.Shape = Microsoft.Glee.Drawing.Shape.Circle;
                edge.SourceNode.Attr.Shape = Microsoft.Glee.Drawing.Shape.Circle;
            }

            Microsoft.Glee.GraphViewerGdi.GraphRenderer renderer = new Microsoft.Glee.GraphViewerGdi.GraphRenderer(graph);
            renderer.CalculateLayout();
            Bitmap bitmap = new Bitmap((int)graph.Width, (int)graph.Height, PixelFormat.Format32bppPArgb);
            renderer.Render(bitmap);
            bitmap.Save(graphPath);

            return true;
        }
        catch
        {
            throw;
        }
}

I am not the original writer of this code, i.e. it was written by another programmer in my company, so I can't really justify the decisions made in the code.

Anyway, the problem that I have is the following: when I test the page locally, the image is created successfully and is displayed on the page. However, when I deploy the website (we are using Windows Azure for hosting), I get the following exception:


    The type initializer for 'Microsoft.Glee.GraphViewerGdi.GViewer' threw an exception.
    System.TypeInitializationException: The type initializer for 'Microsoft.Glee.GraphViewerGdi.GViewer' threw an exception. --->
    System.ComponentModel.Win32Exception: Error creating window handle.
      at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
      at System.Windows.Forms.Control.CreateHandle()
      at System.Windows.Forms.Form.CreateHandle()
      at System.Windows.Forms.Control.get_Handle()
      at System.Windows.Forms.Control.CreateGraphicsInternal()
      at System.Windows.Forms.Control.CreateGraphics()
      at Microsoft.Glee.GraphViewerGdi.GViewer.GetDotsPerInch()
      at Microsoft.Glee.GraphViewerGdi.GViewer..cctor()
      --- End of inner exception stack trace ---
      at Microsoft.Glee.GraphViewerGdi.GViewer..ctor()
      at Microsoft.Glee.GraphViewerGdi.GraphRenderer.CalculateLayout()

I suppose that this is some memory issue, but can you tell me what do you think about it and what might be the cause of the problem? Searching the web didn't really help me.

Thanks in advance.

1

There are 1 best solutions below

2
On

No, this is not a memory issue. The issue is that the Glee library appears to need a window handle to do its job, which works fine when debugging locally because you are logged into the server and have an open Window Terminal in which to generate the handle.

However, when running on the server, it is most likely associated with a user such as Network Service, or a specific user that is not logged in to a Window Terminal, and as such has no associated desktop in which to create a window.

It may be that the server your code is running on has medium trust, and is not allowed to create window handles. I don't know enough about Azure to know if this is the case.

EDIT:

It looks like you need to enable full trust on Azure

http://blogs.msdn.com/b/windowsazure/archive/2009/03/18/hosting-roles-under-net-full-trust.aspx

In your service definition file, you need to add:

<?xml version="1.0" encoding="utf-8"?>
<ServiceDefinition name="MyService" 
   xmlns="http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceDefinition">
   <WebRole name="WebRole" enableNativeCodeExecution="true">
    <InputEndpoints>
      <InputEndpoint name="HttpIn" protocol="http" port="80" />
    </InputEndpoints>
  </WebRole>
</ServiceDefinition>