手把手教会如何将ZLMediaKit构建为windows程序,为你节省大量的服务器资源。

38 阅读8分钟

本文目标为ZLMediaKit构建为windows程序,可安装到客户机节省服务器资源,客户端仅需要调用api即可使用ZLMediaKit丰富的功能;

WinSW把Windows程序变成服务并且开机自启动。

前提

设想一下大家都会遇到的电脑开机有很多软件自启动比如 微信、QQ、百度网盘等等这些图形化界面的自启动,这里我们稍微设置一下它就不会自动启动了,如果对于开发人员来说,每一次开机都要挂 nginx、Redis或者是tomcat等等这些都是以命令提示框运行的,而且如果设成开机自启动是不是都要建立快捷指令到以下这个目录

C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

是不是很不舒服,如果把它们变成Windows服务开机自启动是不是一下子全部解决!接下来我们来讲WinSW程序的下载及使用!

首先WinSW是开源的免费使用,我们只需要编辑一个xml文件就可以使用了,教程开始

下载链接:

GitHub下载链接:

github.com/winsw/winsw…

本图片来源于微信公众号“辉少软件阁”

蓝奏云下载链接:wwi.lanzouw.com/b00p8rcpi

密码:hcze

百度网盘下载链接:pan.baidu.com/s/1gbBwE0MR…

提取码:hui9

使用教程

第一步:我们需要编写xml文件,下载文件夹里面会放的有,如下图所示

本图片来源于微信公众号“辉少软件阁”

第二步:编辑xml文件,打开sample-allOptions.xml文档里面的绿色字体都可以删掉,最后显示如下图,请根据一下解释进行配置

本图片来源于微信公众号“辉少软件阁”

本图片来源于微信公众号“辉少软件阁”

第三步:把编辑好的配置文件和WinSW程序放在执行文件同一个目录下,并将xml文件改成和主程序文件同名如下如所示

本图片来源于微信公众号“辉少软件阁”

第四步:打开cmd,进入WinSW主程序所在的目录中输入命令:

本图片来源于微信公众号“辉少软件阁”

第五步:Win+R 输入:services.msc 打开服务之后就可以看到你添加的文件服务了,这里我添加的是Tomcat启动bat程序,我完全没有运行startup.bat 我就可以在浏览器地址栏输入:localhost:8080 即可访问Tomcat主页 如下图所示

注:如果添加完服务没有反应或者是没有你想要的效果,请把服务删除,编辑配置文件:

本图片来源于微信公众号“辉少软件阁”

<service>  
--设置服务id
<id>myapp</id>  
--设置服务名称 一般和id一样
<name>MyApp Service (powered by WinSW)</name>  
--类似于服务说明、备注>
<description>This service is a service created from a sample configuration</description> 
--这里输入软件的路径
<executable>%BASE%\myExecutable.exe</executable>  
--设置优先事项
<priority></priority>  
--stoptimeout:停止超时时间,默认“15 sec”  
<stoptimeout>15 sec</stoptimeout>  
--是否在停止子进程之前终止父进程,默认true  
<stopparentprocessfirst>true</stopparentprocessfirst>  
--Boot:设备驱动程序由操作系统加载程序启动。此值仅对驱动程序服务有效。
--System:设备驱动程序由操作系统初始化过程启动。此值仅对驱动程序服务有效。
--Automatic:自动,服务控制管理器将在系统启动期间自动启动服务。
--Manual:手动,当进程调用StartService方法时,由服务控制管理器启动的服务。
--Disabled:禁用,无法再启动的服务。
--默认值为Automatic  
<startmode>Automatic</startmode>  
--指定多长时间内服务应该对SetServiceStatus函数进行下一次调用,否则会被标记为无响应,默认“15 sec”  
<waithint>15 sec</waithint>  
--服务两次调用SetServiceStatus函数的间隔时间,默认“1 sec”  
<sleeptime>1 sec</sleeptime>  
<log mode=""></log>
</service>
WinSW.NET2.exe inatall
--显示如下图则代表成功
--删除服务↓
WinSW.NET2.exe uninstall
--这里输入详细的执行文件地址,比如↓  
  <executable>E:\Service\apache-tomcat-8.5.72\bin\startup.bat</executable>  
  --把这个删除↓  
  <priority></priority>
  --查看服务状态一定要显示正在运行,如果没有请启动它

NSIS打包程序安装包

采用NSIS + HM NIS Edit + ,制作安装程序实际上就是使用HM NIS Edit制作安装程序,而NSIS仅仅将制作的安装程序打包成一个exe。

下载

NSIS 下载地址:nsis.sourceforge.io/Download

HM NIS Edit 下载地址:hmne.sourceforge.net/

NSIS_Simple_Service_Plugin下载地址:nsis.sourceforge.io/NSIS_Simple…

安装NSIS

切记:NSIS要配置环境变量

安装HM NSIS Edit

打开链接hmne.sourceforge.net,下载页面:

安装过程:

安装NSIS Simple Service Plugin

下载地址:nsis.sourceforge.io/NSIS_Simple…

上面图中的两个版本挑选一种下载即可,两个都下载也不会有问题。下载完成后,将压缩包中的SimpleSC.dll解压到NSIS安装目录的Plugins文件夹 中,如果你下载的是NSIS_Simple_Service_Plugin的ANSI版本,那就放在NSIS/Plugins/x86-ansi文件夹下;如果你下载的是NSIS_Simple_Service_Plugin的Unicode版本,那就放在NSIS\Plugins\x86-unicode文件夹中。

NSIS_Simple_Service_Plugin的ANSI版本

NSIS_Simple_Service_Plugin的Unicode版本

打包WIndowsService程序

打开HM NIS Edit程序,选择文件==>新建脚本:向导, 依次如下图操作:

下图中的授权文件,如果没有,则清空文本框即可

下图中的两个示例文件,删除即可

下图中圈出来的按钮,左边的按钮是直接选择文件,右边的按钮时根据目录选择文件

我选择的是根据目录选择文件

选择你的windows服务的程序编译目录,Debug文件夹或者Release文件夹

下图中的文本框1是选择可执行文件(因为我打包的程序是Windows服务 所以不需要程序安装后运行,则将此文本框的内容删除即可),剩下两个文件框不懂啥意思,

MS1.0在打包过程中以winsw为主程序自动安装到windows服务中,需要增加增加启动参数输入: install

选择你自己的脚本存放目录以及文件名

到目前为止,程序可以已经打包完成了。

到目前为止,程序可以打包了。但是我们还需要将此服务注册电脑系统的服务中,所以还需要以下步骤:

1.添加注册服务的脚本到安装节点:

以下圈出来的代码,意思是先检测服务是不是已经存在,是不是正在运行中,目的是为了将现有的服务删除,再重新注册

附检测服务的命令:

SimpleSC::ExistsService "JiXiaoNotifyPush"

Pop $0 ; 0:服务已经存在;不是0,服务不存在

;如果服务已经存在

If{If} 0 == 0

Push $0

; Check if the service is running

SimpleSC::ServiceIsRunning "JiXiaoNotifyPush"

Pop $0 ; returns an errorcode (<>0) otherwise success (0)

Pop $1 ; returns 1 (service is running) - returns 0 (service is not running)

;如果检测服务是否正在运行成功

If{If} 0 == 0

Push $0

;如果服务正在运行中

If{If} 1 == 1

;关闭服务

SimpleSC::StopService "JiXiaoNotifyPush" 1 30

Pop $0 ; returns an errorcode (<>0) otherwise success (0)

;如果服务关闭成功

If{If} 0 == 0

;删除服务

DetailPrint "Removing JiXiaoNotifyPush Client service..."

SimpleSC::RemoveService "JiXiaoNotifyPush"

;如果服务关闭不成功

ElseIf{ElseIf} 0 != 0

Push $0

;获取服务关闭不成功的系统错误信息

SimpleSC::GetErrorMessage

Pop $0

;将信息弹窗展示给用户

MessageBox MB_OK|MB_ICONSTOP "JiXiaoNotifyPush服务关闭失败($0)"

${EndIf}

;如果服务没有正在运行中

ElseIf{ElseIf} 1 == 0

;删除服务

DetailPrint "Removing JiXiaoNotifyPush Client service..."

SimpleSC::RemoveService "JiXiaoNotifyPush"

${EndIf}

;如果检测服务是否正在运行不成功

ElseIf{ElseIf} 0 != 0

Push $0

SimpleSC::GetErrorMessage

Pop $0

MessageBox MB_OK|MB_ICONSTOP "检测JiXiaoNotifyPush服务是否正在运行失败($0)"

${EndIf}

${EndIf}

在安装节点的末尾,写入注册服务的脚本

DetailPrint "Installing JiXiaoNotifyPush Client service..."

SimpleSC::InstallService "JiXiaoNotifyPush" "JiXiaoNotifyPush" "16" "2" "$INSTDIR\JiXiaoNotifyPush.exe" "" "" ""

Pop $0

;如果安装不成功

If{If} 0 != 0

Push $0

;获取不成功的系统错误信息

SimpleSC::GetErrorMessage

Pop $0

;将信息弹窗展示给用户

MessageBox MB_OK|MB_ICONSTOP "JiXiaoNotifyPush服务安装失败($0),请手动注册"

${EndIf}

#启动服务

DetailPrint "Starting JiXiaoNotifyPush Client service..."

SimpleSC::StartService "JiXiaoNotifyPush" "" 30

Pop $0

If{If} 0 != 0

Push $0

SimpleSC::GetErrorMessage

Pop $0

MessageBox MB_OK|MB_ICONSTOP "JiXiaoNotifyPush服务启动失败($0)"

${EndIf}

题外话:简单说下命令参数的意思,中括号里面的都是参数
SimpleSC::InstallService [name_of_service] [display_name] [service_type] [start_type] 
  [binary_path] [dependencies] [account] [password]

SimpleSC::StartService [name_of_service] [arguments] [timeout]SimpleSC::StopService [name_of_service] [wait_for_file_release] [timeout]SimpleSC::RemoveService [name_of_service]

  • name_of_service - 用于启动/停止命令和所有其他命令的服务的名称
  • display_name - 系统控制中服务控制管理器中显示的名称
  • service_type - 以下代码之一
    • 1 - SERVICE_KERNEL_DRIVER - 驱动程序服务。
    • 2 - SERVICE_FILE_SYSTEM_DRIVER - 文件系统驱动服务。
    • 16 - SERVICE_WIN32_OWN_PROCESS - 在自己的进程中运行的服务。(应该在大多数情况下使用)
    • 32 - SERVICE_WIN32_SHARE_PROCESS - 与一个或多个其他服务共享进程的服务。
    • 256 - SERVICE_INTERACTIVE_PROCESS - 服务可以与桌面交互。
      • 注意:如果您指定 SERVICE_WIN32_OWN_PROCESS 或 SERVICE_WIN32_SHARE_PROCESS,并且服务在 LocalSystem 帐户的上下文中运行,您也可以指定此值。示例:SERVICE_WIN32_OWN_PROCESS 或 SERVICE_INTERACTIVE_PROCESS -(16 或 256)= 272
      • 注意:从 Windows Vista 开始,服务无法直接与用户交互。因此,不应在新代码中使用此技术。有关更多信息,请参见:http : //msdn2.microsoft.com/en-us/library/ms683502(VS.85).aspx
  • binary_path - 服务的目录,参数中的 $INSTDIR是根目录的意思
  • start_type - 以下代码之一
    • 0 - SERVICE_BOOT_START - 驱动程序启动阶段开始
    • 1 - SERVICE_SYSTEM_START - 驱动程序 scm 阶段开始
    • 2 - SERVICE_AUTO_START - 服务自动启动(应该在大多数情况下使用)
    • 3 - SERVICE_DEMAND_START - 驱动程序/服务手册启动
    • 4 - SERVICE_DISABLED - 驱动程序/服务被禁用
  • wait_for_file_release - 服务停止后等待文件释放。如果在停止服务后二进制文件将被覆盖,这将很有用。
    • 0 - NO_WAIT - 不等待文件发布
    • 1 - WAIT - 等待文件发布
    • 注意:如果使用 SERVICE_WIN32_OWN_PROCESS,则此选项应设置为 WAIT。如果 SERVICE_WIN32_SHARE_PROCESS 被使用,这个选项应该只在进程中的最后一个服务停止时设置为 WAIT。

2.添加关闭删除服务的命令到卸载程序的节点下:

最后点击下图中的按钮(编译并运行) ,就可以看到已经打包的文件了

双击Setup.exe文件,选择安装目录,然后就可以在服务列表中看到我们编写的windows服务。

MS编写配置文件生成

main.cpp

主函数端口控制,例如:http:80、https:443等。

secret校验,使用开源默认值不安全。红框注释掉config.ini生成。

ssl文件加载方法

WebHook.cpp

hookApi默认配置控制,例如:是否开启hookApi,Api回调地址等。

WebApi.cpp

api默认配置控制。

红框secret修改。

config.cpp

config.ini的主要默认配置来源。

红框注释掉config.ini生成,并对本地配置文件加载默认返回true。

IP白名单配置

FFmpegSource.cpp

FFmpeg默认配置控制。

mk_common.cpp

mk_common.cpp主要管理mediakit服务启动公共函数。

修改hookApi 参数:

httpSession.cpp 修改httpSession的参数传递 修改 host 为 Referer

config 启动 QSV 加速:

ffmpeg因特尔核显QSV加速

SSLBox SSL文件加载处理:

HttpSession.cpp 自定义跨域配置

API的ip、secret校验方法

webrtc编译

srtp 本地配置