question

Upvotes
Accepted
66 4 7 13

Eikon .Net C# API not working from within Console Application (I isolated the issue but problem remains)

I am constantly running into a run-time error when referencing the .Net C# Eikon API from within a Console App/Class Library.

An unhandled exception of type 'ThomsonReuters.Desktop.SDK.DataAccess.TinyIoCResolutionException' occurred in ThomsonReuters.Desktop.SDK.DataAccess.dll Additional information: Unable to resolve type: ThomsonReuters.Desktop.SDK.DataAccess.IInternalDataServices occurred

For example, I use the following sample code that you provide at : https://developers.thomsonreuters.com/eikon-apis/net-apis-use-custom-applications/downloads

Specifically the project: Usage Example Time series API

I finally, after many hours of debugging isolated the real issue as follows:

Each time I compile my code, one or some of the dependencies copies older versions of the following 4 files into the /bin/debug or /bin/release folder:

I18nResource.dll

EikonPipeDll.dll

msvcp120.dll

msvcr120.dll

The only way any of the code works is with the newest versions of the above files in the binary folder. In my current case those are the DLLs from Nov 16, 2017, which I fetched from my C:\ProgramFiles (x86)\ThomsonReuters\... folder. As soon as I rebuild the project, older files of Nov 24, 2015 overwrite the newer files and I get the exception as indicated above.

What can I do in order to retain the 4 newest dependencies? Please note that even automated copying of the files in the Post-Build Event Command line does not work because somehow the generation of those 4 files is somehow delayed and seems to occur after the post-build events already complete.

Also, another big issue is that those 4 files are necessary in any project binary folders that may wrap around the Reuters API. For example, when I set up a test project that references my Reuters API wrapper then those 4 files need to be present in the binary folder of such test project as well , otherwise above exception will be thrown. However, unlike with all other dependencies which are automatically copied into the binary folders of projects that reference objects that rely on such dependencies, those 4 above files are not copied at all.

Can you please tell me whether there is a more professional solution out there for anyone with a paid Eikon desktop license and who wants to access data via the .Net API than being forced to use numerous HACKS to make it work? Sorry if this comes across as being overly aggressive. But I have been dealing with this issue for over a year now, on and off, and now coming back to this I still find the same exact problems bubbling up. I pointed out this problem in multiple other threads. I was clearly able to isolate the problem and someone of the Reuters developer team should be able to easily reproduce this error.

In response to answer regarding post-built event:

I could only see the following, the problem I have is that the files are copied but only old files which cause the throwing of runtime exceptions:

<Target Name="EikonSdkIpc_CopyNativeDependencies" AfterTargets="AfterBuild">
    <Error Condition="!Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll')" Text="This project needs a file provided by a NuGet package that is missing on this computer. Enable NuGet Package Restore to download it.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="EIKONSDKBUILD0001" />
    <Copy Condition="Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll')" SourceFiles="..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll" DestinationFolder="$(OutputPath)" ContinueOnError="True" />
    <Error Condition="!Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\i18nresource.dll')" Text="This project needs a file provided by a NuGet package that is missing on this computer. Enable NuGet Package Restore to download it.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="EIKONSDKBUILD0001" />
    <Copy Condition="Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\i18nresource.dll')" SourceFiles="..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\i18nresource.dll" DestinationFolder="$(OutputPath)" ContinueOnError="True" />
    <Error Condition="!Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\msvcp120.dll')" Text="This project needs a file provided by a NuGet package that is missing on this computer. Enable NuGet Package Restore to download it.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="EIKONSDKBUILD0001" />
    <Copy Condition="Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\msvcp120.dll')" SourceFiles="..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\msvcp120.dll" DestinationFolder="$(OutputPath)" ContinueOnError="True" />
    <Error Condition="!Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\msvcr120.dll')" Text="This project needs a file provided by a NuGet package that is missing on this computer. Enable NuGet Package Restore to download it.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="EIKONSDKBUILD0001" />
    <Copy Condition="Exists('..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\msvcr120.dll')" SourceFiles="..\..\..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\msvcr120.dll" DestinationFolder="$(OutputPath)" ContinueOnError="True" />
  </Target>
eikoneikon-data-apieikon-com-apic#
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
Accepted
66 4 7 13

I do not know why exactly but I got it to work both under WPF and Console Apps. I uninstalled all packages and references and re-installed with the "highest dependency" option for dependent package versions. I tried that before, and it did not work then, so I doubt this was the culprit. The only explanation I have and what I changed and made the difference is the following:

var assembly = Assembly.LoadFile(assemblyPathFileName);
                
                ////load into byte array
                //var byteArray = File.ReadAllBytes(assemblyPathFileName);


                ////create assembly
                //var assembly = Assembly.Load(byteArray);

To make sense of the above, I essentially wrap the Eikon API in my own plugin class library. The library and all its dependencies will then be loaded via the above. Before, I loaded assembly via the commented-out code, now I use "Assembly.LoadFile()". I forgot what the difference exactly in the assembly load rules between Assembly.LoadFile and Assembly.Load vs LoadFrom. But this apparently made all the difference. My hunch is that "Assembly.LoadFile" will get a path and any other dependent assemblies will be searched in the same folder while loading bytes does not provide such information. Please note that I for "Assembly.Load" I hooked into "AppDomain.CurrentDomain.AssemblyResolve += ..." in order to resolve unresolved assemblies, but nothing worked until I used "Assembly.LoadFile()".

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Upvotes
45.2k 103 43 60

When installing Eikon .NET SDK with Nuget, it will add tasks into the project file (csproj) to copy those DLL files to the $(OutputPath) folder.

If you open the project file (csproj) with an editor, you will see those tasks under the<Target>element.

 <Target Name="EikonSdkIpc_CopyNativeDependencies" AfterTargets="AfterBuild">
    <Error Condition="!Exists('..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll')" Text="This project needs a file provided by a NuGet package that is missing on this computer. Enable NuGet Package Restore to download it.  For more information, see http://go.microsoft.com/fwlink/?LinkID=317567." HelpKeyword="EIKONSDKBUILD0001" />
    <Copy Condition="Exists('..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll')" SourceFiles="..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll" DestinationFolder="$(OutputPath)" ContinueOnError="True" />
...
  </Target>

You need to verify that the locations of DLL files (SourceFiles attribute in the <Copy> element) are correct.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Please see the output of my project file, the files are copied, however, those are old files which cause runtime exceptions. When I copy the exact same 4 files from my current C:\Program Files (x86)\Thomson Reuters\.... (which are new files) then the code executes correctly. But with each re-build or re-compilation those new files are overwritten by the old files.

What is more worrisome is that those are not true dependencies. The files are not pulled into the bin folders of objects that reference the Thomson Reuters Api, hence execution still ultimately fails

Upvotes
45.2k 103 43 60

From your project file, Visual Studio copies the 64 bit version of Eikon SDK API to the output path.

SourceFiles="..\packages\ThomsonReuters.Udap.Ipc.Signed.x64.2.10.5\tools\EikonPipeDll.dll"

However, to make the application executable, you replaced the copied DLL files with the files from C:\Program Files (x86)\Thomson Reuters\..... As I know, applications in the C:\Program Files (x86)\ folder are 32 bit Windows applications.

It seems that your application is 32 bit but the visual studio copies the 64 bit version of Eikon SDK API to the output path. This is why it throws the exception at run time.

If you target the application to 32 bit platform, please use 32 bit version of Eikon SDK API (ThomsonReuters.Desktop.SDK.DataAccess.Singed) instead.

ThomsonReuters.Desktop.SDK.DataAccess.Singed is for a 32 bit application while ThomsonReuters.Desktop.SDK.DataAccess.Singed.x64 is for a 64 bit application.

The script in the project file will look like:

 <Target Name="EikonSdkIpc_CopyNativeDependencies" AfterTargets="AfterBuild">
...
    <Copy Condition="Exists('..\packages\ThomsonReuters.Udap.Ipc.Signed.2.10.5\tools\EikonPipeDll.dll')" SourceFiles="..\packages\ThomsonReuters.Udap.Ipc.Signed.2.10.5\tools\EikonPipeDll.dll" DestinationFolder="$(OutputPath)" ContinueOnError="True" />
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

You made several incorrect assumptions. Please let me correct:

My C# application is pure 64bit. That is why I stated I use the Nuget package "ThomsonReuters.Desktop.SDK.DataAccess.Singed.x64" which specifically targets 64 bit applications.


Next, risking to repeat myself, the 4 files that are copied automatically via the project (csproj) file are outdated files, yes they are 64bit which matches with my application, but they DO NOT WORK. THEY CAUSE RUNTIME EXCEPTIONS. So, I have to manually copy the files from "C:\Program Files (x86)\Thomson Reuters\Eikon\X\Bin (x64)" which are also 64 bit...

...and though that manual copy causes the API to work, those files get overwritten with each re-build or re-compilation of the code.

The critical thing here is that your mechanism of copying the 4 files DOES NOT WORK. It produces 4 outdated files. The dates of the 4 files I manually copy over are from November 16, 2017 (File Version 9.42.0.140). The files that your nuget package contains are older and DO NOT WORK. Does that make my problem clearer?

Although the versions are older than the libraries in Eikon, it works on my machine. My simple application can load those libraries and run properly.

Could you please share the full .csproj file?

Please find attached the project filereuters.zip

reuters.zip (2.5 KiB)
Upvotes
45.2k 103 43 60

Thank you so much for the project file. It looks okay.

First, I would like to focus on the version of EikonPipeDll.dll file. From my test, both versions can run properly and be able to retrieve the data. The followings are screenshots of Process Explorer that shows the versions of DLL files loaded by the application.

This one is for version 9.0.11.1902 (11/24/2015).

The following picture is for version 9.42.0.140 (11/16/2017).

I think that if the version of ThomsonReuters.Udap.Bus.Tools.dll is 2.10.5.157 (11/24/2015), the correct version of EikonPipeDll.dll should be 9.0.11.1902 (11/24/2015).

The default platform of the example program is x86. After changing to x64, the script may incorrectly copy the x86 (32bit) DLL files to the output folder which causes the run-time exception. You may verify the platform of the DLL files copied by the Visual Studio with a "dumpbin /headers" command from Visual Studio Command Prompt.

C:\...\DataApiUsageExampleTimeseriesData\bin\x64\Debug>dumpbin /headers EikonPipeDll.dll
Microsoft (R) COFF/PE Dumper Version 14.00.24215.1
Copyright (C) Microsoft Corporation.  All rights reserved.

Dump of file EikonPipeDll.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
            8664 machine (x64)
               6 number of sections
        535E2E75 time date stamp Mon Apr 28 17:33:25 2014
               0 file pointer to symbol table
               0 number of symbols
              F0 size of optional header
            2022 characteristics
                   Executable
                   Application can handle large (>2GB) addresses
                   DLL

...

If it is a DLL for x64 machines, you will see machine (x64) in the result.


2015version.png (17.0 KiB)
2017version.png (17.2 KiB)
icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

Some observations:

1) ThomsonReuters.Udap.Bus.Tools.dll 2.10.5.157 (11/24/2015) definitely does not work with EikonPipeDll.dll 9.0.11.1902 (11/24/2015) together, at least not as of now. Maybe it did in the past, I cannot verify it, but it throws the same runtime exception as stated in my original question. Please see screenshot of the versions that are NOT compatible.

2) The core problem remains that because those are not hard dependencies, they are never pulled by any application or class library that may indirectly reference the Reuters API via wrappers.

capture.png (62.7 KiB)

I have investigated a bit further and I am not even sure whether those 4 files are thre culprit. I just noticed that I had some exceptions excluded from being thrown in the Exception Settings of VS. Now after throwing each and every exception I actually get the following runtime exception :

capture.png (72.4 KiB)

That happens before the original "ThomsonReuters.Desktop.SDK.DataAccess.TinyIoCResolutionException" is thrown.

I verified and I definitely reference Version 2.1.2 of the Common.Logging library. In fact, nuget automatically installed that version when I pulled in ThomsonReuters.Desktop.SDK.DataAccess.Signed.x64

Any idea what this might be caused by and also whether this may potentially be related to the original run time error?

Upvotes
45.2k 103 43 60

From the previous attached project file, when installing Eikon SDK, Visual Studio may use Highest value for the DependencyVersion option so it installed the highest version of dependency packages. For example, it installed Common.Logging version 3.4.1 instead of 2.1.2.

 <Reference Include="Common.Logging, Version=3.4.1.0, Culture=neutral, PublicKeyToken=af08829b84f0328e, processorArchitecture=MSIL">
  <HintPath>..\..\..\packages\Common.Logging.3.4.1\lib\net40\Common.Logging.dll</HintPath>
  </Reference>
  <Reference Include="Common.Logging.Core, Version=3.4.1.0, Culture=neutral, PublicKeyToken=af08829b84f0328e, processorArchitecture=MSIL">
  <HintPath>..\..\..\packages\Common.Logging.Core.3.4.1\lib\net40\Common.Logging.Core.dll</HintPath>
  </Reference>

For an application to use these highest dependency packages, App.config of the application should have the following entries.

  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="protobuf-net" publicKeyToken="257b51d87d2e4d67" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-2.3.3.0" newVersion="2.3.3.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
      </dependentAssembly>
      <dependentAssembly>
        <assemblyIdentity name="Common.Logging" publicKeyToken="af08829b84f0328e" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-3.4.1.0" newVersion="3.4.1.0" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>

For those 4 DLL files issue, could you please use a Process Monitor tool to monitor your process in order to verify the problem?

Please refer to this question regarding how to use the Process Monitor tool.

icon clock
10 |1500

Up to 2 attachments (including images) can be used with a maximum of 512.0 KiB each and 1.0 MiB total.

my app.config reflects your above value, and it did before. But please see my answer as I got it to work, independently of your suggestion. But thank you for your help and suggestions.