使用ASP.NET核心的跨平台USB通信
Cross-platform USB communication using ASP.NET Core
概述
我已经将 Web 应用程序移植到 .NET Core,我发现它能够在 运行 在 Windows 上连接时通过 USB 与微控制器通信,但在 运行宁 Linux。我正在努力锻炼:
为什么会这样(是我使用的库中的错误,还是我错误配置了 Linux 环境?)
我如何解决或解决它(替代库、环境变化等)
如果有人成功地创建了一个基于 .NET Core 的应用程序,该应用程序可以以与平台无关的方式通过 USB 进行通信,我将非常感谢您的意见。
环境
为了在本 post 的其余部分中参考,这些是关于我当前环境的一些详细信息:
- 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 服务,我用它来控制微控制器。基于 .NET Framework,它仅限于 运行ning on Windows。为了实现跨平台支持,我开始将应用程序移植到.NET Core。该任务现在或多或少已经完成 - 例如,我现在可以构建 运行 我的应用程序作为 Docker 服务,我认为这将大有裨益。
我的应用程序分为多个项目,但出于此目的 post 我只会解决两个问题:
ASP.NET 基于核心的 Web 服务 项目,它使应用程序的核心功能可以通过 Web 通信进行控制。 1 它将其他所有内容联系在一起,这就是我使用 dotnet <<application.dll>>
.
实际执行的内容
一个 USB 通信服务 项目,它处理与我的 USB 设备的通信。 2 它目前使用 CoreCompat.LibUsbDotNet 库 (v2.2.8-r101),它作为一个跨平台的 C# 适配器WinUSB
和 libusb
库分别在 Windows 和 Unix 上。该项目作为 Web 服务使用的 Nuget 包分发,这就是问题所在。
当我 运行 直接在 Windows 下时,应用程序 运行 没问题。但是,如果我尝试在 Linux 虚拟机上或作为 Docker 服务 运行 它,Web 服务将无法初始化并出现错误,抱怨 libusb-1.0 library
可能不在。 3
根据此错误消息,我尝试检查 Linux VM 和 Docker 容器的环境,我曾尝试 运行 将应用程序连接到这些容器上。 4
在 Docker 虚拟机上安装我的 USB 设备并在特权模式下 运行基于我的 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 服务 Docker文件
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] find / -name libusb*
在 Docker 容器上的输出
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
Link 实际共享库到您拥有的 .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
虽然我还没有得到设备列表。
概述
我已经将 Web 应用程序移植到 .NET Core,我发现它能够在 运行 在 Windows 上连接时通过 USB 与微控制器通信,但在 运行宁 Linux。我正在努力锻炼:
为什么会这样(是我使用的库中的错误,还是我错误配置了 Linux 环境?)
我如何解决或解决它(替代库、环境变化等)
如果有人成功地创建了一个基于 .NET Core 的应用程序,该应用程序可以以与平台无关的方式通过 USB 进行通信,我将非常感谢您的意见。
环境
为了在本 post 的其余部分中参考,这些是关于我当前环境的一些详细信息:
- 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 服务,我用它来控制微控制器。基于 .NET Framework,它仅限于 运行ning on Windows。为了实现跨平台支持,我开始将应用程序移植到.NET Core。该任务现在或多或少已经完成 - 例如,我现在可以构建 运行 我的应用程序作为 Docker 服务,我认为这将大有裨益。
我的应用程序分为多个项目,但出于此目的 post 我只会解决两个问题:
ASP.NET 基于核心的 Web 服务 项目,它使应用程序的核心功能可以通过 Web 通信进行控制。 1 它将其他所有内容联系在一起,这就是我使用
dotnet <<application.dll>>
. 实际执行的内容
一个 USB 通信服务 项目,它处理与我的 USB 设备的通信。 2 它目前使用 CoreCompat.LibUsbDotNet 库 (v2.2.8-r101),它作为一个跨平台的 C# 适配器
WinUSB
和libusb
库分别在 Windows 和 Unix 上。该项目作为 Web 服务使用的 Nuget 包分发,这就是问题所在。
当我 运行 直接在 Windows 下时,应用程序 运行 没问题。但是,如果我尝试在 Linux 虚拟机上或作为 Docker 服务 运行 它,Web 服务将无法初始化并出现错误,抱怨 libusb-1.0 library
可能不在。 3
根据此错误消息,我尝试检查 Linux VM 和 Docker 容器的环境,我曾尝试 运行 将应用程序连接到这些容器上。 4
在 Docker 虚拟机上安装我的 USB 设备并在特权模式下 运行基于我的 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 服务 Docker文件
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] find / -name libusb*
在 Docker 容器上的输出
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
Link 实际共享库到您拥有的 .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
虽然我还没有得到设备列表。