Need to create COM DLL to use in Scripting like "Excel.Application" - com

I want to create a COM DLL using VSS 2010 and need to register to Registry. My aim is I want use that created DLL like "Excel.Application", "Word.Application", "Wscript.Shell" kind-of.
I want to create instance using CreateObject / New OleObject methods and use the same in my Scripting (VBScript or JavaScript).
Any one help me to create a COM object and how to register it?
I tried to create COM Object and tried to register using RegSvr32.exe. It says "dll was loaded but no entry point found. Make sure valid dll or ocx"
Here is my code for your ref...
<ComClass(ComClass1.ClassId, ComClass1.InterfaceId, ComClass1.EventsId)> _
Public Class ComClass1
Public Const ClassId As String = "b3b13b6c-6de5-47cb-ad6f-0ae5c7ce5c59"
Public Const InterfaceId As String = "68536b50-1b47-42d5-970f-d3d34b56d681"
Public Const EventsId As String = "413fa5c3-76fa-44d0-b753-1f3d3f52dbaf"
' A creatable COM class must have a Public Sub New() with no parameters,
' otherwise, the class will not be
' registered in the COM registry and cannot be created
' via CreateObject.
Public Sub New()
MyBase.New()
End Sub
Public Sub Test1()
Console.WriteLine("Test1....")
End Sub
End Class
Thanks,
Shanmugavel.C

Create a CLass Library
Inside the .vb file, Create a Interface first.
Create class by inheriting from Interface.
Create Strong Name under "Signing" TAB of Properties.
Enable the "Register for Com Interop" under "compile" TAB of Properties
Enter the Assembly Information.
Build the Solution.
After this,
Goto "Visual Studio 2010 Command Prompt"
Navigate to dll path
Register the dll using "regasm" like regasm test.dll /tlb:test.tlb
Now Registry Entries will be done under CLSID and Interface. Then
Export to GAC(Global Assembly Cache ie. C:\Windows\Microsoft.Net\Assembly) using "gacutil.exe" like gacutil /i test.dll
That's all.... We can use the COM application....
Refer the links:
http://www.codeproject.com/KB/COM/nettocom.aspx
http://www.15seconds.com/issue/040721.htm

Related

Unable to access methods in dll generated from WSDL using SVCUtil

I am attempting to create a dll from a WSDL file for accessing a web service within a VBA application. When using the compiled library I can't call the class methods i need, only the methods with similar names which are built in the proxy to build the main request/response.
This is the procedure I have tried:
Generate proxy classes in vb.net using svcutil.exe
Compile proxy classes to dll library using vbc.exe
Register dll using regasm.exe
Add reference to tlb file from within VBA (Excel)
call method from within VBA after defining an instance of the class
Svcutil "https://deltek.XXXXXX.com/Vision/visionws.asmx?wsdl" /language:vb /syncOnly
vbc /t:library /out:DeltekVisionOpenAPIWebService.dll DeltekVisionOpenAPIWebService.vb
regasm /codebase /tlb DeltekVisionOpenAPIWebService.dll
An extract of the generated vb file:
Option Strict Off
Option Explicit On
<System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0"), _
System.ServiceModel.ServiceContractAttribute([Namespace]:="http://tempuri.org/Deltek.Vision.WebServiceAPI.Server/DeltekVisionOpenAPIWebServi"& _
"ce", ConfigurationName:="DeltekVisionOpenAPIWebServiceSoap")> _
Public Interface DeltekVisionOpenAPIWebServiceSoap
'CODEGEN: Generating message contract since element name ConnInfoXML from namespace http://tempuri.org/Deltek.Vision.WebServiceAPI.Server/DeltekVisionOpenAPIWebService is not marked nillable
<System.ServiceModel.OperationContractAttribute(Action:="http://tempuri.org/Deltek.Vision.WebServiceAPI.Server/DeltekVisionOpenAPIWebServi"& _
"ce/UpdateOpportunity", ReplyAction:="*")> _
Function UpdateOpportunity(ByVal request As UpdateOpportunityRequest) As UpdateOpportunityResponse
End Interface
Partial Public Class DeltekVisionOpenAPIWebServiceSoapClient
Inherits System.ServiceModel.ClientBase(Of DeltekVisionOpenAPIWebServiceSoap)
Implements DeltekVisionOpenAPIWebServiceSoap
<System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)> _
Function DeltekVisionOpenAPIWebServiceSoap_UpdateOpportunity(ByVal request As UpdateOpportunityRequest) As UpdateOpportunityResponse Implements DeltekVisionOpenAPIWebServiceSoap.UpdateOpportunity
Return MyBase.Channel.UpdateOpportunity(request)
End Function
Public Function UpdateOpportunity(ByVal ConnInfoXML As String, ByVal DataXML As String) As String
Dim inValue As UpdateOpportunityRequest = New UpdateOpportunityRequest()
inValue.Body = New UpdateOpportunityRequestBody()
inValue.Body.ConnInfoXML = ConnInfoXML
inValue.Body.DataXML = DataXML
Dim retVal As UpdateOpportunityResponse = CType(Me,DeltekVisionOpenAPIWebServiceSoap).UpdateOpportunity(inValue)
Return retVal.Body.UpdateOpportunityResult
End Function
End Class
I expect to be able to call the class methods that relate to the web service calls, but the only methods that are available (returned by autocomplete/don't error as not defined when called) are the methods used to build the request and response as defined in the interface.
Edit:
Somehow missed that regasm was reporting this error, but not sure how to address it:
Type library exporter warning processing 'DeltekWebAPI.DeltekVisionOpenAPIWebServiceSoapClient, DeltekVisionOpenAPIWebService'. Warning: Type library exporter encountered a type that derives from a generic class and is not marked as [ClassInterface(ClassInterfaceType.None)]. Class interfaces cannot be exposed for such types. Consider marking the type with [ClassInterface(ClassInterfaceType.None)] and exposing an explicit interface as the default interface to COM using the ComDefaultInterface attribute.

COM Visible Assembly - Object method not accessible through its exposed interface method

I implemented a .NET DLL with COM visibility (VB.NET):
Public Class Processer Implements IProcesser
Public Sub processASpecificThing(ByVal param As String) _
Implements IProcesser.processAThing
' [...]
End Sub
End Class
Below the Interface definition. For some reasons I exposed a method with a different name in the interface.
Imports System.Runtime.InteropServices
Imports System.ComponentModel
<InterfaceType(ComInterfaceType.InterfaceIsDual)> _
Public Interface IProcesser
Sub processAThing(ByVal param As String)
End Interface
The project is configured to set the Assembly as COM visible. If I understood correctly InterfaceIsDual let the Interface be visible at early binding as well as at late binding.
In a VB6 project, this works:
Dim aProcesser as IProcesser
Set aProcesser = New Processer
aProcesser.processAThing "param" ' Call by the *Interface* method name
In a VB6 project or an ASP classic VBScript page, this fails:
Dim aProcesser
Set aProcesser = CreateObject("ProcessLib.Processer")
' Call by the *Interface* method name
aProcesser.processAThing "param" ' [FAIL]
' Call by the *Interface* method name
aProcesser.processASpecificThing "param" ' [SUCCESS]
The failing line leads to the error message:
Object Doesn't Support this Property or Method
The real context of this question is an ASP classic page. I use a late binding to avoid adding a METADATA header in the ASP file (I believe it's the only way, but not tested yet).
Sounds like the interface is not accessible. Why does that problem occur and how could I make the interface accessible with ?

Can a class library use function stored in main project?

In my VB.NET application, I would like to move some code (a class) into a separate file. The separate file will use functions located in the main project.
If I create a Class Library, functions called from the DLL are not defined in the DLL and Visual Studio won't compile it.
In what ways could I move code into file and load/execute it at runtime and get the result the my main code? I don't know if I'm clear...
This can be done indirectly using interfaces. Create a public interface in the library that has the calls you need to make against that main project's class. Have the main project's class implement this interface. When the main projects starts have it pass in instance of this class in to the library project via the interface. The library should store this reference. It can now makes calls against the main projects class using this reference through the interface.
The Library Project:
Public Interface ITimeProvider
ReadOnly Property Time As Date
End Interface
Public Class LibraryClass
Private Shared _timeProvider As ITimeProvider
Public Shared Sub Init(timeProvider As ITimeProvider)
_timeProvider = timeProvider
End Sub
Public Function GetTimeString() As String
Return "The current time is " & _timeProvider.Time.ToString
End Function
End Class
The Main Project:
Public Class SimpleTimeProvider
Implements ClassLibrary1.ITimeProvider
Public ReadOnly Property Time As Date Implements ClassLibrary1.ITimeProvider.Time
Get
Return Date.Now
End Get
End Property
End Class
Public Class MainClassTest
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ClassLibrary1.LibraryClass.Init(New SimpleTimeProvider)
Dim test As New ClassLibrary1.LibraryClass
Console.WriteLine(test.GetTimeString)
End Sub
End Class
This example has the library project using a class that is defined in the Main project.
Simple answer is - you can't.
You can't have assemblyA referencing assemblyB and assemblyB referencing assemblyA
The solution is probably to move any code that is used by both your application and assembly into the assembly. Then both can access this code

VB.net load dll

I have been attempting to load a DLL using Reflector
Imports System.Reflection
I have a simple DLL file written in c++ using /CLR (this is the entire file)
using namespace System;
namespace ASSEMBLE{
public class REM{
public:
int VALUE(){
return 100;
}
};
};
And inside my VB.net butten click event i have
Dim dllPath As String = "C:\Users\richard\Documents\Visual Studio 2012\Projects\link\link\bin\Release\dlltest.dll"
' load the assembly
Dim assembly1 As System.Reflection.Assembly = Assembly.LoadFrom(dllPath)
' get the type
Dim t As Type = assembly1.GetType("ASSEMBLE.REM")
' create an instance and add it.
Dim c As Object = Activator.CreateInstance(t)
MsgBox(t.InvokeMember("VAULE", BindingFlags.Default Or BindingFlags.InvokeMethod, Nothing, c, {}))
When event triggered (ie. i load the dll) i get the error:
Method 'ASSEMBLE.REM.VALUE' not found
Using:
<DllImport("DLL.dll")> Public Shared Function VALUE() As Integer
End Function
is not an option. I need to load the DLL after runtime.
Your REM class is an unmanaged class, and therefore reflection cannot see its methods. Using the /CLR compile option does not automatically force all classes to be managed. It just allows you to have managed classes in your project.
To allow the call to InvokeMember, you need to make REM a managed class. This can be done by adding ref to the class declaration like so:
public ref class REM{
...
};

Late binding run-time error in VB6 when creating an object from a .NET assembly

i have a vb6 project that has a reference to a vb.net com library.
the project runs well when i use early binding such as:
Dim b as object
Set b = new myComLib.testObject
when i use late binding such as:
Dim b as object
Set b = CreateObject("myComLib.testObject")
i get the following error:
Run-time error '429': ActiveX component can't create object
Any ideas?
thanks
The registry entries for the .NET COM Interop class in this case are:-
HKEY_CLASSES_ROOT\myComLib.testObject
containing a CLSID value and the CLSID entry itself
HKEY_CLASSES_ROOT\CLSID\<<myComLib.testObject\CLSID value>>
They are also replicated in
HKEY_LOCAL_MACHINE\SOFTWARE\Classes
CreateObject uses the HKEY_CLASSES_ROOT entries to retrieve the details of the class name passed in so if they're missing you will receive
Run-time error '429': ActiveX component can't create object
Within the VB6 IDE, adding a reference to the dll (in the case of a .NET assembly, via it's tlb file) bypasses this registry search thereby allowing the early binding to work without the COM registry entries.
The class has to be correctly registered for CreateObject to work. This should occur as part of the Visual Studio build process, otherwise it needs to be registered manually using Regasm.
You can test this behaviour by doing the following:-
1) Create a new VB.NET project myComLib registering for COM Interop in the project Compile properties and add a class testObject
Public Class testObject
Public Property TestProperty As String
Public Function TestFunction() As String
Return "return"
End Function
End Class
2) Build myComLib
3) Create a new VB6 project, add two command buttons to Form1 and the following code
Private Sub Command1_Click()
Dim b As Object
Set b = New myComLib.testObject
b.TestProperty = "Hello"
MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub
Private Sub Command2_Click()
Dim b As Object
Set b = CreateObject("myComLib.testObject")
b.TestProperty = "Hello"
MsgBox b.TestProperty, vbOKOnly, b.TestFunction()
End Sub
4) Run the VB6 project (without full compile as that will fail)
Command2 will popup a message box, Command1 will fail with
Compile Error: User-defined type not defined.
5) Stop the project and add a reference to myComLib via it's tlb file
6) Run the VB6 project and both buttons should now work
7) Go into the registry and delete the HKEY_CLASSES_ROOT\myComLib.testObject entry (this can be re-created by Rebuilding the .NET component, you'll need to close VB6 to carry out the rebuild)
Command2 will now fail with
Run-time error '429': ActiveX component can't create object
until the registry entry is re-added.
If you're the ClassInterfaceType.None setting, You have to add a ProgId attribute to your class to allow late binding.
For example:
[Guid("B1E17DF6-9578-4D24-B578-9C70979E2F05")]
public interface _Class1
{
[DispId(1)]
string TestingAMethod();
}
[Guid("197A7A57-E59F-41C9-82C8-A2F051ABA53C")]
[ProgId("Rubberduck.SourceControl.Class1")]
[ClassInterface(ClassInterfaceType.None)]
public class Class1 : _Class1
{
public string TestingAMethod()
{
return "Hello World";
}
}