Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

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

Posted

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..!

Posting Guidelines

 

Avatar by Lebb

Posted

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.

Posted

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...

Posting Guidelines

 

Avatar by Lebb

Posted

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:

Posted (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 by Mike_R

Posting Guidelines

 

Avatar by Lebb

Posted (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 by Scott
Posted (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 by Mike_R

Posting Guidelines

 

Avatar by Lebb

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...