发布.NET Framework控制台应用时加载Speech核心DLL失败求助
问题场景
使用Visual Studio 2022、C#、.NET Framework 4.8.1开发控制台应用,通过NuGet安装Azure Cognitive Services Speech SDK v1.25。开发环境运行正常,但发布后在Windows 11/10 x64机器上启动时抛出以下错误:
Unhandled exception: System.DllNotFoundException: Unable to load DLL 'Microsoft.CognitiveServices.Speech.core.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
at Microsoft.CognitiveServices.Speech.Internal.SpeechConfig.speech_config_from_subscription(IntPtr& config, String subscriptionKey, String region)
at Microsoft.CognitiveServices.Speech.SpeechConfig.FromSubscription(String, subscriptionKey, String region)
at CommandApp.Program.Main()
已尝试但无效的操作:
- 卸载重装NuGet包并重新发布
- 手动复制
Microsoft.CognitiveServices.Speech.core.dll到应用目录 - 尝试通过引用管理器添加该DLL(提示加载失败)
- 确认发布包仅包含
Microsoft.CognitiveServices.Speech.csharp.dll,未包含原生core.dll - 修复已安装的Microsoft Visual C++ Redistributable (x64) v14.34.31938
- 将项目配置从AnyCPU切换为x64后重新发布
解决方案
1. 确保原生DLL被设置为内容文件并复制到输出
- 找到NuGet包目录下的原生DLL:
[项目根目录]/packages/Microsoft.CognitiveServices.Speech.1.25.0/runtimes/win-x64/native/Microsoft.CognitiveServices.Speech.core.dll - 将该文件添加到项目中(右键项目 → 添加 → 现有项)
- 选中该文件,在属性窗口设置:
- 复制到输出目录:始终复制
- 生成操作:内容
2. 手动修改.csproj文件强制包含原生DLL
打开项目的.csproj文件,添加以下配置段,确保发布时包含原生DLL:
<ItemGroup> <Content Include="packages\Microsoft.CognitiveServices.Speech.1.25.0\runtimes\win-x64\native\Microsoft.CognitiveServices.Speech.core.dll"> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory> </Content> </ItemGroup>
注意替换路径中的版本号为你实际使用的SDK版本。
3. 指定项目的运行时标识
在.csproj文件的<PropertyGroup>段中添加运行时标识,让NuGet自动匹配x64架构的原生依赖:
<PropertyGroup> <RuntimeIdentifier>win-x64</RuntimeIdentifier> </PropertyGroup>
添加后重新生成并发布项目。
4. 验证VC++运行时版本兼容性
Speech SDK v1.25可能依赖更新或特定版本的VC运行时,尝试安装**Microsoft Visual C Redistributable for Visual Studio 2015-2022 (x64)**的最新版本,覆盖现有安装后再次测试应用。
5. 改用SDK官方安装程序(备选方案)
下载对应v1.25版本的Azure Cognitive Services Speech SDK Windows安装程序,在目标机器上完成安装后,将项目引用指向安装目录中的DLL文件,替代NuGet包的引用。这种方式可确保所有原生依赖组件正确注册。
内容的提问来源于stack exchange,提问作者Tristan Bailey

