c# - 使用ASP.NET Core的跨平台USB通信

标签 c# asp.net-core usb libusb-1.0 libusbdotnet

概述

我已经将Web应用程序移植到.NET Core,并且发现它在Windows上运行时可以通过USB与微 Controller 进行通信,而在Linux上运行时则不能。我正在尝试解决:

  • 为什么会这样(这是我正在使用的库中的错误,还是我对Linux环境进行了错误配置?)
  • 我如何解决或解决它(替代库,对环境的更改等)

  • 如果有人成功地创建了一个基于.NET Core的应用程序,该应用程序可以通过与平台无关的方式通过USB进行通信,我将非常感谢您的输入。

    环境

    作为本文其余部分的引用,以下是有关我当前环境的一些详细信息:
  • Windows 7 64位主机
  • Dotnet版本1.0.0-preview2-003131
  • Docker版本1.12.0,内部版本8eab29e
  • Docker工具箱(我相信v1.12.3)
  • VirtualBox v5.0.30 r112061

  • 细节

    我以前有一个基于的.NET Framework基于的Web服务,该服务用于控制微 Controller 。由于基于.NET Framework,因此只能在Windows上运行。为了获得跨平台支持,我开始将应用程序移植到 .NET Core 。现在,该任务或多或少已经完成-例如,我现在可以将应用程序作为Docker服务构建和运行,我认为这将带来巨大的好处。

    我的应用程序分散在多个项目中,但是出于本文的目的,我将仅解决两个问题:
  • 基于ASP.NET Core的的Web服务项目,该项目将应用程序的核心功能调整为可通过Web通讯进行控制。 1 它将其他所有内容联系在一起,这是我实际上使用dotnet <<application.dll>>执行的操作。
  • 一个 USB通信服务项目,用于处理与我的USB设备的通信。 2 当前它使用CoreCompat.LibUsbDotNet库(v2.2.8-r101),该库分别作为Windows和Unix上WinUSBlibusb库的跨平台C#适配器。该项目以Web服务使用的Nuget包的形式分发,这就是问题所在。

  • 当我直接在Windows下运行该应用程序时,该应用程序运行良好。但是,如果我尝试在Linux虚拟机上或作为Docker服务运行它,则该Web服务将无法初始化,并显示错误消息,提示无法找到libusb-1.0 library 3

    基于此错误消息,我尝试检查尝试在其上运行应用程序的Linux VM和Docker容器的环境。 4

    将我的USB设备安装在Docker虚拟机上并在特权模式下基于我的Web应用程序镜像运行一个容器后,我可以确认它可以看到我的USB设备:

    root@19e8929e1814:/app# lsusb
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 002: ID 2b87:0001
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
    

    我还确认libusb-1.0已安装 5 ,并从ldconfig缓存中检查是否可用:

    root@19e8929e1814:/app# ldconfig -p | grep libusb
    libusb-1.0.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libusb-1.0.so.0
    libusb-1.0.so (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libusb-1.0.so
    libusb-0.1.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libusb-0.1.so.4
    libusb-0.1.so.4 (libc6,x86-64) => /usr/lib/x86_64-linux-gnu/libusb-0.1.so.4
    

    基于这一点,我不确定为什么CoreCompat.LibUsbDotNet引发关于无法找到libusb-1.0的异常,并且只能假定这是库中的错误。

    有没有人成功地设法使用该库在Unix环境下进行通信?或者,是否有人发现了针对基于.NET Core的应用程序以与平台无关的方式与USB设备通信的另一种方法?

    引用

    [1] Web服务项目的project.json
    {
      "dependencies": {
        "<<Company>>.Communications.<<Product>>Usb": "0.4.9",
        "<<Company>>.<<Product>>Web.Core": {
          "target": "project"
        },
        "<<Company>>.<<Product>>WebComponentPackage": "0.4.9-beta0002",
        "Autofac": "4.2.1",
        "Common.Logging": "3.4.0-Beta2",
        "Microsoft.AspNetCore.Diagnostics": "1.1.0-preview1-final",
        "Microsoft.AspNetCore.Server.IISIntegration": "1.1.0-preview1-final",
        "Microsoft.AspNetCore.Server.Kestrel": "1.1.0",
        "Microsoft.AspNetCore.StaticFiles": "1.1.0",
        "Microsoft.AspNetCore.WebSockets.Server": "0.1.0",
        "Microsoft.Extensions.DependencyModel": "1.1.0-preview1-001100",
        "Microsoft.Extensions.Logging.Console": "1.1.0",
        "Microsoft.NETCore.App": {
          "version": "1.1.0",
          "type": "platform"
        },
        "Serilog.Enrichers.Thread": "3.0.0",
        "Serilog.Sinks.Literate": "2.1.0-dev-00034",
        "Serilog.Sinks.RollingFile": "3.3.0",
        "System.Runtime.Loader": "4.3.0",
        "Thrower": "3.0.4"
      },
    
      "tools": {
      },
    
      "frameworks": {
        "netcoreapp1.1": {
          "imports": [
            "dotnet5.6",
            "portable-net45+win8"
          ]
        }
      },
    
      "buildOptions": {
        "emitEntryPoint": true,
        "preserveCompilationContext": true
      },
    
      "runtimeOptions": {
        "configProperties": {
          "System.GC.Server": true
        }
      },
    
      "publishOptions": {
        "include": [
          "wwwroot",
          "web.config"
        ]
      },
    
      "scripts": {
        "postpublish": [ "dotnet publish-iis --publish-folder %publish:OutputPath% --framework %publish:FullTargetFramework%" ]
      }
    }
    

    [2] USB通信项目的project.json
    {
      "version": "0.4.9-*",
      "description": "Provides a type of communication service that facilitates communication between .NET applications and <<Product>> over USB.",
      "authors": ["<<Author>>"],
    
      "dependencies": {
        "Microsoft.Composition": "1.0.30",
        "Microsoft.NETCore.Portable.Compatibility": "1.0.1",
        "Thrower": "3.0.4",
        "CoreCompat.LibUsbDotNet": "2.2.8-r101",
        "Common.Logging": "3.4.0-Beta2",
        "<<Company>>.Message": "0.4.3",
        "NETStandard.Library": "1.6.1",
        "<<Company>>.Communications.Core": "0.4.5",
        "Serilog": "2.3.0"
      },
      "packOptions": {
        "owners": ["<<Company>>"],
        "repository": {
          "type": "git",
          "url": "https://bitbucket.org/<<Company>>-dev/<<Product>>usb"
        }
      },
      "frameworks": {
        "netstandard1.4": {
          "imports": [ "dnxcore50", "portable-net45+win8" ]
        }
      },
      "buildOptions": {
        "xmlDoc": true
      }
    }
    

    [3] USB通信失败异常

    Unhandled Exception: System.DllNotFoundException: libusb-1.0 library not found.  This is often an indication that libusb-1.0 was installed to '/usr/local/lib' and
     mono.net is not looking for it there. To resolve this, add the path '/usr/local/lib' to '/etc/ld.so.conf' and run 'ldconfig' as root. (http://www.mono-project.co
    m/DllNotFoundException) ---> System.DllNotFoundException: Unable to load DLL 'libusb-1.0.dll': The specified module could not be found.
     (Exception from HRESULT: 0x8007007E)
       at MonoLibUsb.MonoUsbApi.Init(IntPtr& pContext)
       at MonoLibUsb.MonoUsbSessionHandle..ctor()
       --- End of inner exception stack trace ---
       at MonoLibUsb.MonoUsbSessionHandle..ctor()
       at MonoLibUsb.MonoUsbEventHandler.Init(UnixNativeTimeval unixNativeTimeval)
       at MonoLibUsb.MonoUsbEventHandler.Init()
       at MonoLibUsb.MonoUsbApi.InitAndStart()
       at LibUsbDotNet.LudnMonoLibUsb.MonoUsbDevice.get_MonoUsbDeviceList()
       at LibUsbDotNet.Main.LegacyUsbRegistry.get_DeviceList()
       at LibUsbDotNet.UsbDevice.get_AllLibUsbDevices()
       at LibUsbDotNet.UsbDevice.get_AllDevices()
       at LibUsbDotNet.UsbDevice.OpenUsbDevice(Predicate`1 findDevicePredicate)
       at LibUsbDotNet.UsbDevice.OpenUsbDevice(UsbDeviceFinder usbDeviceFinder)
       at <<Company>>.Communications.<<Product>>Usb.UsbCommunicationService.Start()
       at <<Company>>.<<Product>>Web.Core.DeviceController.Initialize()
       at <<Company>>.<<Product>>Web.ServiceAdapters.WebSockets.Startup.ConfigureServices(IServiceCollection services)
    --- End of stack trace from previous location where exception was thrown ---
       at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
       at Microsoft.AspNetCore.Hosting.ConventionBasedStartup.ConfigureServices(IServiceCollection services)
       at Microsoft.AspNetCore.Hosting.Internal.WebHost.EnsureApplicationServices()
       at Microsoft.AspNetCore.Hosting.Internal.WebHost.BuildApplication()
       at Microsoft.AspNetCore.Hosting.WebHostBuilder.Build()
       at <<Company>>.<<Product>>Web.ServiceAdapters.WebSockets.Program.Main(String[] args)
    

    [4] Web服务Dockerfile
    FROM microsoft/aspnetcore:1.1.0
    ENTRYPOINT ["dotnet", "bin/Debug/netcoreapp1.1/publish/<<Company>>.<<Product>>Web.ServiceAdapters.WebSockets.dll"]
    ARG source=.
    WORKDIR /app
    EXPOSE 80
    COPY $source .
    RUN apt-get update
    RUN apt-get install -y libusb-1.0-0-dev usbutils
    

    [5]在Docker容器上输出find / -name libusb*
    root@19e8929e1814:/app# find / -name libusb*
    /lib/x86_64-linux-gnu/libusb-1.0.so.0
    /lib/x86_64-linux-gnu/libusb-1.0.so.0.1.0
    /lib/x86_64-linux-gnu/libusb-0.1.so.4.4.4
    /lib/x86_64-linux-gnu/libusb-0.1.so.4
    /usr/lib/x86_64-linux-gnu/libusb-1.0.a
    /usr/lib/x86_64-linux-gnu/pkgconfig/libusb-1.0.pc
    /usr/lib/x86_64-linux-gnu/libusb-1.0.so
    /usr/lib/x86_64-linux-gnu/libusb-0.1.so.4
    /usr/include/libusb-1.0
    /usr/include/libusb-1.0/libusb.h
    /usr/share/doc/libusb-1.0-0
    /usr/share/doc/libusb-1.0-doc
    /usr/share/doc/libusb-1.0-doc/html/libusb_8h_source.html
    /usr/share/doc/libusb-1.0-0-dev
    /usr/share/doc/libusb-0.1-4
    /usr/share/doc-base/libusb-1.0-doc
    /var/lib/dpkg/info/libusb-1.0-0-dev:amd64.md5sums
    /var/lib/dpkg/info/libusb-1.0-doc.list
    /var/lib/dpkg/info/libusb-1.0-0:amd64.md5sums
    /var/lib/dpkg/info/libusb-1.0-0:amd64.symbols
    /var/lib/dpkg/info/libusb-1.0-0:amd64.shlibs
    /var/lib/dpkg/info/libusb-1.0-0:amd64.list
    /var/lib/dpkg/info/libusb-1.0-0:amd64.postrm
    /var/lib/dpkg/info/libusb-1.0-0:amd64.postinst
    /var/lib/dpkg/info/libusb-1.0-doc.md5sums
    /var/lib/dpkg/info/libusb-1.0-0-dev:amd64.list
    /var/lib/dpkg/info/libusb-0.1-4:amd64.postrm
    /var/lib/dpkg/info/libusb-0.1-4:amd64.shlibs
    /var/lib/dpkg/info/libusb-0.1-4:amd64.symbols
    /var/lib/dpkg/info/libusb-0.1-4:amd64.postinst
    /var/lib/dpkg/info/libusb-0.1-4:amd64.list
    /var/lib/dpkg/info/libusb-0.1-4:amd64.md5sums
    

    最佳答案

    将实际的共享库链接到您拥有的.Net Core版本的共享库位置。我设法使用以下方法加载了库:

    ln -s /lib/x86_64-linux-gnu/libusb-1.0.so.0 /opt/dotnet/shared/Microsoft.NETCore.App/1.1.0/libusb-1.0.dll
    

    我还没有设备 list 。

    参见this issue on Github

    关于c# - 使用ASP.NET Core的跨平台USB通信,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41610802/

    相关文章:

    linux - 建议 : USB Monitoring Programming

    c# - Linq:列表列表到长列表

    azure - 如何在ASP.NET Core中获取cpu/内存/网络使用百分比来进行节流?

    linux/libusb 获取usb设备路径

    c# - 如何将 IFormFile 放入 MVC6 中的 View 模型中

    asp.net-core - ASP.NET Core 2.0 MVC - 如何从 View 编译中排除某些文件夹?

    c++ - 使用 OpenCV 打开 USB 摄像头

    c# - 无法在 EF Where 表达式中使用 LINQ 用于 lambda 属性

    c# - 在不创建数据库的情况下将 Mini-Profilier 与 EF 4.3 和 MVC 4 结合使用

    c# - UWP ComboBox 不再具有打开/关闭动画(内部版本 14393)