C#, .NET Core, and NuGet

C#, .NET Core, and NuGet

This week, we publish a new version of our C# library with some interesting new features: the library is now available through the NuGet package manager, we support .NET Core 2, and finally we managed to get rid of the dllmap entries that we needed to add when using our library with Mono.



Let's start with the last item: No more need for dllmap entries in the app.config file.

As we explained it three weeks ago, the C# library is made of C# code but also of a "yapi" dynamic library which is compiled for each OS. Under Windows, the .NET virtual machine can automatically retrieve the correct version of this library, but with Mono we had to add entries in the application configuration file for the library to work. This is not necessary anymore.

We must simply copy in the executable directory the different versions of the "yapi" library which are located in the Sources/dll subdirectory. Concretely, for your application to work with Mono, you must have in your executable directory the following files:

  • yapi.dll : the "yapi" library for Windows 32 bits
  • amd64/yapi.dll : the "yapi" library for Windows 64 bits
  • libyapi-i386.so :the "yapi" library for Linux 32 bits
  • libyapi-amd64.so : lthe "yapi" library for Linux 64 bits
  • libyapi-armhf.so : the "yapi" library for Linux ARM
  • libyapi.dylib :the "yapi" library for macOS (64 bits)
  • libyapi32.dylib : the "yapi" library for macOS (32 bits)


When executing, our library automatically detects the OS and loads the correct version of the library.

.NET Core 2


Getting rid of dllmap entries allowed us to add support for .NET Core 2.x. .NET Core is a new implementation of the .NET standard created by Microsoft.

This implementation has the following advantages:

  • The Windows, macOS, and Linux operating systems are supported
  • Intel 32 and 64 bits processors are supported for all the OSes, as well as ARM processors but only for Linux
  • The project is Open Source (https://github.com/dotnet/core)
  • Microsoft actively contributes to the development


For more information on what .Net Core is, we leave you to read Microsoft's documentation on the topic.

To use the C# library in a .NET Core project, the process is identical: you must add the .cs files and copy the Sources/dll subdirectory files into the executable directory. But as we are going to see below, you can use NuGet to automate this task.

The NuGet package


We took advantage of these modifications to publish our library under NuGet: https://www.nuget.org/packages/Yoctopuce.YoctoLib/

NuGet is a package manager developed by Microsoft for .NET projects. Its aim is to ease the life of developers by taking care of downloading and installing the libraries which are used in a project.

The problem with NuGet is that between the different types of Visual Studio projects, the different versions of the NuGet client, and now the new .Net Core projects, it's difficult to have one library which works for everybody.

In order to have a easy to use package, we limited its use to the following cases:

  • A "traditional" .NET project since Framework 4.5
  • A .Net Core project since version 2.0


In all other cases, you can still use our library, but you must manually add the source files and copy the "yapi" dynamic library, as explained in our introductory post.

An example is better than long speeches


To show how to use the NuGet package, we are going to write a short command line program which lists the Yoctopuce modules connected to the USB ports.

The source code is that of the "Doc-Inventory" example which is included with the library sources:

class Program
{
    static void Main(string[] args)
    {
        YModule m;
        string errmsg = "";

        if (YAPI.RegisterHub("usb", ref errmsg) != YAPI.SUCCESS) {
            Console.WriteLine("RegisterHub error: " + errmsg);
            Environment.Exit(0);
        }

        Console.WriteLine("Device list");
        m = YModule.FirstModule();
        while (m != null) {
            Console.WriteLine(m.get_serialNumber()
                           + " (" + m.get_productName() + ")");
            m = m.nextModule();
        }
        YAPI.FreeAPI();
    }
}



We are going to show you how to implement this short program in a .NET Framework project as well as in a .NET Core project.

.NET Framework 4.5 and above


You must start by creating a new project of type "Console App (.NET Framework)" in Visual Studio.

You must create a new project of type 'Console App (.NET Framework)' in Visual Studio
You must create a new project of type 'Console App (.NET Framework)' in Visual Studio



Then, you must access to the "NuGet package manager". You can do so by using the menu ("Tools"->"NuGet Package Manage"->"Manage NuGet Package for Solutions...") or with a right click on the project by selecting "Manage NuGet Package...".

The NuGet tab is available through the menu in Visual Studio
The NuGet tab is available through the menu in Visual Studio



The NuGet tab allows you to look for the Yoctopuce package and to add it to the project directly from NuGet.org with the "Install" button.

The NuGet tab allows you to look for the Yoctopuce package and to add it to the project
The NuGet tab allows you to look for the Yoctopuce package and to add it to the project



When installed, the Yoctopuce.YoctoLib NuGet package is displayed in the project Reference.

The Yoctopuce.YoctoLib package is listed in the project references
The Yoctopuce.YoctoLib package is listed in the project references



Here you are. There is nothing else to do. When compiling, the dynamic libraries are automatically copied with the executable in the output directory.

Note that all the versions of the "yapi" dynamic library are copied, including the Linux and macOS versions. This means that you can directly use the application under Linux or macOS with Mono. You only need to copy the complete directory and to run the executable with Mono.

.NET Core 2.x


We are going to see how to implement the same application but this time under Linux using .NET Core 2.2.

Under Linux, there is no IDE, but only the dotnet tool which enables you to compile and run a .NET Core project.

We start by creating a new project of type "console" with the new command and the "console" option:

yocto@linux-laptop:~/demo$ dotnet new console



Then, we must edit the Program.cs file to add the code of our example in the Main() function.

Before compiling the project, we need the Yoctopuce.YoctoLib package. For this we use the add package command with the name of the Yoctopuce package.

yocto@linux-laptop:~/demo$ dotnet add package Yoctopuce.YoctoLib



Then you can directly run the executable with the run command:

yocto@linux-laptop:~/demo$ dotnet run Device list LIGHTMK3-A10AB (Yocto-Light-V3) yocto@linux-laptop:~/demo$



Conclusion

Getting rid of the dllmap entries invalidates a large part of what we discussed three weeks ago, but it enabled us to add support for .NET Core and a NuGet package.

.Net Core is not much used yet, but it is promising. Indeed, you can create "completely autonomous" applications by creating applications containing the .NET machine directly. This enables you to compile applications which can be used directly on a Raspberry Pi without needing to install anything else. But this is a topic for another post...




1 - andiw Sunday,march 17,2019 8H24

Great news! Unfortunately, the NuGet package does not work for me in my .NET Framework 7.4.2 class library. It does simply not appear in the project's references. Here is the log of the console (sorry, in German):

PM> Install-Package Yoctopuce.YoctoLib

Es wird versucht, Abhängigkeitsinformationen für das Paket "Yoctopuce.YoctoLib.1.10.34639" bezüglich des Projekts "DeviceWin" mit dem Ziel ".NETFramework,Version=v4.7.2" zu erfassen.
Das Erfassen von Abhängigkeitsinformationen hat 5,05 ms gedauert.
Es wird versucht, Abhängigkeiten für das Paket "Yoctopuce.YoctoLib.1.10.34639" mit dem DependencyBehavior "Lowest" aufzulösen.
Das Auflösen von Abhängigkeitsinformationen hat 0 ms gedauert.
Aktionen zum Installieren des Pakets "Yoctopuce.YoctoLib.1.10.34639" werden aufgelöst.
Aktionen zum Installieren des Pakets "Yoctopuce.YoctoLib.1.10.34639" wurden aufgelöst.
Das Paket "Yoctopuce.YoctoLib 1.10.34639" wird aus "nuget.org" abgerufen.
Das Paket "Yoctopuce.YoctoLib.1.10.34625" wurde aus "packages.config" entfernt.
"Yoctopuce.YoctoLib.1.10.34625" wurde erfolgreich von "DeviceWin" deinstalliert.
Das Paket "Yoctopuce.YoctoLib.1.10.34639" wird dem Ordner "C:\Users\Andi\Documents\Projekte\KKB\Iovent\Win\packages" hinzugefügt.
Das Paket "Yoctopuce.YoctoLib.1.10.34639" wurde dem Ordner "C:\Users\Andi\Documents\Projekte\KKB\Iovent\Win\packages" hinzugefügt.
Das Paket "Yoctopuce.YoctoLib.1.10.34639" wurde "packages.config" hinzugefügt.
"Yoctopuce.YoctoLib 1.10.34639" wurde erfolgreich auf "DeviceWin" installiert.
Das Paket "Yoctopuce.YoctoLib.1.10.34625" wird aus dem Ordner "C:\Users\Andi\Documents\Projekte\KKB\Iovent\Win\packages" entfernt.
Das Paket "Yoctopuce.YoctoLib.1.10.34625" wurde aus dem Ordner "C:\Users\Andi\Documents\Projekte\KKB\Iovent\Win\packages" entfernt.
Das Ausführen von NuGet-Aktionen hat 2,93 sec gedauert.
Verstrichene Zeit: 00:00:03.2449352

"erfolgreich" means "successful" - but there is nothing.
It does also not work on my .NET Framework 4.7.2 WinForms project. However, it works on a ASP.NET Core project.

Any idea?

2 - andiw Sunday,march 17,2019 8H45

It also works on a .NET Standard 2.0 class library!

3 - anthonyb Sunday,march 17,2019 20H24

This is great news. I'm looking forward to your blog post on using this with the Raspberry Pi :)

4 - seb (Yocto-Team)Monday,march 18,2019 17H03

@andiw : Oops! We have published the package too quickly and the version 1.10.34639 was missing a dll. We have released a new version v1.10.34678 that fix this issue.

Update your package and everything should work as expected. Let us now if you have any other issue.

Yoctopuce, get your stuff connected.