.NET MAUI中使用DryWetMIDI连接MIDI输出设备失败问题
解决.NET 7 MAUI中DryWetMIDI输出设备报错及EventSent不触发问题
一、排查MAUI Windows平台权限配置
MAUI打包为MSIX应用时默认处于沙箱环境,需显式声明MIDI设备访问权限:
- 打开项目中的
Package.appxmanifest文件 - 在
<Capabilities>节点内添加MIDI设备能力声明:
<Capabilities> <!-- 保留原有权限声明 --> <DeviceCapability Name="midi"/> </Capabilities>
二、修正DryWetMIDI设备初始化逻辑
1. 显式打开输出设备
控制台应用可能自动完成设备打开操作,但MAUI需要手动调用Open()确保设备句柄有效:
void ConnectMidi() { // 创建输入设备 inputDevice = InputDevice.GetByName("Keystation Mini 32"); inputDevice.EventReceived += OnEventReceived; // 创建并显式打开输出设备 outputDevice = OutputDevice.GetByName("Microsoft GS Wavetable Synth"); outputDevice.Open(); outputDevice.EventSent += OnEventSent; // 连接设备 devicesConnector = inputDevice.Connect(outputDevice); inputDevice.StartEventsListening(); }
2. 在UI线程执行设备初始化
MAUI的UI线程模型可能导致后台线程创建的设备句柄失效,通过Dispatcher确保初始化操作在主线程执行:
async void ConnectMidi() { await Dispatcher.DispatchAsync(() => { inputDevice = InputDevice.GetByName("Keystation Mini 32"); inputDevice.EventReceived += OnEventReceived; outputDevice = OutputDevice.GetByName("Microsoft GS Wavetable Synth"); outputDevice.Open(); outputDevice.EventSent += OnEventSent; devicesConnector = inputDevice.Connect(outputDevice); inputDevice.StartEventsListening(); }); }
三、替代方案:使用NAudio库
若DryWetMIDI在MAUI中仍存在兼容性问题,可尝试NAudio(Windows平台对MIDI支持更稳定):
- 安装NuGet包:
Install-Package NAudio - 示例实现代码:
private MidiIn midiIn; private MidiOut midiOut; void ConnectMidi() { // 查找目标输入设备索引 int inputIndex = -1; for (int i = 0; i < MidiIn.NumberOfDevices; i++) { if (MidiIn.DeviceInfo(i).ProductName.Equals("Keystation Mini 32", StringComparison.OrdinalIgnoreCase)) { inputIndex = i; break; } } // 查找目标输出设备索引 int outputIndex = -1; for (int i = 0; i < MidiOut.NumberOfDevices; i++) { if (MidiOut.DeviceInfo(i).ProductName.Equals("Microsoft GS Wavetable Synth", StringComparison.OrdinalIgnoreCase)) { outputIndex = i; break; } } // 初始化输入设备 if (inputIndex != -1) { midiIn = new MidiIn(inputIndex); midiIn.MessageReceived += OnMidiMessageReceived; midiIn.Start(); } // 初始化输出设备 if (outputIndex != -1) { midiOut = new MidiOut(outputIndex); } } private void OnMidiMessageReceived(object sender, MidiInMessageEventArgs e) { Debug.WriteLine("MIDI消息已接收"); // 将收到的消息转发到输出设备 midiOut?.Send(e.RawMessage); }
- 同样需要在
Package.appxmanifest中添加<DeviceCapability Name="midi"/>权限声明。
内容的提问来源于stack exchange,提问作者Age Brouwer
相关产品推荐
相关产品推荐

