C# Web应用调用EXE文件的一些实践

简介:

需求

最近同事使用Python开发了一款智能文字转语音的程序,经讨论部署在WINDOWS环境服务器下,因此需要生成目标为可执行程序文件,即EXE文件。需要在WEB应用程序里进行调用,并传递相关参数。

该测试效果如下图: 打开AI语音合成配置如下:

如图配置中,可以选择朗读人角色,音量大小,音调高低和控制语速选项, 此款应用将在合成音视频中起到关键作用。


范例运行环境

操作系统: Windows Server 2019 DataCenter


.net版本: .netFramework4.7.1 或以上


开发工具:VS2019  C#


可执行文件的设计

可执行文件 edgetts.exe 实现文字转语音功能,其说明如下:


序号 参数 类型 说明

1

-filename 字符 存在的文件名

word docx文档

txt文本文件

md markdown文档

2

-s

角色

固定值 主播的角色值

3

-p 字符 固定值 音调高低

4

-r 1位小数数值 0.1开始的倍速 默认为1.0

5

-v

整数



音量大小

调用方法:


edgetts.exe 要转换的文件名   [-s 声音参数 -p 音调参数 -r速度参数 -v 音量参数]

调用举例:


edgetts d:\tts\test.txt


edgetts d:\tts\test.txt  -s yunyang  -p default -r 1.0  -v 100


调用说明:


1、除要转换的文件名为必要参数外,其他参数均有默认值

2、转换程序不要放在根目录下

3、转换程序在转换文本相同路径下生成同名的mp3文件

4、转换程序需要连接外网


调用可执行文件方法

需要引用 using System.Diagnostics;


程序集 System.Diagnostics.Process.dll 提供对本地和远程进程的访问权限并能够启动和停止本地系统进程。


包括两种方法,方法包括需要调用的可执行文件名和可提供的参数:


RunExecuteFile

 public string RunExecuteFile(string filename,string arguments)
        {
            Process prc = new Process();
            try
            {
                prc.StartInfo.FileName = filename;
                prc.StartInfo.Arguments = arguments;
                prc.StartInfo.UseShellExecute = false;
                //输入输出重定向
                prc.StartInfo.RedirectStandardError = true;
                prc.StartInfo.RedirectStandardInput = true;
                prc.StartInfo.RedirectStandardOutput = true;
                prc.StartInfo.CreateNoWindow = false;
                prc.Start();
                //获得输出
                string output = prc.StandardOutput.ReadLine();
                return output;
            }
            catch (Exception ex)
            {
                if (!prc.HasExited)
                {
                    prc.Close();
                }
                return ex.Message.ToString();
            }
            return "";
 
        }

RunShellExecuteFile

public string RunShellExecuteFile(string filename, string arguments)
{
            System.Diagnostics.Process prc = new System.Diagnostics.Process();
            prc.StartInfo.FileName = filename;
            prc.StartInfo.Arguments = arguments;
            prc.StartInfo.UseShellExecute = true;
            prc.StartInfo.CreateNoWindow = true;
            prc.Start();
            prc.WaitForExit();
            return "";
}

方法的区别

主要区别在于 UseShellExecute 的属性的 true 或 false 。该属性获取或设置指示是否使用操作系统 shell 启动进程的值。


如果应在启动进程时使用 shell,则为 true ;如果直接从可执行文件创建进程,则为  false 。 .NET Framework 应用默认值为 true 。为 true 的时候表示可以尝试调用一切可以调用的程序,但不限于EXE文件。


WEB调用举例

根据前面AI语音合成图示,可编写如下后端调用示例代码:


protected void Button1_Click(object sender, EventArgs e)
    {
        string tts = "D:\\tts\\edgetts.exe";
        string tts_para = " -s " + x_speaker.SelectedValue;
        if (x_volume.Text != "")
        {
            tts_para += " -v " + x_volume.Text;
        }
        if (x_rate.Text != "")
        {
            tts_para += " -r " + x_rate.Text;
        }
        if (x_pitch.SelectedValue != "default")
        {
            tts_para += " -p " + x_pitch.SelectedValue;
        }
        string cdir = Request.PhysicalApplicationPath + "\\test\\ai\\";
        string[] allfs = Directory.GetFiles(cdir);
        for (int i = 0; i < allfs.Length; i++)
        {
            string mp3 = allfs[i].ToLower();
            File.Delete(mp3);
        }
        string guid = System.Guid.NewGuid().ToString().Replace("-", "");
        string txtfile = Request.PhysicalApplicationPath + "\\test\\ai\\"+guid+".txt";
        SaveToFile(txtfile,debug.Text, false, Encoding.UTF8, 512);
        string mp3file = Request.PhysicalApplicationPath + "\\test\\ai\\"+guid+".mp3";
        string rv=RunShellExecuteFile(tts, " "+txtfile + tts_para);
        if (File.Exists(mp3file))
        {
            testaudio.Style["display"] = "";
            testaudio.Attributes["src"] = "https://" + Request.Url.Host + "/bfile/ai/" + guid + ".mp3";
            string imgurl = "https://" + Request.Url.Host + "/test/ai/images/boy.jpg";
            if (x_speaker.SelectedValue == "xiaoxiao" || x_speaker.SelectedValue == "xiaoyi" || x_speaker.SelectedValue == "yunxia")
            {
                imgurl = "https://" + Request.Url.Host + "/test/ai/images/girl.jpg";
            }
            layer.options_yes = "document.getElementById('testaudio').play();layer.closeAll();";
            layer.open("<img src=\""+imgurl+"\" width=200/>语音合成成功!", "'点这里播放'", "ok");
        }
        else
        {
            debug.Text = rv;
            layer.open("未找到文件!" + tts+ txtfile + tts_para, "'确定'", "ok");
        }
 
    }
 
public string SaveToFile(string PathFile,string filecontent,bool append,System.Text.Encoding encodtype,int buffersize)
    {
      string rv="";
      StreamWriter df=new StreamWriter (PathFile,append,encodtype,buffersize);
      try
      {
        df.Write(filecontent);
        df.Close();
      }
      catch(Exception e)
      {
        rv=e.Message;
        df.Close();
      }
      finally
      {
        df.Close();
      }
      return rv;
 
    }//SaveToFile Function

前端代码示例如下:

    <div id="h5panel" runat="server" style="margin-top:-50px" class="login-box query-panel">
<div style="text-align:left"><asp:HyperLink ID="backurl" Text="返回" onclick="layer.open({ type: 2, shadeClose: false, content: '正在返回页面,请稍候...' });"  NavigateUrl="/cc/prods/media/msIndex.aspx"  runat="server"/> </div>
        <h2>
            <asp:Label ID="fnamelabel" runat="server" Text="文字转语音AI合成测试"></asp:Label></h2>
        <div class="user-box" style=" color:White; text-align:center; margin-bottom:50px">
<br><br>
       <div class="user-box" style=" display:none1; padding-top:10px;">
           <div style="display:flex">
            <asp:TextBox  TextMode="MultiLine" Rows="6" ID="debug" Height="100px" Text="Hello!欢迎来到立德云!" style="color:White; width:100%; background: #fff;display:none1; background-color:Black;filter:opacity(50%);"  runat="server"></asp:TextBox>          
            </div>
      </div>
      <audio id="testaudio" runat="server" autoplay="autoplay"  style="display:none" controls>  </audio>
              <div class="user-box" style="margin-bottom:0px;display:flex;width:100%;justify-content:flex-end;">
        <input type="button" value="打开AI语音合成配置" style=" border-radius:5px" onclick="document.getElementById('ai_profile').style.display=''" />
        </div>
           <div id="ai_profile" class="user-box" style="display:none; margin-top:0px;">
        <div class="form-horizontal" style=" margin-left:20px; border-style:solid; border-width:1px; border-radius:5px; padding-left :50px;">
                        <div class="form-group" style=" margin-top:30px;">
                            <label class="col-sm-1  control-label" style="font-size:12pt; text-align:center;">
                            朗读人角色
                            </label>
                            <div class="col-sm-2">
                                <asp:DropDownList ID="x_speaker"  checkSchema="notnull" noClear CssClass="form-control" cName="音调"  AUTOCOMPLETE="off" required="" runat="server">
                                <asp:ListItem Value="xiaoxiao">晓晓</asp:ListItem>
                                <asp:ListItem Value="xiaoyi">晓依</asp:ListItem>
                                <asp:ListItem Value="yunjian">云健</asp:ListItem>
                                <asp:ListItem Value="yunxi">云溪</asp:ListItem>
                                <asp:ListItem Value="yunxia">云霞</asp:ListItem>
                                <asp:ListItem Selected="True" Value="yunyang">云扬</asp:ListItem>
                                </asp:DropDownList>
                            </div>
                            <label class="col-sm-1  control-label" style=" font-size:12pt; text-align:center;">
                            音量
                            </label>
                            <div class="col-sm-1">
                                <asp:TextBox ID="x_volume"  checkSchema="notnull" Text="100" noClear CssClass="form-control" cName="音量"  AUTOCOMPLETE="off" required="" runat="server">
                                </asp:TextBox>
                            </div>
 
                          </div>
                        <div class="form-group">
                            <label class="col-sm-1  control-label" style=" font-size:12pt; text-align:center;">
                            音调
                            </label>
                            <div class="col-sm-2">
                                <asp:DropDownList ID="x_pitch"  checkSchema="notnull" noClear CssClass="form-control" cName="音调"  AUTOCOMPLETE="off" required="" runat="server">
                                <asp:ListItem>default</asp:ListItem>
                                <asp:ListItem>x-low</asp:ListItem>
                                <asp:ListItem>low</asp:ListItem>
                                <asp:ListItem>medium</asp:ListItem>
                                <asp:ListItem>high</asp:ListItem>
                                <asp:ListItem>x-high</asp:ListItem>
                                </asp:DropDownList>
                            </div>
                            <label class="col-sm-1  control-label" style=" font-size:12pt; text-align:center;">
                            语速
                            </label>
                            <div class="col-sm-1">
                                <asp:TextBox ID="x_rate"  checkSchema="notnull" Text="1.0" noClear CssClass="form-control" cName="语速"  AUTOCOMPLETE="off" required="" runat="server">
                                </asp:TextBox>
                            </div>
                       </div>
        </div>
     </div>
 
       <div class="user-box" style="text-align:center; display:none1; padding-top:10px;">
        <div align="center">
        <asp:Button ID="Button1" Text="AI语音合成" OnClientClick="layer.open({ type: 2, shadeClose: false, content: '正在进行AI语音合成...' });" 
                style="width:30%; background-color:#1E90FF;color:White;border-color:#87CEFA;padding-left:10px; padding-right:10px" 
                CssClass="form-control" runat="server" onclick="Button1_Click"  />
        </div>
       </div>
 
        <div class="user-box" style="text-align:center; display:none">
                <video id="coplayer" autoplay="autoplay" controls="controls" webkit-playsinline playsinline x5-playsinline x-webkit-airplay="allow" style="margin: 0px auto; width:100%" runat="server" ></video>
                <a id="b_rate" onclick="rate(this);" style=" float:right; line-height:25px; margin-right:10px; color:#fff;display:none;">1x</a> 
        </div>
        <div class="ann" >
            <label><asp:Literal ID="x_introduce" runat="server"/></label>
        </div>
        
    </div>
<script src="https://res2.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
 <script type="text/javascript" src="hls.min.0.12.4.js"> </script>
 <script type="text/javascript" src="tcplayer.v4.min.js"> </script>
<script type="text/javascript" language="javascript" src="/master/js/jquery.js" ></script><!-- BASIC JS LIABRARY -->
 
 
 
</div>

小结

在实际的应用中,调用 RunShellExecuteFile 方法更加通用一些,本示例调用 RunExecuteFile没有成功,因协作需要,我们需要尝试多种方法进行解决,而不是要在第一时间要求其它团队更改设计。



相关文章
|
5天前
|
设计模式 安全 网络安全
安全风险在WEB应用中的排名变化
【7月更文挑战第16天】本文介绍OWASP的安全风险评估,一个国际非营利组织,专注于提升Web应用安全。其Top 10项目列出最严重的安全风险,如Broken Access Control(现最严重风险),加密故障,注射漏洞,不安全设计,配置错误等。2021版新增了不安全设计、软件完整性故障和服务器端请求伪造等类别。安全问题排名考虑了发生率,以反映攻击者只需一个实例即可造成损害的风险。**
29 2
安全风险在WEB应用中的排名变化
|
6天前
|
数据库 开发者 Python
实战指南:用Python协程与异步函数优化高性能Web应用
【7月更文挑战第15天】Python的协程与异步函数优化Web性能,通过非阻塞I/O提升并发处理能力。使用aiohttp库构建异步服务器,示例代码展示如何处理GET请求。异步处理减少资源消耗,提高响应速度和吞吐量,适用于高并发场景。掌握这项技术对提升Web应用性能至关重要。
28 10
|
4天前
|
JavaScript 前端开发 网络协议
从理论到实践:全面剖析Python Web应用中的WebSocket实时通信机制
【7月更文挑战第17天】WebSocket在实时Web应用中扮演重要角色,提供全双工通信,减少延迟。本文详述了Python中使用`websockets`库创建服务器的步骤,展示了一个简单的echo服务器示例,监听8765端口,接收并回显客户端消息。客户端通过JavaScript与服务器交互,实现双向通信。了解WebSocket的握手、传输和关闭阶段,有助于开发者有效利用WebSocket提升应用性能。随着实时需求增长,掌握WebSocket技术至关重要。
15 6
|
2天前
|
存储 数据库 开发者
Flask中的蓝图与插件应用:构建模块化Web应用的利器
【7月更文挑战第19天】Flask蓝图和插件是构建模块化、可扩展和可维护Web应用的强大工具。蓝图允许你将应用分割成多个独立的部分,提高了代码的组织性和可重用性;而插件则为Flask应用提供了丰富的功能和社区支持,简化了开发过程。通过合理地使用蓝图和插件,你可以更加高效地开发出高质量的Web应用。
|
2天前
|
前端开发 数据库 开发者
构建可维护的Web应用:Python模板引擎与ORM的协同工作
【7月更文挑战第19天】在Web开发中,可维护性至关重要。Python搭配Flask或Django框架,利用模板引擎(如Jinja2)和ORM(如SQLAlchemy或Django ORM)增强开发效率和代码质量。模板引擎桥接前后端,ORM简化数据库操作,两者协同提升可读性和可测试性。例如,Flask用Jinja2渲染动态HTML,Django通过ORM处理数据库模型。这种分离关注点的方法降低了耦合,增强了应用的可维护性。
10 1
|
2天前
|
JSON 中间件 数据处理
实践出真知:通过项目学习Python Web框架的路由与中间件设计
【7月更文挑战第19天】探索Python Web开发,掌握Flask或Django的关键在于理解路由和中间件。路由连接URL与功能,如Flask中@app.route()定义请求响应路径。中间件在请求处理前后执行,提供扩展功能,如日志、认证。通过实践项目,不仅学习理论,还能提升构建高效Web应用的能力。示例代码展示路由定义及模拟中间件行为,强调动手实践的重要性。
|
5天前
|
前端开发 JavaScript UED
Python Web应用中的WebSocket实战:前后端分离时代的实时数据交换
【7月更文挑战第16天】在前后端分离的Web开发中,WebSocket解决了实时数据交换的问题。使用Python的Flask和Flask-SocketIO库,后端创建WebSocket服务,监听并广播消息。前端HTML通过JavaScript连接到服务器,发送并显示接收到的消息。WebSocket适用于实时通知、在线游戏等场景,提升应用的实时性和用户体验。通过实战案例,展示了如何实现这一功能。
|
5天前
|
JavaScript 前端开发 UED
WebSocket在Python Web开发中的革新应用:解锁实时通信的新可能
【7月更文挑战第16天】WebSocket是实现Web实时通信的协议,与HTTP不同,它提供持久双向连接,允许服务器主动推送数据。Python有多种库如websockets和Flask-SocketIO支持WebSocket开发。使用Flask-SocketIO的简单示例包括定义路由、监听消息事件,并在HTML中用JavaScript建立连接。WebSocket提高了实时性、减少了服务器压力,广泛应用于聊天、游戏等场景。
12 1
|
8天前
|
XML 前端开发 API
惊艳全场的秘诀!AJAX、Fetch API与Python后端,打造令人惊叹的Web应用!
【7月更文挑战第13天】构建现代Web应用的关键在于提供无缝用户体验,这涉及AJAX和Fetch API的异步数据交换以及Python(如Flask)的后端支持。Fetch API以其基于Promise的简洁接口,改进了AJAX的复杂性。例如,一个Flask应用可提供用户数据,前端利用Fetch API在不刷新页面的情况下显示信息。这种结合提升了效率,减少了服务器负载,是现代Web开发的趋势。随着技术发展,预期将有更多工具优化这一过程。
27 3
|
2天前
|
中间件 API 开发者
深入理解Python Web框架:中间件的工作原理与应用策略
【7月更文挑战第19天】Python Web中间件摘要:**中间件是扩展框架功能的关键组件,它拦截并处理请求与响应。在Flask中,通过`before_request`和`after_request`装饰器模拟中间件行为;Django则有官方中间件系统,需实现如`process_request`和`process_response`等方法。中间件用于日志、验证等场景,但应考虑性能、执行顺序、错误处理和代码可维护性。
7 0