geoslegend / winforms-geplugin-control-library

Automatically exported from code.google.com/p/winforms-geplugin-control-library
GNU General Public License v3.0
0 stars 0 forks source link

VB 2010: Application crash on form closing #110

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Use VB 2010
2. Add GeWebBrowser, KmlTreeView and GeToolStrip to form
3. Use following code:

    Private Sub frm_WW_Conflicts_Load(sender As Object, e As System.EventArgs) Handles Me.Load

        server = New GEServer(System.Net.IPAddress.Any, 8080, KmlDir
        server.Start()

        GeWebBrowser1.LoadEmbeddedPlugin()

    End Sub

    Private Sub GeWebBrowser1_PluginReady(sender As Object, e As FC.GEPluginCtrls.GEEventArgs) Handles GeWebBrowser1.PluginReady

        _ge = e.ApiObject ' reference to the Google Earth Plugin object

        'Add ToolStrip
        GeToolStrip1.SetBrowserInstance(GeWebBrowser1)
        KmlTreeView1.SetBrowserInstance(GeWebBrowser1)

        'Layers
        GEHelpers.EnableLayer(_ge, Layer.Borders, True)

        'Options
        options = New GEOptions(_ge)
        options.ScaleLegendVisibility = True
        options.StatusBarVisibility = True

        'Nav Control
        control = New GENavigationControl(_ge)
        control.Visibility = Visibility.Show

        GeToolStrip1.Refresh()

        'Load first conflict
        Call Load_KML(0)

    End Sub

    Private Sub GeWebBrowser1_KmlLoaded(sender As Object, e As FC.GEPluginCtrls.GEEventArgs) Handles GeWebBrowser1.KmlLoaded

        'add the kml to the plugin
        Try
            GeWebBrowser1.ParseKmlObject(e.ApiObject)
            KmlTreeView1.ParseKmlObject(e.ApiObject)
        Catch ex As Exception
            MessageBox.Show(ex.Message, "KML Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

    Private Sub Load_KML(ByVal Conflict_Index As Short)

        Try
            GeWebBrowser1.FetchKml("http://localhost:8080/Test.kml")
        Catch ex As Exception
            MessageBox.Show(ex.Message, "KML Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
        End Try

    End Sub

    Private Sub frm_WW_Conflicts_FormClosing(sender As Object, e As System.Windows.Forms.FormClosingEventArgs) Handles Me.FormClosing
        GeWebBrowser1.KillPlugin(True)
        server.Stop()
    End Sub

What is the expected output? What do you see instead?
When closing the form, the app should not close. When closing a form with the 
GEPlugin, the entire app closes/crashes. However, no error message is given.

What version of the product are you using? On what operating system?
VB 2010, Win 7 64Bit, Product Revision 539

Please provide any additional information below.
Any help debugging this would be great. Your help has been terrific.
The crash doesn't happen if I play with the GEPlugin for a little bit. However, 
if I try to reopen the form, then the app crashes while opening the form. No 
error message.

Clicking on "Refresh Plugin" in the GEToolStrip also crashes the entire app.

I'm not sure I'm disposing of the GEPLugin correctly.

Thank you again for the help!

Original issue reported on code.google.com by nhi...@vt.edu on 18 Jul 2013 at 11:28

GoogleCodeExporter commented 8 years ago
Can you tell me what you mean by "when closing the form, the app should not 
close."
What form and which app are you talking about? 

In any case, you shouldn't really have to dispose the plugin at all, the 
process will terminate itself a short time after the browser quits.

Also when you say "then the app crashes while opening the form" can you be more 
specific? For example what does the call stack look like?

Thanks.

Original comment by fraser.c...@gmail.com on 18 Jul 2013 at 1:45

GoogleCodeExporter commented 8 years ago
I have an MDIForm for my application. So, I open a new form to display the GE 
PLugin. When closing the GEPlugin form, it also closes/crashes the MDIForm. I 
did some testing and all works fine until I Fetch the Kml with:

GeWebBrowser1.FetchKml("http://localhost:8080/Test.kml")

After that, if I close the form that contains the plugin, the MDIForm crashes 
too. I tried a basic Kml files from Google also.

How can see the call stack or crash log?

Original comment by nhi...@vt.edu on 18 Jul 2013 at 2:00

GoogleCodeExporter commented 8 years ago
Sorry, I can't really help with general programming here. If you are not sure 
how to debug an application in visual studio then there is a wealth of 
information on the internet and in the help files for the application. For 
starters...

http://msdn.microsoft.com/en-us/library/windows/hardware/hh439516(v=vs.85).aspx

Although I can't be sure, I suspect you are probably doing something outside 
the library that is causing the crash, possibly something in your MDIForm. 

Anyhow, if you can post some more info I will take a look. 

Thanks

Original comment by fraser.c...@gmail.com on 18 Jul 2013 at 3:50

GoogleCodeExporter commented 8 years ago
Call Stack looks like this if I stop the code at "End Sub" of the "FormClosing" 
function above.

>   WEM_GUI.exe!WEM_GUI.frm_WW_Conflicts.frm_WW_Conflicts_FormClosing(Object 
sender, System.Windows.Forms.FormClosingEventArgs e) Line 45    Basic
    [External Code] 

Original comment by nhi...@vt.edu on 18 Jul 2013 at 4:31

GoogleCodeExporter commented 8 years ago
This might be more helpful. This is from the Windows Event Viewer:

Application: WEM_GUI.exe Framework Version: v4.0.30319 Description: The process 
was terminated due to an unhandled exception. Exception Info: 
System.Net.Sockets.SocketException Stack: at 
System.Net.Sockets.Socket.EndReceive(System.IAsyncResult) at 
FC.GEPluginCtrls.HttpServer.GEServer.ReadCallback(System.IAsyncResult) at 
System.Net.LazyAsyncResult.Complete(IntPtr) at 
System.Net.ContextAwareResult.CompleteCallback(System.Object) at 
System.Threading.ExecutionContext.runTryCode(System.Object) at 
System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(
TryCode, CleanupCode, System.Object) at 
System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,
 System.Threading.ContextCallback, System.Object) at 
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, 
System.Threading.ContextCallback, System.Object, Boolean) at 
System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, 
System.Threading.ContextCallback, System.Object) at 
System.Net.ContextAwareResult.Complete(IntPtr) at 
System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr) at 
System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, 
UInt32, System.Threading.NativeOverlapped*) at 
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, 
UInt32, System.Threading.NativeOverlapped*) 

Original comment by nhi...@vt.edu on 18 Jul 2013 at 4:37

GoogleCodeExporter commented 8 years ago
Ah OK I think this is the same as issue as this.

https://code.google.com/p/winforms-geplugin-control-library/issues/detail?id=64

Try giving the sever an IP address rather than relying on the default value of 
"IPAddress.Any".
For example. 

this.server = new Server("whatever");
this.server.IPAddress = System.Net.IPAddress.Loopback; //ip that you want the 
sever to use

Original comment by fraser.c...@gmail.com on 18 Jul 2013 at 5:50

GoogleCodeExporter commented 8 years ago
Ok. I got the form closing crash fixed by using:

server = New GEServer(System.Net.IPAddress.Loopback, 8080, KML_Dir)

and changing the KML URL to server.IPAddress.ToString instead of "localhost"

GeWebBrowser1.FetchKml("http://" & server.IPAddress.ToString & ":" & 
server.Port.ToString & "/" & KLM_Name)

Original comment by nhi...@vt.edu on 18 Jul 2013 at 6:10

GoogleCodeExporter commented 8 years ago
Just a note for others:

Do not call "server.Stop()", because it generates the same crash if you close a 
form using the GEWebBrowser and reopen it. Without the "server.Stop()" call, 
everything works fine.

Original comment by nhi...@vt.edu on 18 Jul 2013 at 6:22

GoogleCodeExporter commented 8 years ago
That isn't strictly true.

The reason it is crashing is because you are trying to recreated a socket that 
has not finished disposing. When you call server.Stop() you have to wait some 
time before recreating am instance of the GESever with the same settings.

If you used a different port each time then you wouldn't get the socket error.
This is just how TCP works - closing a TCP socket queues the socket for release 
but the socket is not actually released for some time.

You have to wait some time before you can bind a new socket to a previously 
used address like that.

If you do want to open and close the server like that you must use a different 
port.
The better option would be to move the server code out of that form or else as 
you have said leave it running.

Original comment by fraser.c...@gmail.com on 18 Jul 2013 at 7:14

GoogleCodeExporter commented 8 years ago
[deleted comment]
GoogleCodeExporter commented 8 years ago
Also - there is no need to do 

GeWebBrowser1.FetchKml("http:// & server.IPAddress.ToString & ":" & 
server.Port.ToString & "/" & KLM_Name)

You can simply do 

GeWebBrowser1.FetchKml(server.BaseUrl & KLM_Name)

Original comment by fraser.c...@gmail.com on 18 Jul 2013 at 8:22

GoogleCodeExporter commented 8 years ago
Thanks. That's better.

The reason why I'm trying to Start/Stop the server on form "Opening/Closing" is 
because the KML files to display are located in different directories and 
generated dynamically.

Can I set the server to a certain Root directory and fetch KMLs in 
subdirectories?

Something like that:

GeWebBrowser1.FetchKml(server.BaseUrl & "\SomeSubDir\AnotherSubDir\ & KLM_Name)

Original comment by nhi...@vt.edu on 18 Jul 2013 at 8:28

GoogleCodeExporter commented 8 years ago
Yes, as long as those directories exist then you can use them. 

Original comment by fraser.c...@gmail.com on 19 Jul 2013 at 6:20