ASP.NET Web应用程序 - 在部署上,System.Speech.dll对象不会被设置为对象的实例

我有一个ASP.NET Web应用程序使用System.Speech将文本转换为WAV文件。它在本地正常工作,但是当我将其部署到服务器时,出现以下错误消息。这是使用Windows Server 2012,ASP.NET 4.0和IIS 10.0

Object reference not set to an instance of an object.
System.Speech
   at System.Speech.Internal.ObjectTokens.RegistryDataKey..ctor(String fullPath, RegistryDataKey copyKey)
   at System.Speech.Internal.ObjectTokens.SAPICategories.DefaultDeviceOut()
   at System.Speech.Internal.Synthesis.VoiceSynthesis..ctor(WeakReference speechSynthesizer)
   at System.Speech.Synthesis.SpeechSynthesizer.get_VoiceSynthesizer()
   at QuinnSDS.handlerTransform.<>c__DisplayClass6.<ProcessRequest>b__1()

在服务器上运行生成此错误消息的代码:

using System;
using System.Web.Mvc;
using System.IO;
using System.Speech.Synthesis;
using System.Threading;
using System.Threading.Tasks;
using EXCHANGE.MAIL.SIGNATURE.Comm;
using System.Configuration;
using System.Speech.AudioFormat;
using TTSWebServerApi.Models;

namespace TTSWebServerApi
{

    public class TTSController : Controller
    {
        private static SpeechSynthesizer speechSyn = new SpeechSynthesizer();
        private static string TTSServerIp = ConfigurationManager.AppSettings["TTSServerIP"];
        private static int TTSServerPort = ConvertHelper.SafeGetIntFromString(ConfigurationManager.AppSettings["TTSServerPort"], 9980);

        private static int SpeechVolume = ConvertHelper.SafeGetIntFromString(ConfigurationManager.AppSettings["speechVolume"], 100);
        private static int SpeechRate = ConvertHelper.SafeGetIntFromString(ConfigurationManager.AppSettings["speechRate"], -3);

        [AcceptVerbs(new[] { "Get", "Post", "OPTIONS" })]
        [ActionName("getWavUrl")]
        public ActionResult GetWavUrl(string key)
        {
            var dr = new DataResult<string>();
            dr.Data = "";
            try
            {
                LogHelper.Debug(string.Format("进入程序{0}", key));
                dr.Data= SaveWave(key);
            }
            catch (Exception ex)
            {              
                dr.Message = ex.Message;
                dr.Data = null;
                dr.Result = false;
            }
            return new JsonNetResult() { Data = dr, Formatting = Newtonsoft.Json.Formatting.None };
        }

        private string SaveWave(string ttsText)
        {
            try
            {
                Task<String> task = Task.Factory.StartNew<string>(() => ListenterImpl(ttsText));
                //RunSomeOtherMethod();
                String taskResult = task.Result;
                return taskResult;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private  string ListenterImpl(string ttsText)
        {
            string path= "";
            try
            {
                LogHelper.Debug(string.Format("开始处理文本:{0}", ttsText));
                DownLoadFile info = new DownLoadFile();
                DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new DateTime(1970, 1, 1)); // 当地时区
                long timeStamp = (long)(DateTime.Now - startTime).TotalMilliseconds; // 相差毫秒数
                string fileName = timeStamp.ToString() + ".wav";
                string directoryPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "wav", DateTime.Now.ToString("yyyyMMdd"));
                LogHelper.Debug(string.Format("将要生成文件夹path:{0}", directoryPath));
                if (!Directory.Exists(directoryPath))
                {
                    // Create the directory it does not exist.
                    Directory.CreateDirectory(directoryPath);
                    LogHelper.Debug(string.Format("生成文件夹path:{0}", directoryPath));                
                }
                string path = Path.Combine(directoryPath, fileName);
                string httpStr = string.Format("http://{0}:{1}/wav/{2}", TTSServerIp, TTSServerPort, fileName);
                info.FilePath = path;
                info.FileName = fileName;
                info.HttpStr = httpStr;
                int samplesPerSecond = 8000;
                int bitsPerSample = 16;
                int channelCount = 1;
                int averageBytesPerSecond = 2;
                int blockAlign = 16000;
                byte[] formatSpecificData = null;
                LogHelper.Debug("开始文字转语音wav");

                speechSyn.Volume = SpeechVolume;
                speechSyn.Rate = SpeechRate;

                SpeechAudioFormatInfo formatInfo = new SpeechAudioFormatInfo(EncodingFormat.Pcm, samplesPerSecond, bitsPerSample, channelCount, averageBytesPerSecond, blockAlign, formatSpecificData);
                LogHelper.Debug(string.Format("formatInfo:Pcm,samplesPerSecond:{0}",formatInfo.SamplesPerSecond));
                speechSyn.SetOutputToWaveFile(info.FilePath, formatInfo);
                speechSyn.Speak(ttsText);
                speechSyn.SetOutputToDefaultAudioDevice();
                LogHelper.Debug("生成wav文件结束");
                Thread.Sleep(1000);
                using (FileStream fs = System.IO.File.OpenWrite(path))
                {
                    info.FileSize = fs.Length;
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error(ex.Message);
                LogHelper.Error(ex.ToString());
                throw new Exception("出错啦!", ex);
            }
            return path;
        }
    }
}

语音合成对象创建时不会中断;每当我尝试以任何方式使用该对象时,它都会中断。代码本地在服务器上,运行良好

google上搜到了与我产生一样的现象,给出了有用的信息:

什么用户帐户是从ASP.NET执行时运行的代码?如果Speech API像调用堆栈建议的那样触摸注册表,它可能与您手动运行代码的帐户拥有不同的权限。

如果您不能仅仅使用您登录到计算机的相同帐户运行您的站点的应用程序池,则使用Process Monitor追踪此类问题已经取得了一些成功。基本上,执行Process Monitor运行时失败的代码,并在“结果”列(或任何看起来可疑的东西)中查找“ACCESS DENIED”。快速切换应用程序池以使用您的标准用户帐户将是排除安全或权限相关问题的最快方法。

进程监视器告诉我,IIS用户没有创建注册表项的权限,我给了他适当的权限,现在没关系

我利用Process Monitor 进程监视工具查看我的问题所在,也是一样的问题 iis 没有创建注册表项的权限。

给它权限,问题解决。

Process Monitor 进程监视工具 非常好用 留下地址。

https://docs.microsoft.com/zh-cn/sysinternals/downloads/procmon

results matching ""

    No results matching ""