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

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 ?

Related

How to upload file with Asp.net Web Api project?

i have a web API project to be consumed from mobile applications and i was trying to make a file upload controller. there are few resources in C# and i don't find anything useful for VB.NET.
i tried this code below converting from c# to VB.NET, but says "Move is not a member of MultiPartFileData".
Imports System
Imports System.Collections.Generic
Imports System.IO
Imports System.Linq
Imports System.Net
Imports System.Net.Http
Imports System.Threading.Tasks
Imports System.Web
Imports System.Web.Http
Namespace HelloWorld.Controller
Public Class FileUploadingController
Inherits ApiController
<HttpPost>
<Route("api/FileUploading/UploadFile")>
Public Async Function UploadFile() As Task(Of String)
Dim ctx = HttpContext.Current
Dim root = ctx.Server.MapPath("~/App_Data")
Dim provider = New MultipartFormDataStreamProvider(root)
Try
Await Request.Content.ReadAsMultipartAsync(provider)
For Each file In provider.FileData
Dim name = file.Headers.ContentDisposition.FileName
name = name.Trim(""""c)
Dim localFileName = file.LocalFileName
Dim filePath = Path.Combine(root, name)
File.Move(localFileName, filePath)
Next
Catch e As Exception
Return $"Error: {e.Message}"
End Try
Return "File uploaded!"
End Function
End Class
End Namespace
That error message means the compiler think that you are trying to call a method from the MultiPartFileData class. The variable of type MultiPartFileData is the one called file (notice the lowercase) initialized in the For Each loop.
Instead you want to call the Move method from the System.IO.File class (notice the uppercase).
VB.NET services (always running in background looking to catch errors while you type) is case insensitive so, for it, the two names are the same and here arises the error emitted when you code that line.
The best solution is to avoid names like file for your variables when you plan to use the class System.IO.File. Otherwise you could simply add the full qualified method's name in this way
System.IO.File.Move(localFileName, filePath)

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.

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{
...
};

Can I make a function COM Only? (Opposite of <Runtime.InteropServices.ComVisible(False)> )

I have some functions in my VB.NET DLL which I can 'hide' from my VB6 app by using the following:
<Runtime.InteropServices.ComVisible(False)> _
But is there a way to make a function ONLY visible to COM clients and not to .NET assemblies?
This way I can use Shared methods for the .NET side avoiding the need for an instance declaration.
You might be able to achieve what you want by using Explicit Interface Implementation. You can declare an interface that will be used by COM clients and another one for .NET clients, leaving all methods private in your implementation class. The code may look like this:
Imports System.Runtime.InteropServices
Public Interface ITestInterface
<ComVisible(True)> _
Sub MyTestMethod()
End Interface
<ComVisible(True)> _
Public Class TestClass
Implements ITestInterface
Private Sub MyTestMethod() Implements ITestInterface.MyTestMethod
End Sub
End Class
I have to say that I do not understand what you mean with: "This way I can use Shared methods for the .NET side avoiding the need for an instance declaration. "

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

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