none
How to Make a COM Server with VB.Net RRS feed

  • Question

  • I have a COM server created in VB6 as an ActiveX .exe that is exposed to COM by using the /REGSERVER command line (i.e. after the ActiveX app was compiled, I entered the full path name of the app in the "Run" command followed by " /REGSERVER"). The purpose of this app is to receive event details from another third party app. When you subscribe to this third party app's events, you either provide the ProgID (which is the name of my app and the name of the class it contains that handles the event details, separated by a period) or the CLSID (I used the former).

    Now I would like to replace this old VB6 app with a VB.Net one. What is the best way to go about this?

    I see posts talking about setting the "Register for COM interop" property to true, but this is not available for Windows apps. If this is the way to go, what types of VB.Net projects do have this property available? The third party app requires that the app containing the "callback" class be compiled as an .exe.

    Larry

    Wednesday, November 15, 2017 6:40 PM

All replies

  • Hi Larry,

    This forum is for issues while using VS debugger tools, as your issue is more related to VB, I will move it VB forum for you to get a professional answer.

     

    Best regards,

    Fletcher


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.


    • Edited by Fletch Zhou Thursday, November 16, 2017 6:31 AM
    Thursday, November 16, 2017 6:31 AM
  • Hi LarryS10,

    According to your description, you want to use vb.net project to achieve the same goal. Do you want to create new vb.net project or just want to search one app to achieve goal?

    Best Regards,

    Cherry


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, November 23, 2017 7:59 AM
    Moderator
  • An ActiveX EXE cannot be created in .NET, but I'm not sure that you need one in this instance. It sounds like you have a COM "event sink" with the third-party app but I'm not sure because there isn't enough detail about this solution. Does this third-party app have a COM interface? Maybe you could post some of your Classic VB code for conversion.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Thursday, November 23, 2017 2:53 PM
  • Here is a VB.NET sample to create an out-of-of process .exe com server.  It's a bit old, but might be helpful -

    Out-of-process VB COM server (VBExeCOMServer)

    Thursday, November 23, 2017 6:07 PM
  • Hi Paul,

    Here is the code from the class module in the VB6 ActiveX project:

    Private Declare Function SetForegroundWindow Lib "user32" (ByVal hwnd As Long) As Long
    Private EventCounter As Integer
    
    Implements QBSDKEVENTLib.IQBEventCallback
    
    
    Public Sub IQBEventCallback_inform(ByVal eventXML As String)
    
        Dim tmpXML As String
        tmpXML = eventXML
        EventCounter = EventCounter + 1
        DisplayEvent.Text1 = Replace(tmpXML, vbLf, vbCrLf, 1, -1, vbTextCompare)
        DisplayEvent.Show
        SetForegroundWindow DisplayEvent.hwnd
        Call ParseTxnID(tmpXML)
        
    End Sub

    This "call back" class receives event information from the third party application in the form of a string. It then displays the that event info on the form "DisplayEvent".

    I want to be able to create a project in VB.Net that compiles into an .exe and exposes itself to COM. That is, once it is compiled, when I open any other project in VB.NET (or VB6 for that matter) and click on "Project > Add Reference" and then click the "COM" button, the compiled application is there to be selected. I can then insert the same class (above) in that project to receive the event info.

    In VB6, you exposed the app to COM using the "Run" command and entering the app name (full path) followed by " /REGSERVER".

    Larry

    Monday, November 27, 2017 6:13 PM
  • Is there a reason why you need to create an EXE? A DLL with a COM Class (for COM interop) should work as well. In this instance you would use the Regasm utility to register the component for COM.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Monday, November 27, 2017 10:25 PM
  • Hi Paul,

    The third party app that sends its event info requires that the receiving app (the one exposed to COM) be an EXE, NOT a DLL.

    Frankly, I think they're stuck in a time warp, but that's what I have to work with.

    Larry

    Tuesday, November 28, 2017 2:15 PM
  • Larry,

    Did you notice the sample link that I posted earlier?

    Tuesday, November 28, 2017 2:39 PM
  • Yes, thanks RLWA, I'm studying it now. Although at first glance it talks of using REGASM, which I understand registers a VB.Net project as an assembly. Having said that, it does also mention that the public class "Simple Object" is registered with COM. So there may be something there I can use.

    My initial research led me to look at adding a COM class to a Windows Form application since I can simply supply that class' CLSID to the third party once it is registered in COM. But I could not find where that COM class was ever registered with COM (I'm sure I was missing one or more steps). I thought the COM class was registered automatically when the project was compiled.

    Larry

    Wednesday, November 29, 2017 3:39 PM
  • To expose COM interfaces in .NET you need to use the Regasm utility to register for COM Interop. I used the project from RLWA32's link and this worked for me with Microsoft Word. I'm simply sinking the Microsoft Word Quit event so you would need to change that code for your component (or create a new Class).

    Just an FYI, there is a post build event (Build Events button on Compile tab of Project Properties) in the project that calls Regasm to register the component for COM.

    Public Class SimpleObject
        Inherits ReferenceCountedObject
    
        Private WithEvents oWord As Microsoft.Office.Interop.Word.Application
    
        Public Sub RunWordAndQuit()
    
            oWord = New Microsoft.Office.Interop.Word.Application
            oWord.Documents.Add()
            oWord.Quit()
    
        End Sub
    
        Private Sub oWord_Quit() Handles oWord.Quit
    
            Dim eventForm As New DisplayEvent
            DisplayEvent.Label1.Text = "Word is quitting"
            DisplayEvent.ShowDialog()
    
        End Sub
    
    End Class
    


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Wednesday, November 29, 2017 4:47 PM
  • Paul,

    The example posted seems to confuse the issue a bit.

    If I understand correctly Larry is interested in creating a COM server.  However, the posted code and comments are relevant for a COM client where Microsoft Word is the server.

    Wednesday, November 29, 2017 4:53 PM
  • Paul,

    The example posted seems to confuse the issue a bit.

    If I understand correctly Larry is interested in creating a COM server.  However, the posted code and comments are relevant for a COM client where Microsoft Word is the server.

    Current VB 6 ActiveX EXE is handling events from a third-party app according to his description and code. He wants to replace this component with a .NET version. I simply used Word since I'm not familiar with the third-party app he is using. Not sure where the confusion would be.

    >>The purpose of this app is to receive event details from another third party app. When you subscribe to this third party app's events, you either provide the ProgID (which is the name of my app and the name of the class it contains that handles the event details, separated by a period) or the CLSID (I used the former).<<


    Paul ~~~~ Microsoft MVP (Visual Basic)

    Wednesday, November 29, 2017 5:13 PM
  • Now wonder I'm confused.  The initial question is "How to make a COM Server with VB.Net"!

    • Edited by RLWA32 Wednesday, November 29, 2017 5:24 PM
    Wednesday, November 29, 2017 5:19 PM
  • Now wonder I'm confused.  The initial question is "How to make a COM Server in VB.Net"!

    RLWA,

    Please let Larry the OP reply himself. There is no problem to attend another contributor on a mistake. But then should one time enough and wait for the OP.

    If not, then start a discussion to keep threads clean. 



    Success
    Cor

    Wednesday, November 29, 2017 5:31 PM
  • Now wonder I'm confused.  The initial question is "How to make a COM Server with VB.Net"!


    Yes you are confused, but I think you are on the right track to the solution. ;-)

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Wednesday, November 29, 2017 6:49 PM
  • Paul -

    Another reason for my confusion was the OP's statement "I have a COM server created in VB6 as an ActiveX .exe that is exposed to COM by using the /REGSERVER command line (i.e. after the ActiveX app was compiled, I entered the full path name of the app in the "Run" command followed by " /REGSERVER")".

    Cor -

    IMHO, pointing out the apparent discrepancy and resulting confusion may actually be helpful to the OP. :)

    Thursday, November 30, 2017 2:05 PM
  • Guys,

    I apologize if my limited knowledge of COM and the true meaning of the term "server" has led to confusion.

    The application I currently have in VB6 and I want to replace with VB.Net simply contains a "callback" class that receives and responds to event information that QuickBooks (QB) (the third party app) sends to it. In order to tell QB where to send this information, the receiving app, compiled as an EXE, must be exposed to COM and provide either (1) the full path name of the receiving app along with the name of the "callback" class  or (2) the CLSID of the "callback" class when you subscribe to certain QB events, which you do in a separate app.

    It appears that Paul's example references the Word COM component and responds to that, whereas with my app, QB (reading between the lines) will reference my app's COM component and send info to the "callback" class in it.

    In studying RLWA32's link, I saw reference to the "standard CoRegisterClassObject API" which according to documentation "Registers an EXE class object with OLE so other applications can connect to it."

    So maybe CoRegisterClassObject is the answer for me?

    To summarize, I need to create a simple (if possible) VB.Net project that compiles to EXE which contains one public class that receives the event info from QB. Then I need to either register the entire EXE with COM of the CLSID of the public class so QB knows how to connect to it.

    I really appreciate all your help so far.

    Larry

    Thursday, November 30, 2017 3:55 PM
  • Larry,

    Since what you are describing seems to be specific to Quickbooks, I suggest you pursue the matter in its own forums for developers at https://help.developer.intuit.com/s/ for more targeted responses.

    Thursday, November 30, 2017 4:17 PM
  • So maybe CoRegisterClassObject is the answer for me?

    .

    Larry

    No, you pretty much need most of the code in that component. Just adding the registration facility isn't going to emulate an ActiveX EXE.

    What I would do is just add your code from the VB 6 ActiveX EXE Class to the SimpleObject Class and delete the HelloWorld Function. You may have to make some minor syntax changes to the code. The CLSID is documented  in the code should you need it for the QuickBooks component. I'm assuming that you will need to add the QuickBooks component to the project as well.


    Paul ~~~~ Microsoft MVP (Visual Basic)


    Thursday, November 30, 2017 9:55 PM
  • That sounds like a good plan, Paul. But when I try to build that project without making any changes, I get three errors (the first two are the same):

    An error occurred while writing the registration information to the registry. You must have administrative credentials to perform this task. Contact your system administrator for assistance.

    The third error:

    The command "echo Generate and register type library.
    C:\Windows\MicrosoftNET\Framework\v2.0.50727\regasm.exe /tlb "C:\DATA\StinsonSolutions\VBExeCOMServer\debug\VBExeCOMServer.exe"
    echo Register the component
    C:\Windows\MicrosoftNET\Framework\v2.0.50727\regasm.exe /tlb "C:\DATA\StinsonSolutions\VBExeCOMServer\debug\VBExeCOMServer.exe" exited with code 100.

    The first two errors make no sense since I am the only user on this PC and I am the administrator. I assume the last error was caused by the first two?

    Any ideas on how to resolve these?

    Larry

    Tuesday, December 5, 2017 2:53 PM
  • You must use an elevated command prompt.


    Or run the VS IDE with elevated privileges so that the build registration step also runs elevated.
    • Edited by RLWA32 Tuesday, December 5, 2017 3:19 PM
    Tuesday, December 5, 2017 3:12 PM
  • Yes, you can run Visual Studio "as Administrator" as RLWA32 mentioned or remove the post build commands and run the Regasm command line utility manually after the Build completes. Either way, registering the component for COM Interop requires elevated privileges to update the Windows Registry.

    Paul ~~~~ Microsoft MVP (Visual Basic)

    Tuesday, December 5, 2017 3:37 PM
  • To prevent the Post-Build step for registration from running you can also go to the project properties and change the properties for that step to indicate that it should not be used.
    Tuesday, December 5, 2017 3:50 PM