We are currently working on creating an ActiveX dll for migrating our existing xlt template file. For this we tried creating an ActiveX dll in VB6. We were successful in creating the Add-Ins but we are facing a serious issue.
The AddinInstance_OnConnection is being called indefinitely leading to creation of multiple excel objects. As this is the primary method that gets called when the host application creates the Add-Ins we are not able to stop this execution.
Can anyone please provide us some suggestion for the above problem.
Thanks in advance
ram
I had a similar problem one time and I resolved it creating an ActiveX EXE that it's the caller of the main application in the Active DLL.
You keep a reference in the EXE to the main application in the DLL and you handle it like:
If IsNull(ReferenceToDll) Then
CreateDllApplication
Endif
RunDllApplication
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.
We're porting an old Visual Studio 6 application to Windows 7. The application heavily uses COM and the old RogueWave database interface. We're having a very random sever crash which looks like some sort of memory integrity problem. The crash occurs in the COM application. The application is started using COM, after starting up it tries to connect to the database. One of the following will occur:
1) Sometimes the COM application will have a sever crash
2) Sometimes it will work
3) Sometimes it will not be able to connect to the database and never will even with retries.
4) Sometimes when calling the RogueWave database creation, it does not return.
When starting the COM application several times in a row it will display any number of these symptoms.
At this point I have not been able to identify what is causing the instability.
The application will also crash when started normally, not using COM, but crashes less frequently.
Previously I saw a problem with identical symptoms in another area of this product. I was able to identify that the symptoms were tied to calls into a dll which were returning a CString that was created as a local variable. The dll is built using _AFXDLL preprocessor definition. After removing the calls to this dll this problem no longer occurs. This problem was occurring in many places.
At first I thought that this problem was caused because the dll was not built as an AFX EXTENSION DLL, but after reading through the documentation the _AFXDLL preprocessor definition will also build the dll as an AFX_EXTENSION_DLL. I'm used to using the _AFXEXT preprocessor directive to build AFX_EXTENSION dlls.
The COM application that is now crashing does not use this DLL. There is another DLL used by the COM application that has 1 exported function that returns a CString created as a local variable. This exported function is not called during the database connection.
Anyone have any ideas what would be causing this apparent memory integrity crash in a COM application? Thank you in advance for your help.
This turned out to be caused by a bug in the Oracle 10g express client dll.
I am very new to development on MS platform and hence I have some issues in understanding the concepts of dll's and how they are used by applications. I have quite extensive experience with Java and will try to compare them in order to understand the functionality even more.
From what I understand, dll's are complied c++/c#/mfc code. Its almost equivalent to .class from Java (Except class files can be decompiled). dll's can be imported in any other source files as a library and so can class files.
Now what I want to know is when we use this dll, is there just once instance of dll that will be shared by multiple instances of application using it or each and every application have its on instance of the dll. I assume it would be the latter as it makes more sense since MS development is completely object oriented.
One prime example of this can be running COM add-ins in any office application. We can have several open instances of excel application with different workbooks. So does each workbook have its own instance of the add-in (which is in form of a dll file) or there is just one instance which is started when excel first loaded and it is shared with all the open workbooks until the last one closes.
If they are not shared, is there any way to share some methods between time (like making static methods and variables in Java)?
Here's a comprehensive explanation of Windows DLLs. http://support.microsoft.com/kb/815065
Regarding instances, I believe it is the latter as you suggested i.e. 1 instance per process, which in case of COM add-ins would be each running instance.
See this paragraph from the article.
When multiple programs use the same library of functions, a DLL can
reduce the duplication of code that is loaded on the disk and in
physical memory. This can greatly influence the performance of not
just the program that is running in the foreground, but also other
programs that are running on the Windows operating system.
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.