Part of my everyday work is maintaining and extending legacy VB6 applications. A common engine is written in C/C++ and VB6 uses these functions in order to improve performance.
When it comes to asynchronous programming, a C interface is not enough and we rely on COM controls to fire events to VB6.
My problem is that when I register the control in VB6, VB loads this control in memory and does not unload it until I quit the VB6 IDE. As the control is loaded the whole time, I am unable to recompile it in VC6, because the DLL file is locked.
A solution I found is not to enable the control in VB but use the CreateObject() with the full name of my control. The problem then is that I must declare my control as an Object because VB6 knows nothing of the interface I am using and I do not have access to IntelliSense, which is a pain.
Any idea how I can tell VB6 to unload controls after quitting the application or directly in the IDE ?
I'm pretty sure there's no good way to force VB6 to unload the control.
Here's what I do... instead of running Visual C and Visual Basic side-by-side, run VB6 under VC :
Load up VC
Open the project containing your COM objects
Edit, change, etc.
In VC, set the Output Executable to be VB6.EXE with appropriate command-line arguments to load the VB6 workspace
Now just hit F5 to launch the VB6 IDE and load your VB6 project
When you want to change the COM code again, exit VB6.EXE, make your changes, and hit F5 again. As long as you save your workspace VB6 will remember what windows you had open and all your project settings.
Advantages of this method:
You can set breakpoints in the COM object and debug it using a full source debugger
You can happily debug in C and VB at the same time
Whenever VB6 is running it always has the latest version of the COM DLLs
Related
To nip this in the bud, I have posted this question and workaround. I would like to accept an answer that actually quantitatively describes the problem.
I do some office programming using VS2010 and VB.NET. I have found that using VB.NET over VBA provides a much better user experience for office automation tasks. But, VB.NET IDE sometimes, not all the time, grinds to a halt when debugging Excel COM interop code, such as it takes 5 minutes to set a string equal to the value of cell, or just removing and adding breakpoints takes minutes apiece. This has been the bane of my existence for sometime, as I would have to restart my computer to fix it, but I have finally figured out the causal actions and a workaround. It happens when I have more than one other Excel instance open besides the COM server. I know Excel usually only opens one EXCEL.EXE, but, I have my registry settings so that every excel document opens in a new instance, so that I can look at separate docs on separate monitors. I don't believe this is uncommon. So, when I have left Excels open and my app starts an Excel COM server and breaks into the debugger, this is when the problem occurs, but also only if I click or operate in someway in one of the Excels after starting the COM server. Then it is like the COM server gets confused as a chameleon in a bag of Skittles of which it can't get out until I restart the computer. So, does anyone have enough debugging, COM, and Interop expertise to tell me what is causing this debugging hell? And possibly a way to preempt it?
To workaround this problem without restarting, I have found that I can end all instances of EXCEL.EXE, even the COM server, and close the IDE, then reopen Excel directly without a document and close it. Now, reopen the IDE, run code, start debugging, and stepping latency is non-existent or negligible.
I've got the very same problem as this question: Edit Xaml while debugging with a twist.
My debug session usually runs some code while I need to change stuff in the XAML, and if I detach all, as recommended as answer in that question, the debugged program might run on, but the WCF services which are also hosted in the debugger will be stopped immediately.
And without service my programm usually last mere seconds.
So, is there a way to exit xaml files during debugging? I don't care for debug and continue, I'm aware the changes will take effect only after a restart of the app. I just need to type in some stuff so I won't forget and am annoyed that I have to use an external editor instead of VS.
I always use another tool. Like notepad++ or expression blend.
You can configure this by right clicking the file -> open with. Or with expression blend you get the open in expression blend option and its pretty good for xaml anyways.
if you need dynamic build you can take a look at project Roslyn
more info here
"Developers could also use the output of such software to do tasks like refactor, or reorganize, their code more easily, to add C# and Visual Basic functionality to programs written in other languages. It also adds dynamic typing to the statically typed C# and Visual Basic, allowing developers to add objects and new variables to a program on the fly."
so my question is relatively simple, can I create VB6 application that references a class in a dll, and then substitute that dll for another at runtime?
Now my intial guess is... no chance in VB6.
So my thoughts turned to a VB.net interop dll. Could I do it in here, and then call the interop dll from the VB?
Again, my guess would be no.... but I'd be happy if someone knew differently.
The only thing that I think would actually work would be DI in .Net, but I'm limited to .net 2, or 3.5 at a big push, so I dont know if that is possible.
So for the background....
I have a dll that a specific site uses, but we dont want to ship that out to everyone. Instead, we want to build a clone dll which just has the interfaces setup so that the VB6 build will complete.
When it gets to the site that needs it, they want to replace the dummy dll, and drop in their version instead.
Note: We do use RegFreeCOM when its gets installed, so I do have the manifest files that I could play around with if needed.
Any ideas would be much appreciated.
Nick
Its a COM dll so its not statically linked to the VB6 exe, so long as the clsids and interface ids are the same in the type library for both DLLs, you can swap them around as you see fit. (If its a VB6 dll this is trivial to do with the 'binary compatibility' build option)
You could also use late binding instead and instead of making a reference directly in your VB6 code, you would create an object and then set that object to an instance.
Examples and information:
MVPS
Microsoft
It's hard to explain our situaction.
We have a 3-tier application. The engine is a DLL coded in C++, then we have a VB6 ActiveX EXE that access to the engine via API calls, and at the top level we have a Excel Addin (in C# using VSTO framework) calling the middle layer with an interop DLL. At this time, each "connection" from the Addin to the engine creates a new EXE (VB6 uses API calls to access to the engine) and all works fine.
Now we are moving the middle layer to .NET, it works 'presumably' fine (it pass all our Unit test) but, we found an error when we open 2 "connections" at same time (ups, no unit test check this situation because it's a new behavour). The DLL have static objects that it's shared over all instances in the same process and we have interactions between "connections". In our old version each "connection" creates a new EXE with no memory sharing between processes, now it's the same process and they share memory and the static objects.
Following the tips from this question. We tried to build a COM EXE in C# to do an out-of-process objects in the middle layer but we have the same result. They share the static objects, at the end, each connection not creates a independent process.
It's clear, but not affordable at this time, moving API calls to ATL or changing the static objects to instanciable references with a handle and change all the API calls to get/set this handlers. I reviewed all examples in MS All-in-one but I didn't find any solution. Neither it's possible to keep only one connection at time, each workbook can have one connection and in the future we want to explore a Web application with multiple connections at same time.
Any suggestion?
Thanks in advance,
Whether COM starts new EXE per each COM object, or uses single EXE to instantiate all the object is controlled by flags parameters passed to CoRegisterClassObject. See
http://msdn.microsoft.com/en-us/library/ms693407(v=vs.85).aspx, and
http://msdn.microsoft.com/en-us/library/ms679697(v=vs.85).aspx
You need to pass REGCLS_SINGLEUSE or REGCLS_MULTI_SEPARATE flags.
Now, the trick is to pass this flag, as you might not call this method directly - the details depend on how you implemented the COM EXE.
it's not clear from the question, but it sounds like the "middle layer" you have was built as a VB6 EXE, and you're trying to replace it with a .net DLL. If that's the case, you'll definitely get the behavior you describe.
With a VB6 EXE com project, instantiating a new object starts a new process. With a .net dll (or a Vb6 dll really) you +won't+ get a new process.
You'd either need to create a .net EXE that exposes COM objects just like your VB6 exe does, or (sounds like you've already investigated this) you'll need to refactor your EXE objects to properly handle multiple instances within a single process.
Honestly, it'd probably be better to do that latter, since relying on singletons like this is generally a bad code smell. But it a pinch, you should be able to replicate the behavior of the VB6 exe with a .net project. You just can't do it in a dll.
Was your middle layer created in .Net? If it was, you might be facing the issue that your COM class is been created as a native .net object instead of a COM object. The solution usually involve using Primary Interop Assemblies. Take a look on this SO question to see if it matches your problem.
is it possible to create an application with flash interface in Vb?
I'm using visual basic 2008.thanks.
I did that a decade ago in VB6. Back then, there was an SWF player ActiveX that could be added to a form... I think the ActiveX DLL was included in that standard Flash plugin for IE and the only thing I had to do is to add a reference to that DLL.
Back then, it was distributed by Macromedia... I'm not sure if it's still possible since Adobe is the distributor.
Sorry if I don't have any recent informations about this :(