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{
...
};
Related
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.
I recently tried Protobuf-net r668 with my vb.net code. I can mark attributes on my data class but can't get the Serialize and Deserialize features to work.
I followed the instructions at http://code.google.com/p/protobuf-net/wiki/GettingStarted but having converted the code to vb.net I found that this C# code:
using (var file = File.Create("person.bin")) {
Serializer.Serialize(file, person);
}
Won't work when translated to vb.net because the Serialize method does not show up as a method of class Protobuf.Serializer.
Any pointers from anyone who has got Protobuf-net working in vb.net would be helpful.
It should just work; the following runs fine, for example:
Imports System.IO
Module Module1
Sub Main()
Dim strFileName As String = "foo.bin"
Dim f As FileStream = File.Create(strFileName)
Dim objData As Foo = New Foo With {.Name = "abcdef"}
ProtoBuf.Serializer.Serialize(f, objData)
End Sub
<ProtoBuf.ProtoContract>
Class Foo
<ProtoBuf.ProtoMember(1)>
Property Name As String
End Class
End Module
My initial thought is that you have referenced a version of the protobuf-net.dll that is intended for one of the mobile platforms, which expose some features slightly differently. Specifically, a dll from the "core only" build. The intended purpose of each different build is described in the What Files Do I Need.txt file (which is include in the root of the package)
I wrote a DLL in C# in VS2012:
namespace COMTest
{
public class MyClass
{
public int Fun()
{
return 3;
}
}
}
And then I set "Make Assembly COM Visible=True" and in the Build page, I set "Register COM for intercrop". Then create a new VB6 project, add a reference to the generated dll file but failed……Later tried tlb file succeeded but without intellisense after saying "a." (No "Fun" tip)
Dim a As MyClass
Set a = New MyClass
MsgBox (a.Fun())
So my questions are:
1) Why must I refer tlb file instead of dll file?
2) Why no intellisense?
Try placing a check mark in:
Tools->Options->Editor->Auto List Members
If that does not help, then to resolve this problem, define a public interface by using methods and properties that you want to expose in the TLB, and then implement the interface in the class. Also, add the ClassInterface (ClassInterfaceType.None) attribute to the class. As you develop the component, you can use this approach to avoid using the ComVisible(False) attribute.
You can have more details here
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";
}
}
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