Can't replace my ActiveX DLL when program is running
Hi,
Wanted to use an ActiveX dll in my program so I created following test projects:
- DLL_test.exe
- ActiveX_DLL.dll
(I did set binary compability to the DLL).
Run the compiled DLL_test.exe and click a button and sure enough I get the message box
The problem is that once the button was clicked at least once, I can't replace the DLL with a new one. Looks like my EXE program is not releasing the DLL once it is called. After closing my EXE and even restarting I can replace the DLL no problem (until I use the function by clicking the button again).
Code:
' Function in my ActiveX_DLL.dll
Public Function About()
MsgBox "My DLL v2.5"
End Function
' My DLL_Test.exe program
Private Sub cmdActiveXDLL_Click()
Dim myDLL As Object
Set myDLL = CreateObject("ActiveX_DLL.class1")
myDLL.About
Set myDLL = Nothing
End Sub
I thought the the code below should be releasing the DLL, but it's not.
Code:
Set myDLL = Nothing
Any ideas?
Re: Can't replace my ActiveX DLL when program is running
In the DLL_test project, have you added a Reference to the DLL? If so, the reference is what is using it.
As you are using CreateObject, there is no need to have a Reference.
Re: Can't replace my ActiveX DLL when program is running
No, I didn't add the reference. All I did is shown in the code.
To me the whole point of using a dll is that I can easely replace it while the program is running. But so far I can't do that...
Re: Can't replace my ActiveX DLL when program is running
I ran your code exactly as you posted it and I didn't have any problems.
I created the DLL and kept the default name for the Class module; Class1
(note: I see in your code you use lower case in class1. I used upper case Class1)
I saved the DLL as ActiveX_DLL.dll
I created a test project and copied your code
Code:
Private Sub Command1_Click()
Dim myDLL As Object
Set myDLL = CreateObject("ActiveX_DLL.Class1")
myDLL.About
Set myDLL = Nothing
End Sub
I clicked on the Command button several times and each time it displayed the message box from the DLL.
EDIT
Yes, I added a reference to it
Re: Can't replace my ActiveX DLL when program is running
Thanks for your response jmsrickland,
Yes, the program works, I'm only having problem when trying to replace the DLL while the EXE is running.
Try this:
1. Run the EXE and click the button (You'll see the messagebox)
2. Without closing the EXE, rebuild the DLL and override the old one
Windows will not allow me to rebuild into the same folder OR replace the old dll because somehow the DLL is being held and not unloading
ALSO, like si_the_geek said, don't reference the DLL in the Project-References since we're create the object on the fly.
Re: Can't replace my ActiveX DLL when program is running
Right.... if you have app1 using DLL1....as long as app1 is running, Dll1 is in use... can't replace it... You can't replace the engine in your car while driving down the road can you? (and if you can, could I have the name of your mechanic?) Essentially that's what you are doing. In order to replace the DLL, you have to be out of the application using it.
-tg
Re: Can't replace my ActiveX DLL when program is running
Techgnome,
True, but the whole point is that I'm not supposed to be using the engine. The car is moving but the engine off and I have 5 guys pushing it. At that point I should be able to change the engine... :)
(As soon as I show the messagebox and click OK to close it, I'm unloading the DLL). So at that point I should be able to replace it.
Let me know if I'm wrong here.
Re: Can't replace my ActiveX DLL when program is running
As soon as I show the messagebox and click OK to close it, I'm unloading the DLL. So at that point I should be able to replace it.
No you are not unloading the DLL. You are just releasing the usage of the function within that DLL. Just because you are finished using the function the DLL is still loaded in memory. Windows keeps track of all this stuff.
You need to just accept the fact and don't try to fight it.
The bottom line is this:
WINDOWS WINS IN THE END
Re: Can't replace my ActiveX DLL when program is running
Actually the DLL is being unloaded, that is what the "Set myDLL = Nothing" line does (I'm not sure why you think it is specifically related to the function).
Doing that should mean that the DLL can be replaced immediately (or almost) after that line runs, so I thought I'd test it out to find the problem.. I used exactly the same code, and found the same issue, which I thought was odd (but good for finding a solution!).
After a bit of playing around I realised that the cause was using the IDE to run the EXE project - when that was run compiled, the behaviour you want (and I expected) is what you get.
Presumably this is because the IDE is doing extra work behind the scenes, but I'm not sure what.
[RESOLVED] Can't replace my ActiveX DLL when program is running
jmsrickland,
Thanks for clearing it up.
If that's the case, then I'll just have to use visual c++ to create a regular DLL.
While waiting for someone to answer my ActiveX DLL problem I played with VC++ and created a simple DLL.
I'm able to call it from VB and REPLACE the DLL while program is running which is the biggest thing for me. The disadvantage is I'm not as proficient in C++ as I am in VB but should be able to figure out most functions.
Re: Can't replace my ActiveX DLL when program is running
He said run the .exe of it so that implies a compiled binary file running outside of the IDE. And as long as the .exe is running I don't think you can resave the DLL as the same name.
EDIT
Well if you are able to do then that is new to me. I am running an executable right now and I am not able to resave the same DLL as the same name as long as the app is running. Once I close the app then I can. So if you say you can and I say I can't then what is going on here?
Re: Can't replace my ActiveX DLL when program is running
Tomexx, did you see my previous post? (you posted soon after, so may have missed it)
Quote:
Originally Posted by jmsrickland
Well if you are able to do then that is new to me. I am running an executable right now and I am not able to resave the same DLL as the same name as long as the app is running. Once I close the app then I can. So if you say you can and I say I can't then what is going on here?
Do you have a Reference to the DLL? If so, that is keeping it open for as long as your program is running.
Are you setting the variable(s) that refer to it to Nothing? If not, you need to.
Re: Can't replace my ActiveX DLL when program is running
OK, here's the deal. I can't save it in the same folder but I can save it in another folder.
Re: Can't replace my ActiveX DLL when program is running
That sounds like it is still in use.. have you checked that the Exe's references don't include it, and that you are setting all of the object variables to Nothing?
Quote:
Originally Posted by tg's signature
"There is a major problem with your code, and VB wants to tell you what it is.. but you have decided to put your fingers in your ears and shout 'I'm not listening!'" -
si_the_geek
I'm proud of that, and think I might add a modified version of that to the FAQ article! :D
Re: Can't replace my ActiveX DLL when program is running
Love that sig.
I'll check into that reference thing you are talking about
Re: Can't replace my ActiveX DLL when program is running
si_the_geek,
I havent' seen your post before.
1. It's not the IDE as I tried both running a compiled EXE and inside IDE. Same problem.
2. I don't have the DLL referenced in the program because it doesn't have to be as you pointed out before.
3. The reason I know it is related to this function is because there are no other functions in my test program.
ALSO, when I first start my EXE before clicking the command button I can replace the DLL at will because it's not loaded yet. Once I click the button, the DLL gets loaded and MsgBox() displayed then I thought I was unloding it with the Set myDLL = Nothing.
So as strage as it seems, jmsrickland might be right :)
But please let me know if you find a solution.
Re: Can't replace my ActiveX DLL when program is running
OK here is my code from the running application:
Code:
Private Sub Command2_Click()
Dim myDLL As Object
Set myDLL = CreateObject("SomeDll.CSomeDll")
myDLL.MyFunction "HELLO FROM TEST APPLICATION"
Set myDLL = Nothing
End Sub
This is running as an EXE and VB is not even up with this project.
I open the DLL project and try to save it in the same folder. Windows says NO.
I try to save it in another folder and Windows says OK
There is no reference to the DLL in the test application other than what you see in the code above.
Re: Can't replace my ActiveX DLL when program is running
Ah.. it appears I did do something a bit different. During my "playing around" I moved the code to Form_Load, and forgot to move it back - with the code there (and the project running compiled) it worked fine.
As you are both finding, it does not work with the code in a button, so it seems like the garbage collector acts strangely.. and as yet I cannot find a way of making it work (such as using an extra form or class just for that code).
I'm currently on my way out of the house, but will try to have another look at it later.
Re: Can't replace my ActiveX DLL when program is running
Check this out.
I recompiled the DLL and saved it in folder A. Closed the DLL project.
I ran the EXE test program and clicked on the button. OK so far.
Now I keep the test program running.
I opened the DLL project and tried to save the DLL in folder A. Windows said No Way.
I then used folder B and saved the DLL there while the test program was still running.
I clicked on the button and it still was OK
Now since I didn't want the DLL in folder B I deleted it from B but the original is still in A
When I clicked on the button again it didn't work.
So, Windows changed the load address frm folder A to folder B and when I clicked on the button after deleting the DLL from B Windows couldn't find the DLL in folder B.
So I closed the test app. Went back to folder A and resaved the DLL again.
The test program worked everytime I clicked on the button.
So, saving the DLL in a different folder changes everything and until you resave it again in the original location no programs can use it because Windows still thinks it's in folder B
Bottom Line:
Learn something everyday
Re: Can't replace my ActiveX DLL when program is running
Here's what's happening....
When you create an object, Windows is creates a reference to it. This reference remains in place for the life of the application. Pooling. It makes object activation faster on later calls since Windows has successfully located the DLL and created the object. Same thing bites me when ever I'm working on custom component on our IIS server. IIS has to be completely turned off before the DLL would be released and replaced.
For the Folder A, Folder B fun: When you compile a DLL, Windows makes a registry setting linking the program id, the classid and it's location together. So when you first compile it to folder A, it sets the registry to say "Hey, when you need object XYZ, look here: Folder A" .... and so it does. When you then compiled to folder B, a registry entry was added to say "Hey, when you need object XYZ, look here: folder B" .... and then you deleted folder b, so when it went to go get the object, it was no longer in Folder B.
By the way, running reg clean would be a good idea right about, since I'm sure no one thought to make things binary compatible (meaning that EVERY time DLL XYZ was compiled, there was a NEW registry entry created for it, even if it goes to the same folder).
-tg
Re: Can't replace my ActiveX DLL when program is running
That would make sense.. apart from the fact that it works as wanted when the code is in Form_load.