Unable to read data from the transport connection VB6 calling com visible c# library - com

I have a c# Framework 4.7.2 Com visible library that calls a web api.
Unit tests in the VS2017 C# IDE library work fine.
However if I try to call via VB6 I get
System.IO.IOException unable to read data from the transport connection: An existing connection was forcibly closed by the rempte
host.
System.Net.Sockets.SocketException
I am running Windows 10
I call as administrator
C:\Windows\Microsoft.NET\Framework\v4.0.30319\regasm /codebase /verbose /tlb:SBD.ComBridge.tlb C:\dev\SBD.ComBridge.dll
to create the .dll and .tlb
I also tried running regasm from the VS2017 command prompt as administrator
RegAsm reports that the libraries register successfully.
In Vb6 the (simplified) code is
Dim o As SBD_ComBridge.BridgeImplementation
Set o = New dBridgeImplementation
o.SetOrderDates id
set o = nothing
In BridgeImplementation the (simplified) code is
[DispId(25)]
[ComVisible(true)]
public void SetOrderDates(int Id)
{
PackAndSend.SetReadByInfo(Id) // calls freight service
}
I know that the code calling the service from within SetReadyByInfo works because my unit test passes when I run it in VS2017
Unfortunately I have been asked not to post the code. However I know that the vb6 code calls Com correctly because there are other methods I call without errors.
I had a similar issue with MYOB api and TLS the solution was to upgrade the Framework. However I can't upgrade the VB6 framework ( the large re-write is not an option) Probably I will just make a .Exe and shell out to it.
[Update]
The link Simon Mourier gave me solves it.
If I add
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
then my com call works on VB6
As the link points out,
This isn't a good solution since it hard codes what TLS version to
use, so it wouldn't use TLS 1.3 in future

As per the update section at the bottom of my question, a work around is to include
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
I need to investigate further for a more complete solution

Related

Web-service moniker in Excel 2016

I have a VBA macro which uses a moniker generated by GetObject to interact with a WCF web-service.
The string describing the web-service passed to GetObject looks like:
service:mexaddress=http://my.net/ws/MyService.svc/mex,
address=http://my.net/ws/MyService.svc,
contract=IMyService,
contractNamespace=http://tempuri.org/,
binding=BasicHttpBinding_IMyService,
bindingNamespace=http://tempuri.org/
All is working fine on Windows 7 with Excel 2010.
But on Windows 10 with Excel 2016 it fails with an Automation Error Invalid Syntax 800401e4.
I've tried different syntaxes seen on documentation and tutorials like service4:mexAddress, with and without quotes ' and double-quotes "... but with no luck so far.
I've even tried to debug it with Visual Studio as I've read that the web-service moniker stuff is implemented in .Net and that I could catch some more explicit exception, but none was caught though I've asked Visual to catch everything it can.
EDIT 1
I've built a new basic WCF service from scratch and the result is the same,
I've traced Excel.exe with ProcMon; not sure it is relevant but on Windows 10/Excel 2016 I see that it tries to access pathes like C:\Users\my-user\Documents\service:mexaddress=http://my.net/ws/MyService.svc/mex, address=http: whereas it is not the case on Windows 7/Excel 2010.
Maybe it's missing the component that handles the service "protocol".
EDIT 2
I've tried to directly embed the WSDL metadata into the connection-string (as described in Using the WCF Moniker with COM Clients) but still the same error,
I've tried to spy the HTTP exchanges with the Fiddler proxy but no request are visible.

How To Reference a Com Object in a WCF Service

I need to reference a Com DLL from within a Silverlight program. Since this is not allowed, I created a wcf service and put my reference to the Com in it.
This idea seems to work fine when I ran my wcf service from my local machine but when I publish the service to my server it failed to work. The error was “Object reference not set to an instance of an object” where I tried to instance the DLL.
Here problem line is
m_cloVB6Encryption = New VB6Encryption.cEncryption
VB6Encryption is a complicated one. It called another DLL which calls several others.
To try to isolate the problem I created a very simple VB6 component, this time I got the error
"Retrieving the COM class factory for component with CLSID {74FE605A-5861-41A0-BA13-27DDD9C2EBB8} failed due to the following error: 80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG))."
This is despite the fact that I manually registered the component and it was successful.
The problem line was cloSimple = New Simple.cSimple.
My computer runs Windows 7; the server runs Windows Server 2012 R2 Standard.
Presumably your COM component was build as 32bit...so when you register it is registered as a (InProc) 32bit COM component....(and can only be loaded by a 32bit application).
Your ASP.NET Website is most likely running in an AppPool that is set to be 64bit...thus it can't use the 32bit COM class.
There are 2 options (the clearest and easiest is option 1):
1) Get your IIS WebSite/Application to run as 32bit, so it can access your already registered 32bit COM component.
To make sure your website is running as 32bit too (instead of as 64bit)...change the DefaultAppPool to enable 32bit applications (or you can create a new AppPool which is 32bit specifically for that webservice/site and make it use it...if you don't want to affect other sites).
https://help.webcontrolcenter.com/kb/a1114/how-to-enable-32-bit-application-pool-iis-7-dedicatedvps.aspx
OR
2) Do some additional registration so that your COM class is available to 64bit clients too (you register it so it is run OUT OF PROCESS...so it can be consumed by either 32bit or 64bit clients....but you might not want that for perf reasons...and it might not always be possible)
http://www.gfi.com/blog/32bit-object-64bit-environment/

Why is my ObjectContext empty when debugging vb 6 dll for an asp classic page IIS6?

I'm trying to debug a VB 6 dll that is used in an ASP classic page. I've gotten other dll working, but one in particular is causing me some real headaches. This one references the COMSVCSLib COM and when debugging, is empty.
...
Dim objContext as COMSVCLib.ObjectContext
Set objContext = GetObjectContext
...
When compiled and called from the asp page, all is fine,
<%
dim obj
set obj = Server.CreateObject("page_builder.glue")
obj.Login
set obj = nothing
%>
I have 'EVERYONE' added to all aspects of the VB ASP debugging DCOM.
I am running Windows Server 2003 in 32-bit on a 64 bit machine, using IIS 6.
As I mentioned other DLLs debug fine, it's just this aspect of this one that doesn't work.
Any suggestions?
The COMSVCLib.ObjectContext object represents the object context in the DCOM host (dllhost.exe). This context gives you access to properties that describe the configuration of your DCOM Application in Component Services.
When you run your .DLL project in debug mode in VB6 however, the DLL will be hosted by the VB6.exe process. This process doesn't have any configuration of the kind that your DCOM Application has, so the VB6.exe process doesn't contain any object context information.
Therefore the GetObjectContext will return nothing.

Error 404 - file not found on Silverlight RIA service call

I have search everywhere for a solution to my problem, but I am not able to find one. I have built a Silverlight 4 Navigation app, and am using RIA Services to process a custom entity (which is essentially running server-side calls to COM dlls). In my debug environment, everything works fine, but when I try to deploy to IIS7 (on the development machine) as a website, it gives me the following error when calling the Get query on the entity:
Load operation failed for query 'GetNewHWCoil'. The remote server returned an error: NotFound.
at System.ServiceModel.DomainServices.Client.OperationBase.Complete(Exception error)
at System.ServiceModel.DomainServices.Client.LoadOperation.Complete(Exception error)
at System.ServiceModel.DomainServices.Client.DomainContext.CompleteLoad(IAsyncResult asyncResult)
at System.ServiceModel.DomainServices.Client.DomainContext.<>c__DisplayClass1b.<Load>b__17(Object )
Everything I found online says to check the Authentication area on IIS and make sure that it is set only to Anonymous Authentication, which it is. And they also say to enable WCF logging, which when I add the necessary text to the web.config file, I still don't get any logs. They also say to use Fiddler2 to trace the HTTP calls, but I only get a 404 error on there with the textview giving me the standard IIS file not found website. I cannot figure out how to debug this problem.
The Silverlight app needs to make calls to a set of 3rd party COM dlls to calculate the performace of water coils. Since I do not want to have the app run OOB, (this will negate the whole point of it being a web app instead of a WPF app) I have the ASP.net project interacting with the dlls using the custom entities.
The function (or Query as RIA services calls it) GetNewHWCoil is located in the DomainService class and uses this code:
Public Function GetNewHWCoil() as HWCoil 'HWCoil is a custom object
If bRanCalc then 'bRanCalc is a global boolean variable that gets set to true if the calc call on the dlls have been made
Return mHWCoil 'global copy of the calculated coil object
bRanCalc = False
else
Return New HWCoil
end if
End Function
The error runs before any calculation should be called, so it is assumed that it is erroring on the 'Return New HWCoil' part.
Any help on this would be appreciated.
Thanks,
Chris
I found the solution to my problem. I fonud out that I can have VS run the debug from IIS, and when I had it create the virtual directory it told me I needed to install ASP.NET 4 on the server. I thought that by checking the ASP.NET checkbox in the Add Windows Features dialog that I had already done that. But it only installed .NET 2 version. So after looking online for this new problem, I found that I needed to run the command
C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis -i
and everything worked fine after that.
Chris

WCF can only serialize parameters on development machine

I have created a WCF service using vb.net. Everything works fine on my development machine but when I deployed it it failed with the following error
'There was an error while trying to deserialize parameter http://tempuri.org/:querys'
I call a single method on the service and it has a single parameter called 'querys'. This parameter was a list(Of CustomType).
I then created a new method with a single parameter of type ArrayList. Thinking that this should serialize. Again it works fine on my development machine but fails when I deploy it with the same error a above.
I am completely stumped how it can serialize a parameter on one machine and not on another. I've tried it on 2 other machine and it doesn't work on either of them. So that rules out a problem with the machine itself.
All machines are running Win XP and .Net v3.5. The service was developed using VB .net in Visual Studio 2008.
Has anyone else experienced this?
I have not included any code because the error is happening System.ServiceModel and as I mentioned above the code does work on the development machine.
Please let me know if you need any more information.
Thanks in advance
Did you mark your 'CustomType' and its fields/properties you want to serialize with attribute DataContract, DataMember?
When you add the service reference to your client app which setting do you use? (Reuse types in referenced assemblies, always generate message contracts...)
If you host the WCF service on a IIS, then you should remember to run this command on the servers.
C:\WINDOWS\Microsoft.NET\Framework\v3.0\Windows Communication Foundation\ServiceModelReg.exe /i /x
Thanks to everyone who replied,
I have resolved the problem but unfortunately do not how. I tried many code changes but as far as I can tell I have reset the code back to the way it was. It is working now and I can not spend any more time on the issue to find out what caused it.
Just one of those things I guess.