<type1>'<typename>' must implement '<membername>' for interface '<interfacename>' - vb.net

We have a web service solution in VB .Net 2005 that we have started getting an error in. We provide an interface like the following:
Public Interface IBatchTrackerService
Function InsertBatchTracker(ByVal BatchTrackerObject As BatchTracker, ByRef errorNum As Integer, ByRef errorMsg As String) As Integer
End Interface
In our class we implement this interface with the following code.
Public Class BatchTrackerService
Implements IBatchTrackerService
Public Function InsertBatchTracker(ByVal BatchTrackerObject As BusinessObjects.BatchTracker, ByRef errorNum As Integer, ByRef errorMsg As String) As Integer Implements IBatchTrackerService.InsertBatchTracker
'Some code here'
End Function
End Class
This code was working properly but has now started causing errors. The error we receive is:
Class 'BatchTrackerService' must implement 'Function InsertBatchTracker(BatchTrackerObject As BusinessObjects.BatchTracker, ByRef errorNum As Integer, ByRef errorMsg As String) As Integer' for interface 'IBatchTrackerService'.
The odd thing is that the project compiles correctly, but shows many of these errors after the compile is finished.
We recently installed Panda as our virus protection which caused a different error that I found the solution here for.
Any help would be greatly appreciated.
Thank you.
Updated 4/21/2009 at 11:50
Both the interface and the implementation are within the same project in the solution.
Updated 4/22/2009 at 08:16
I tried removing the BusinessObjects identifier from in front of the BatchTracker type but I still get the same thing. This is just one example of what has happened throughout the entire solution. Every implementation in this BatchTrackerService is flagged as an error, plus there are several other services that have almost every implementation flagged as an error as well. But somehow the project builds successfully, and yes, it runs properly!
As for BusinessObjects, it contains many of the classes we use as parameters and it is simply another project within this solution. We do not reference any external assemblies to provide these classes to BusinessObjects.
Updated 4/22/2009 at 08:24
The last thing I noticed was that any function/procedure that doesn't use a 'BusinessObjects' class as a parameter, but simply uses strings, integers, etc is not flagged as an error.
Updated 4/22/2009 at 09:50
I tried reverting back to a previous version and I was able to compile and the error count stayed at zero. I narrowed it down to a check-in of one of the project files where the reference to BusinessObjects was slightly changed. I reverted just this project file and everything compiles fine now. Thanks to everyone for leading me in the right direction.

It sounds like you're loading up a different version of the assembly that contains your interface in the web service and in the client, causing the client to reject the signature implemented by the web interface. Ensure that the versions are the same and, if necessary, strong-sign the assembly.

Your interface specifies that the "BatchTrackerObject" parameter be of type "BatchTracker" but your implementation uses type "BusinessObjects.BatchTracker". Try removing the "BusinessObjects." qualifier from your implementation.
Do multiple assemblies provide classes within the BusinessObjects namespace?

Related

Custom DLL to avoid the IE web browser control for "unsafe controls" in a tightly controlled and regulated environment

Scenario:
My company has a legacy (read that as 32 bit) windows form application that will be around for quite some time in the future. This application uses an embedded web browser control that is supplied pages that are contained within the database that it maintains. It was built like this so we could extend/modify as needed. I say this so that I can validate that security is not a concern. Only the application and developers with the correct tools have access to the pages or database. The application is only available inside the office.
There are some processes that I need to accomplish using ActiveX objects that are embedded within the pages/application. One of the biggest and most annoying thing that happens is the ActiveX security warning when I got to create instances of things like “scripting.filesystemobject”. Example:
Set oFSO = CreateObject("Scripting.FileSystemObject")
My solution is to create a DLL that is installed locally on each machine that needs access to the extended functions, have the all the functions (whole DLL ??) marked as safe so that the web browser control does not present the security warning. I have been searching using google and came across very few examples, and all of which are in C# which is not my strongest language.
I’ve had to convert from C to Vb.Net visual basic to get what I have now. When I go to register my DLL, I get the following error message:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319>regasm
Z:\VBNet2017\APIInternal\APIInternal\bin\Debug\APIinternal.dll /tlb
Microsoft .NET Framework Assembly Registration Utility version 4.8.4084.0
for Microsoft .NET Framework version 4.8.4084.0
Copyright (C) Microsoft Corporation. All rights reserved.
Types registered successfully
RegAsm : error RA0000 : Type 'APIInternal.API.Accupay' has an invalid default COM
interface: 'APIInternal.API.Accupay'
UPDATE: Thank you Hans; the error is gone. I've also made some changes in the source code; I changed the ProgID to something that closely resembles where and what this is for. I'm still having issues in creating the object in VB Script.
This is the output from the current version of the code. This is the code, stripped down for clarity:
Option Strict On
Imports System.Runtime.InteropServices
Imports System.IO
Namespace API
Public Interface IAccupay
<DispId(1)>
Function GetFiles(ByVal Folder As String) As List(Of String)
End Interface
<Guid("8B4B5CEF-8B3A-49A1-9053-E909F82D9E73"),
ProgId("AddIn.Accupay"), ClassInterface(ClassInterfaceType.None),
ComDefaultInterface(GetType(IAccupay)), ComVisible(True)>
Public Class Accupay
Implements IAccupay
Private Function GetFiles(Folder As String) As List(Of String) Implements IAccupay.GetFiles
Return Directory.GetFiles(Folder).ToList
End Function
End Class
I have tried just about every combination of ProgID, Name space, Interface name and class name to get this error to go away without any luck. I do know there are other elements that need to be addressed or added, such as error trapping and, if I’m not mistaken, how to actually implement the ObjectSafetyOption which I still don’t know how to do.
I have been using the Guide at the bottom of this article:
Is it possible to mark an ActiveX object as safe so that IE settings need not be changed?, the second answer, but I haven’t had any success.
Please, can someone point me in the right direction, maybe show me what’s wrong with the code that I have and how to physically implement the ObjectSafteyOption that is needed for the web control. Links, additional reading, code examples or comments on how to get this fixed and working would really be appreciated.
Thank you for reading and any help you send my way, Fred
PS: If you need more information, or have a better solution, please don’t hesitate to reply or comment.
UPDATE:
With the code that I have now, I am able to access the DLL in VB.Net visual basic:
Imports System
Imports APIInternal.API
Module Program
Sub Main(args As String())
Dim API As New Accupay
Dim FileList = API.GetFiles("C:\Windows\")
For Each Item As String In FileList
Console.WriteLine(Item)
Next
End Sub
End Module
However, I still can't seem to get the correct calling for a VB Script/html page:
Set Test = CreateObject("Test.Accupay")
Which returns the VB Script error "ActiveX Component can't create object: Test.Accupay or any other iteration of the parts of the name that I tried. I think part of this is that I don't understand how the creation of the project leads to the creation of the object in a com base environment like VB Script.
Fred
The answer to this problem is two fold: You must target the correct platform (X86) AND use the 32 bit version of regasm. Once I realized this was the issue, I was able to create the DLL and use it's functions in the Web Browser control without the active X warning. One example is I can now open the default browser (in this case, NOT IE/EDGE) from a link within the WB Control and another is to get the contents of a folder for further processing within the WB page.

VB.Net Task result is automatically converted to Task(of Task)

I'm trying to convert a sub to be async and, according to every documentation (and as far as I can remember, I did it in the past), it says that I should convert my sub to a Function() as Task.
My problem is that as soon as I hit enter, it is modified to Function() as Task(of Task). To make sure it was not something inside my method, I did an empty one but it resulted in the same behaviour. I also tried doing ctrl+z to force to keep as Task but then I get, on the method,
BC36945 Visual Basic AND VB.NET The 'Async' modifier can only be used on Subs, or on Functions that return Task or Task#Of T#.
and on the caller,
BC36930 Visual Basic AND VB.NET 'Await' requires that the type 'Task' have a suitable GetAwaiter method.
Is it normal? Is it a new behaviour in 4.6.1? Or is there something additional I should do to have it work as expected and return void?
Note: I'm on Framework 4.6.1 with TupleValue nuget installed.
As mentionned by #HansPassant, for Task to be used directly without its full namespace (System.Threading.Tasks.Task), the correct import must be present (which is generally the case by default) and no other namespace should collide with it.
In my specific case, I had Microsoft.Exchange.WebServices.Dataimported which also contains a Task type so when VS modified my signature for async with as Task(of Task), what was really there was as System.Threading.Tasks.Task(Of Microsoft.Exchange.WebServices.Data.Task).
In my project, I fixed the ambiguity by adding Imports Tsk = System.Threading.Tasksand then I was able to simply write as Tsk.Task.

Calling COM component method from IBM Notes 9 fails

When calling a 32 bit COM component method registered in sysWOW64 fails with an error message:
"type mismatch in method OleVarToLsVal, Unknown found, Unknown
expected"
Its win7 64 bit, but the Notes client is installed by default as a 32 bit application. The code looks like:
dim c as Variant
dim n as Variant
set c = createobject("MSWC.counters")
n = c.Get("xx")
When debugging the call, the object is set and testable with "isObject(c)", (although you can't inspect each method/property in detail in LotusScript debug).
The method is supposed to return a primitive long. I've tried setting n as long, clng-ing the values, cstr-ing the values, the parameter, strconv the parameter, using a variable for the parameter, all to no avail.
The exact same code run by WScript VBS host (in syswow64) runs the code as expected.
So, does anybody know:
If Notes 9 COM value marshalling is working for any components?
Is Notes 9 COM set to recognize the 'wow64' alternate 32 bit registry
Are there some COM related marshalling settings somewhere in the registry I can check (if so what/where are they)?
Is there some setting to tell Notes to use 32 bit components (like IIS 32bit compatibility option)
Is there anything I need to do or could do in the main OS to 'redirect or configure' COM
Or is Notes just broken again and nobody cares?
Any help appreciated - Thanks.
The easiest and probably most productive way to solve this would be to open a PMR with IBM. They should be able to answer this quite quickly.
Well, 7 years on (and seriously obsolete!) just an update for anybody looking for an answer... There are a couple of Notes settings needed and not all COM/Active-X componenets or data types are supported by LotusScript, so even if Notes is setup correctly, you still may not be able to acces/use any specific component or some methods in the component.
The user must be allowed to run unrestricted agents/code in the 'Sign or run unrestricted methods and operations:' in the security section of the server(s) document.
The Notes client execution control list ('ECL') must allow access to 'External programs' either by default or to the code-signer. An ECL warning box will ask the user to continue if the external access has not been granted.
If you try to execute an unsupported method or unsupported data type, then further errors will be issued either by LotusScript or COM/Active-X error reporting. The Notes developer help file for 'CreateObject' gives a bit more detail about unsupported data types:
LotusScript does not support identifying arguments for OLE methods or properties by name rather than by the order in which they appear, nor does LotusScript support using an OLE name by itself (without an explicit property) to identify a default property.
Results are unspecified for arguments to OLE methods and properties of type boolean, byte, and date that are passed by reference. LotusScript does not support these data types.
Relying on the 'default property' to access a default method is a common mistake and requires you to pay extra attention to the component details. It is easy to assume the component is not working, but in fact you're just not using it properly.
One way to test this is to try to open a common object available on all Windows machines (maybe others?) maybe 'FileSystemObject' (FSO) or VbScript 'regExp' component. If these work, you can build on that. Getting the 32/64bit registration correct for your client install is another element to test/get right.
For my issues, I suspect that I was using unsupported methods or data types and having used COM/Active-X in Notes occasionally, its all worked ok in general.

WCF Generated Proxy Crashes Monodroid and Monotouch

I've generated a proxy client for my WCF RIA service class via slsvcutil.exe as described in the Xamarin "Introduction to Web Services" document, however when I try to make a call to one of the async methods, my "completed" event handler never gets called -- after a couple of minutes, the app simply terminates from the Android emulator (it does the same thing in Monotouch as well).
After several days of troubleshooting, I finally found the source of the crash, but have no idea how to fix it. I suspect it's a bug in Mono somewhere, but don't know how to troubleshoot any further.
My generated proxy has a class defined like so:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")]
[System.Runtime.Serialization.DataContractAttribute(Name = "ChangeSetEntry", Namespace = "DomainServices")]
[System.Runtime.Serialization.KnownTypeAttribute(typeof(SL5Proxy.ChangeSetEntry[]))]
public partial class ChangeSetEntry : object
{
...
}
(The code above is greatly simplified - there are about a dozen KnownTypeAttribute() lines, but I've determined that the one shown above is the source of the problem. It's important to note that the ChangeSetEntry object does not have any reference to a ChangeSetEntry[] array.)
I found that if I simply comment out the
[System.Runtime.Serialization.KnownTypeAttribute(typeof(SL5Proxy.ChangeSetEntry[]))]
line from the proxy code, everything works 100% correct and my async "completed" handler is called exactly as expected. I don't know why slsvcutil.exe generates the problematic KnownTypeAttribute() line, but it does.
My guess is that there's some kind of infinite recursion that gets created when the ChangeSetEntry class tells the runtime serializer that ChangeSetEntry[] is a known type -- the runtime tries to resolve the known type, comes back to ChangeSetEntry and does it all again.
So I'm curious if anyone else has seen this issue, whether it's a known problem and whether there is a workaround -- perhaps some way to suppress the generation of the KnownTypeAttribute() lines from slsvcutil.exe

Is there any way to display a Windows form BEFORE the "Startup" form is loaded in VB.NET?

My company's main software package includes a hefty configuration library which loads on startup. This config library includes some mandatory settings which, if not supplied (via command line arguments), cause the entire application to exit.
This has never been an issue for our users, who launch the software via scripts which have the needed command line arguments supplied automatically. But sometimes when debugging our software we developers forget to specify the necessary arguments in Visual Studio's debug options; it's then very annoying to be greeted with the message Config specification invalid -- missing required parameters X, Y, and Z -- shutting down (I'm paraphrasing, of course).
It's not really a big deal, just an annoyance. Still, I felt it worthwhile to throw together a little form to make this process a little less painful; it notifies the user which parameters are missing and allows him/her to specify values for those parameters directly on the form, without having to restart the application.
My intentions were good (I think?), but it seems I can't get this solution to actually work. The problem is that after I've launched our software with missing settings, the form pops up and prompts me as expected; but after I've entered the required parameters and it's time for the application to "really" start, I get this InvalidOperationException:
SetCompatibleTextRenderingDefault must
be called before the first
IWin32Window object is created in the
application.
I think I understand what's going on here: the VB.NET project I'm working on is doing something like this "behind the scenes"*:
Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New MainForm)
End Sub
That call to SetCompatibleTextRenderingDefault is, apparently, throwing an exception because a form was already created and displayed prior to its execution.
Is there any way around this? Is there perhaps a more "proper" solution to this problem that I'm not thinking of (i.e., should I not be trying to collect user input via a form at all)?
*This is a best guess based on what I've seen in C# WinForms projects. Strangely, unless I'm missing something, it seems that VB.NET WinForms projects completely hide this from the developer.
Do make sure that you have the application framework option turned off and Sub Main selected as the starting method. Make it look similar to this:
Sub Main(ByVal args() As String)
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
If args.Length = 0 Then
Using dlg As New OptionsDialog
If dlg.ShowDialog <> DialogResult.OK Then Return
'' Use dlg result...
End Using
End If
Application.Run(New MainForm)
End Sub
Perhaps you could use the static Debugger.IsAttached (or even a #DEBUG directive) in your program's "main" function that feeds in some input file (say an XML file) into your parsed args collection instead?