Scott Posted December 22, 2004 Posted December 22, 2004 HI I have a program where I use the following code to login. Dim objLogin As ACDB.Login Dim objRuntimeSession As ACDB.RuntimeSession objLogin = New ACDB.Login() objLogin.Login("", "") objLogin.ValidateUser("Module.ABC") objRuntimeSession = objLogin.RuntimeSession After the last command, the number of the available licenses is decremented by 1. But when I terminate my program, it lasts about 40 minutes until the license is available again. But in VB6 the license is available immediately after terminating the program, when I use the same methods to login. A special method to logoff does not exist. I tried to release the objects with Marshal.ReleaseComObject(objLogin) and Marshal.ReleaseComObject(objRuntimeSession). The reference counter of the 2 RCW's is then 0, but it doesn't change anything. Can anyone help me ? Thanks Quote
Mike_R Posted December 23, 2004 Posted December 23, 2004 This can be tricky/stubborn stuff. I find that the 'Marshal.ReleaseComObject()' command to be tricky at best. It doen't do any good unless you use it for absolutely every COM Object that you use and it's very easy to slip up and miss one. I find that it's easier to code normally and then if you have a COM Object or Resource, say called "MyCOMObject", then it might look like this:MyCOMObject.Close ' Or .Quit or whatever is required. MyCOMObject = Nothing CG.Collect If really a stubborn case, you can try this:MyCOMObject.Close ' Or .Quit or whatever is required. MyCOMObject = Nothing CG.Collect GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() Good luck, I have my fingers crossed for you..! Quote Posting Guidelines Avatar by Lebb
Scott Posted December 27, 2004 Author Posted December 27, 2004 My COM object doesn't have a .Close or .Quit method. I tried : MyCOMObject = Nothing CG.Collect GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() but with the same result. I'm wondering why the objects aren't released in .Net when I terminate the program because in VB6 they are. Quote
HJB417 Posted December 27, 2004 Posted December 27, 2004 Marshal.ReleaseComObject might do the trick. Quote
Mike_R Posted December 28, 2004 Posted December 28, 2004 Well it sounds like you are doing everything right. You are calling Marshal.ReleaseComObject() on both relevant objects and getting a confirmation that the reference count = 0. Yet it fails... :( It doesn't look to be the case, but are either of these Methods actually functions returning an Object?: objLogin.Login("", "") objLogin.ValidateUser("Module.ABC") I'm sure not, but I had to ask... if either does return an object, then that would cause a hang (believe it or not). Well, you've tried everything it seems the only thing I can think of is to throw everything at it at once: Sub MySub() Dim objLogin As ACDB.Login Dim objRuntimeSession As ACDB.RuntimeSession objLogin = New ACDB.Login objLogin.Login("", "") objLogin.ValidateUser("Module.ABC") objRuntimeSession = objLogin.RuntimeSession Marshal.ReleaseComObject(objRuntimeSession) Marshal.ReleaseComObject(objLogin) objRuntimeSession = Nothing objLogin = Nothing GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() End Sub If this fails, then the only other idea I have is to make use of the Process.GetProcessByName() method and then call Process.Kill. Very ugly, but this may be the only way if we can't get it to release via normal COM Interop commands... Quote Posting Guidelines Avatar by Lebb
Scott Posted December 29, 2004 Author Posted December 29, 2004 I have now tried this: Private Sub LogIn() Dim objLogin As ACDB.Login Dim objRuntimeSession As ACDB.RuntimeSession objLogin = New ACDB.Login() objLogin.Login("", "") objLogin.ValidateUser("Module.Finish") objRuntimeSession = objLogin.RuntimeSession Dim proc As Process = proc.GetCurrentProcess Marshal.ReleaseComObject(objRuntimeSession) Marshal.ReleaseComObject(objLogin) objRuntimeSession = Nothing objLogin = Nothing GC.Collect() GC.WaitForPendingFinalizers() GC.Collect() GC.WaitForPendingFinalizers() proc.Kill() End Sub The 2 methods don't return an object. Public Sub Login(Optional ByVal strRes1 As String = "", Optional ByVal strRes2 As String = "") Public Sub ValidateUser(ByVal strUniqueID As String) I had the idea to write a DLL in VB6 with a function 'Login' which contains the code to login and returns the 'RuntimeSession' object and a method 'Logout' in which I set everything to Nothing but it doesn't work too. I have also tried Application.Exit and Environment.Exit. It seems that the objects are only released when the code is written with VB6 and the application is terminated because even in VB6 when I set everything to Nothing, it doesn't change anything. Perhaps the developers didn't consider the possibility that someone could use .Net because I contacted the support and they also seem rather helpless. But I can't use VB6 because I don't have a valid license. :confused: Quote
Mike_R Posted December 29, 2004 Posted December 29, 2004 (edited) Ok, I slightly mis-understood... So this object is preventing your own App from closing down?? That is pretty amazing, as well as distressing. :( I'm stunned that neither Process.Kill nor Application.Exit allowed your routine to exit. Can you kill it "manually" from the Task Manager?? Or does it simply hang for eth 40 mins you were talking about (or until you reboot)? I think I'm running out of ideas though... Edited December 29, 2004 by Mike_R Quote Posting Guidelines Avatar by Lebb
Scott Posted December 30, 2004 Author Posted December 30, 2004 (edited) I don't think you mis-understood me, perhaps my last post was a bit confusing. I have no problem to close down my App, I used Application.Exit and Environment.Exit only because I thought when I close down the App in this way the objects would perhaps be released and the license would be available again so that another workstation can use it. Perhaps I reference a COM object that accidentally does not release yet another COM object properly. So when I release a COM object, it continues to stay in memory because it doesn't release the second COM object. Thanks for the help Edited December 30, 2004 by Scott Quote
Mike_R Posted December 30, 2004 Posted December 30, 2004 (edited) It sounds like to me that the company that makes this needs to make a .LogOff() method. Maybe you should suggest it? It shouldn't be very hard for them -- basically whatever they have in their Class_Terminate() Event would need to be put within this .LogOff method, that way it could be called explicitly, directly. I'm sorry couldn't do better... :( Edited December 30, 2004 by Mike_R Quote Posting Guidelines Avatar by Lebb
Recommended Posts