VB.Net Program with COM ActiveX capabilities - vb.net

Say I created a program with a textbox on it and a button that does something with the text in the textbox.
How do I make that program COM visible, load it and automate it from another project?
My goal is to be able to automate the program using COM:
Dim myProj as object = createObject("myProgram")
myProj.setText("Hello World")
myProj.buttonClickEvent()
Similar to how you can load a new excel and automate via interop:
dim xl as object = createobject("excel.application")
Dim wb as object = xl.workbooks.add
Dim ws as object = wb.worksheets(1)
ws.cells(1,1) = "i love stackoverflow"
How do programs do this? I'm looking for the answer VB.Net specific. Thank you in advance!

This page should give you the necessary details you will need: http://www.codeproject.com/KB/vb/MusaExposingCOM.aspx
This process that you want is normally called "exposing a COM interface", this is done via early binding or late binding. Early binding means the methods (locations) are known when you create your program, late binding means the methods (locations) are looked up when you run the program. Late binding, I think, is a little slower but the lookup only has to happen once. This is negligible.

Related

Close Shell.Application Instance

I'm writing a script to open documents using the default program via the Windows shell based on this SO answer:
Dim Shex As Object
Set Shex = CreateObject("Shell.Application")
tgtfile = "C:\Nax\dud.txt"
Shex.Open (tgtfile)
I notice the instance of Shell.Application never gets closed. In my code, I Set Shex = Nothing, but is that enough? If I create a Word or Outlook instance, for example, I would need to close it with .Quit before setting the variable to nothing. There's nothing obviously analogous going on here.
I set a reference to Microsoft Shell Controls and Automation to explore the Shell object, but couldn't find any methods for the .Application or .Parent properties, let alone one that looked like .Quit.
Am I missing something obvious? Does the garbage collector somehow also get rid of the instance? Is it something specific to the shell object itself?
Thinking about it, I'm pretty sure #jamheadart is right and I'm just instancing a VBA class rather than creating an application class in Windows.
To be sure, though, I'm taking #Mert Y's suggestion of using a context manager to limit scope.
Final code:
With CreateObject("Shell.Application")
.Open (strPath)
End With

How to close a Pop-Up while running RunApplication(X) in VB.NET

I am trying to run an Application, but during the running of this application, there is a pop-up, which makes the code freeze as I do not know how to close the pop-up.
The application is built on VB.NET
Dim oDesk as Object
Dim oApp as Object
oDesk =CreateObject("Desktop.Application")
oApp = oDesk.RunApplication(Input1) 'Reference to the VB.NET code that will navigate to the required module.
SendKeys.SendWait("{ENTER}")
Tried to send ENTER to close the pop-up, but RunApplication gets, stuck. Not sure how to restrict pop-ups etc. in VB.net.
Any help appreciated!
Best,
Gert
You are able typically to create an additional object to handle the popUps. This is rather an application specific, so be careful. The logic depends on the application.
Dim oDesk as Object
Dim oApp as Object
Dim oAppPopUp as Object
oDesk =CreateObject("Desktop.Application")
oApp = oDesk.RunApplication(Input1,oAppPopUp) 'Reference to the VB.NET code that will navigate to the required module.
SendKeys.SendWait("{ENTER}")

Excel application object in VB (apparently) prevents normal use of Excel while VB program is running

I have made a Visual Basic program in Visual Studio (NOT VBA) that creates an instance of Excel and uses it throughout the program to open existing/create Workbooks. The problem I'm encountering is that any time after the instance of Excel is created, I am unable to completely open a workbook normally (from within windows explorer). I say 'completely' because Excel DOES appear open, but the menus and workbook itself don't actually populate. The Excel border just sits there and the busy cursor is shown when I hover over it.
Once the VB program is closed and that object is released, Excel returns to 'normal' functionality. Additionally, when I quit the VB program, the partially opened workbook also goes closes, almost as though it was attached to the instance of Excel I created in code.
The instance of excel created should be totally silent and the user should never even know it's being used. To that end, I'd like the user to be able to open other workbooks as though Excel isn't already being used elsewhere. This is important because other Excel workbooks might need to be opened for reference by the user during runtime.
I declare the object this way because there are many sub routines in various modules that all might want to use the instance of Excel.
Public Shared XLapp As New Excel.Application
The following code runs when the first form opens in the applicaion. Once this bit runs and the XLapp object gets set to a new Excel.Application, I lose the ability to open a workbook normally, as described above.
If IsNothing(XLapp) Then XLapp = New Excel.Application
XLapp.Visible = False
XLapp.DisplayAlerts = False
XLapp.EnableEvents = False
XLapp.ScreenUpdating = False
After creating a workbook object, I'll later in the code, and in various places throughout, open a workbook typically as below:
Dim OpenedWorkbook as Excel.Workbook = Nothing
[...]
OpenedWorkbook = XLapp.Workbooks.Open(workbook_filepath)
I've always been under the impression that if I'm opening workbooks using this particular object (XLapp) that when a workbook is opened in windows explorer that a new instance of Excel would be created. That is to say, the instance of Excel my program creates should be isolated from other instances of Excel, but that doesn't seem to be the case here.
Is there something else I need to do (or have I done something wrong?) to allow the user to use Excel normally while my program is running?
Thanks in advance for the help and for having patience with this VB newbie!
(Sorry, too long for a comment.)
You might be using the wrong tool for the job. You write:
The instance of excel created should be totally silent and the user should never even know it's being used. To that end, I'd like the user to be able to open other workbooks as though Excel isn't already being used elsewhere.
The purpose of Excel interop is to remote-control Excel, just like a user would interact with it. However, users don't interact with silent, non-visible Excel windows. It's just not what Excel interop is made for.
I suspect that you don't really want to remote-control a locally installed Excel instance. What you really want to do is to open and manipulate Excel workbooks. Then do just that: Use one of the Excel libraries for .NET and modify the Excel files directly (personally, I like SpreadsheetLight, but others are fine as well). Additional bonus: Your users don't need to have Excel installed.
You should refer to this post ... How do I properly clean up Excel interop objects?
Basically, when you create the Excel object, and don't dispose of it correctly, it hangs around sucking up legitimate Excel file open requests but not acting on them!
Fixing this type of error is time consuming, because the worksheet/cell/etc references all need to be disposed of correctly.
Furthermore, if you use more than one '.' in an instruction (eg Parent.Child.GrandChild) then you are in even more trouble since you create a reference to Child, but don't store it anywhere, and thus can't dispose of it!
As #Heinzi mentions, you could well fare better by using a different library rather than Excel interop if all you are doing is reading/writing values. I've used EPPlus with no issues so far (add via Nuget)!

What is the Vision VBA equivalent to Access' Application object?

In Access VBA, you can access properties/methods of the running application by typing the word Application, followed by a period, followed by what you want.
For example, I can instantiate and show a FileDialog like so:
Dim openFileDialogue As Object
Set openFileDialogue = Application.FileDialog(3)
openFileDialogue.Show
If I wanted to do this in Visio VBA, what would I need to substitute Application for in the above code?
Thanks
Try this link: http://visguy.com/vgforum/index.php?topic=738.0
At the very bottom is a code sample from "Nikolay" that shows an alternative way of getting the Fi
It shows an alternative (though more complex) way of getting the File Dialog to show up in Visio

Can I set a Excel Application Object to point to an already open instance of Excel?

I am currently trying to create an export tool to push data into Excel. However after the first push, Excel is left open, and sometimes a user may want to leave Excel open while they push more data to another page in the same excel sheet. I usually just release the COM objects once the export is done. The way my methods work right now involves opening a new instance of excel every time I export...
would it be beneficial to create a global instance of the application to use continuiously from the point I begin exporting until the point of the Excel application being closed?
Should I be using event handlers to detect when Excel has been closed so I know when to release the COM objects?
If I do try to make a global instance of an Excel Application, I can instantiate it and wait to release it, that way I don't need to try and find open instances of excel again.. but if I needed to find, and assign to a variable, an open instance of Excel (that has previously existed in code but had the COM objects released), how would I do this?
I have used this in the past. tPath is the path to my excel file that should be opened/reused.
Dim exApp As New Excel.Application
'finds the workbook. If it is already open, then it uses that. Otherwise, it opens in new instance
Dim wb As Excel.Workbook
wb = System.Runtime.InteropServices.Marshal.BindToMoniker(tPath)
exApp = wb.Parent
You can use the Interop Library to point to the open excel-app
(This code is written in C# so there could be some minor change for VB.Net)
oExcel = (Excel.Application)System.Runtime.InteropServices.Marshal.GetActiveObject("Excel.Application")