Discord.NET C# Bot连接语音频道后立即退出异常排查求助
问题描述
使用Discord.NET框架开发C# Discord Bot时触发异常:Bot加入存在其他用户的语音频道后会立即退出;当语音频道内无其他用户时,Bot可正常停留。已下载opus.dll放置在程序exe同级目录下,仍无法定位问题根因。
报错信息
20:54:58 App Command System.BadImageFormatException: An attempt was made to load a program with an invalid format. (0x8007000B) at Discord.Audio.OpusDecoder.CreateDecoder(Int32 Fs, Int32 channels, OpusError& error) at Discord.Audio.OpusDecoder..ctor() at Discord.Audio.Streams.OpusDecodeStream..ctor(AudioStream next) at Discord.Audio.AudioClient.CreateInputStreamAsync(UInt64 userId) at Discord.WebSocket.SocketGuild.RepopulateAudioStreamsAsync() at Discord.WebSocket.SocketGuild.FinishConnectAudio(String url, String token) at Discord.WebSocket.SocketGuild.ConnectAudioAsync(UInt64 channelId, Boolean selfDeaf, Boolean selfMute, Boolean external) at Discord.WebSocket.SocketGuild.ConnectAudioAsync(UInt64 channelId, Boolean selfDeaf, Boolean selfMute, Boolean external) at Discord.WebSocket.SocketVoiceChannel.ConnectAsync(Boolean selfDeaf, Boolean selfMute, Boolean external) at discord_bot.Modules.ExampleCommands.JoinChannel(IVoiceChannel channel) in C:\Users\hybas\source\repos\discord-bot\discord-bot\Modules\ExampleCommands.cs:line 58 at Discord.Interactions.Builders.ModuleClassBuilder.<>c__DisplayClass11_0.<<CreateCallback>g__ExecuteCallback|1>d.MoveNext()
语音连接代码
[Command("join", RunMode = RunMode.Async)] public async Task JoinChannel(IVoiceChannel channel = null) { // 获取语音频道对象 channel = channel ?? (Context.User as IGuildUser)?.VoiceChannel; if (channel == null) { await Context.Channel.SendMessageAsync("用户必须处于语音频道中,或传入语音频道参数。"); return; } // 连接语音频道,后续音频传输可复用该AudioClient实例 var audioClient = await channel.ConnectAsync(); }
根因分析与解决方法
System.BadImageFormatException (0x8007000B) 是典型的原生库架构不匹配错误,你放置的opus.dll和程序运行的目标架构不一致,导致加载失败。
空频道下Bot能正常停留,是因为频道内没有其他用户的音频流需要解码,Discord.NET不会初始化Opus解码器实例;一旦频道内存在其他用户,框架会自动创建Opus解码器处理音频流,触发dll加载逻辑,加载失败就会导致Bot直接断连退出。
按以下步骤排查修复:
- 修正项目平台目标配置:右键项目→属性→生成,将平台目标从「任意CPU」明确设置为
x64(绝大多数运行环境为64位,优先选这个),同时取消勾选「首选32位」选项,保存配置后重新编译项目。 - 替换匹配架构的原生dll:根据你设置的平台目标,下载对应架构版本的opus.dll、libsodium.dll(Discord.NET语音功能同时依赖这两个原生库,缺一不可),目标为x64就用64位版本dll,目标为x86就用32位版本,禁止混放不同架构的dll。
- 确认dll输出路径正确:不要只把dll放在源码目录的exe同级路径,调试/正式运行时dll需要放在编译输出目录(即
bin/Debug或bin/Release下对应框架版本的文件夹,和编译生成的bot exe文件同目录)。可以将两个dll添加到项目资源中,在文件属性页将「复制到输出目录」设置为「如果较新则复制」,避免路径错误导致加载失败。 - 清理旧编译文件后重新生成:删除bin、obj文件夹后重新编译项目,避免旧版本的错误dll缓存导致问题复现。
内容的提问来源于stack exchange,提问作者LZLZZ
相关产品推荐
相关产品推荐

