界面展示一下:
原因
平常工作中用Nginx比较多,网上虽然也有wnmp集成环境,但是感觉界面不好看,用起来不舒服,所有决定自己做一个吧。
原料
软件用的是C#,GUI框架是WPF(这个做出来更好看一点),先去官网下载PHP,用的是NTS版本的(因为这里PHP是以CGi的形式跑的),再去下载Windows版的Nginx和Mysql
代码
基类
public class WnmpProgram: INotifyPropertyChanged
{
public TextBlock statusLabel { get; set; } // Label that shows the programs status
public string exeName { get; set; } // Location of the executable file
public string procName { get; set; } // Name of the process
public string progName { get; set; } // User-friendly name of the program
public string workingDir { get; set; } // working directory
public Log.LogSection progLogSection { get; set; } // LogSection of the program
public string startArgs { get; set; } // Start Arguments
public string stopArgs { get; set; } // Stop Arguments if KillStop is false
public bool killStop { get; set; } // Kill process instead of stopping it gracefully
public string confDir { get; set; } // Directory where all the programs configuration files are
public string logDir { get; set; } // Directory where all the programs log files are
public Ini Settings { get; set; }
//public ContextMenuStrip configContextMenu { get; set; } // Displays all the programs config files in |confDir|
//public ContextMenuStrip logContextMenu { get; set; } // Displays all the programs log files in |logDir|
public Process ps = new Process();
public event PropertyChangedEventHandler PropertyChanged;
// 是否在运行
private bool running = false;
public bool Running
{
get
{
return this.running;
}
set
{
this.running = value;
if(PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs("Running"));
}
}
}
public WnmpProgram()
{
//configContextMenu = new ContextMenuStrip();
//logContextMenu = new ContextMenuStrip();
//configContextMenu.ItemClicked += configContextMenu_ItemClicked;
//logContextMenu.ItemClicked += logContextMenu_ItemClicked;
}
/// <summary>
/// 设置状态
/// </summary>
public void SetStatus()
{
if (this.IsRunning() == true)
{
this.Running = true;
}
else
{
this.Running = false;
}
}
public void StartProcess(string exe, string args, bool wait = false)
{
ps.StartInfo.FileName = exe;
ps.StartInfo.Arguments = args;
ps.StartInfo.UseShellExecute = false;
ps.StartInfo.RedirectStandardOutput = true;
ps.StartInfo.WorkingDirectory = workingDir;
ps.StartInfo.CreateNoWindow = true;
ps.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
ps.Start();
if (wait) {
ps.WaitForExit();
}
}
public virtual void Start()
{
if(IsRunning())
{
return;
}
try {
StartProcess(exeName, startArgs);
Log.wnmp_log_notice("Started " + progName, progLogSection);
} catch (Exception ex) {
Log.wnmp_log_error("Start(): " + ex.Message, progLogSection);
}
}
public virtual void Stop()
{
if(!IsRunning())
{
return;
}
if (killStop == false)
StartProcess(exeName, stopArgs, true);
var processes = Process.GetProcessesByName(procName);
foreach (var process in processes) {
process.Kill();
}
Log.wnmp_log_notice("Stopped " + progName, progLogSection);
}
public void Restart()
{
this.Stop();
this.Start();
Log.wnmp_log_notice("Restarted " + progName, progLogSection);
}
//public void ConfigButton(object sender)
//{
// var btnSender = (Button)sender;
// var ptLowerLeft = new Point(0, btnSender.Height);
// ptLowerLeft = btnSender.PointToScreen(ptLowerLeft);
// configContextMenu.Show(ptLowerLeft);
//}
//private void logContextMenu_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
//{
// try {
// Process.Start(Settings.Editor.Value, frmMain.StartupPath + logDir + e.ClickedItem.Text);
// } catch (Exception ex) {
// Log.wnmp_log_error(ex.Message, progLogSection);
// }
//}
public bool IsRunning()
{
var processes = Process.GetProcessesByName(procName);
return (processes.Length != 0);
}
}
开启mysql代码:
class MysqlProgram : WnmpProgram
{
private readonly ServiceController MysqlController = new ServiceController();
public const string ServiceName = "mysql-salamander";
public MysqlProgram()
{
MysqlController.MachineName = Environment.MachineName;
MysqlController.ServiceName = ServiceName;
}
public void RemoveService()
{
StartProcess("cmd.exe", stopArgs, true);
}
public void InstallService()
{
StartProcess(exeName, startArgs, true);
}
public bool ServiceExists()
{
ServiceController[] services = ServiceController.GetServices();
foreach (var service in services) {
if (service.ServiceName == ServiceName)
return true;
}
return false;
}
public override void Start()
{
if(MysqlController.Status == ServiceControllerStatus.Running)
{
return;
}
try {
MysqlController.Start();
MysqlController.WaitForStatus(ServiceControllerStatus.Running);
Log.wnmp_log_notice("Started " + progName, progLogSection);
} catch (Exception ex) {
Log.wnmp_log_error("Start(): " + ex.Message, progLogSection);
}
}
public override void Stop()
{
if(MysqlController.Status == ServiceControllerStatus.Stopped)
{
return;
}
try {
MysqlController.Stop();
MysqlController.WaitForStatus(ServiceControllerStatus.Stopped);
Log.wnmp_log_notice("Stopped " + progName, progLogSection);
} catch (Exception ex) {
Log.wnmp_log_notice("Stop(): " + ex.Message, progLogSection);
}
}
}
开启php代码:
class PHPProgram : WnmpProgram
{
public PHPProgram()
{
ps.StartInfo.EnvironmentVariables.Add("PHP_FCGI_MAX_REQUESTS", "0"); // Disable auto killing PHP
}
private string GetPHPIniPath()
{
return MainWindow.StartupPath + "/" + Settings.PHPDirName.Value + "/php.ini";
}
public override void Start()
{
if(this.IsRunning())
{
return;
}
uint ProcessCount = Settings.PHP_Processes.Value;
short port = Settings.PHP_Port.Value;
string phpini = GetPHPIniPath();
try {
for (var i = 1; i <= ProcessCount; i++) {
StartProcess(exeName, String.Format("-b localhost:{0} -c {1}", port, phpini));
Log.wnmp_log_notice("Starting PHP " + i + "/" + ProcessCount + " on port: " + port, progLogSection);
port++;
}
Log.wnmp_log_notice("PHP started", progLogSection);
} catch (Exception ex) {
Log.wnmp_log_error("StartPHP(): " + ex.Message, progLogSection);
}
}
}
开启nginx
这里要注意WorkingDirectory属性设置成nginx目录,这里是setup代码
private readonly WnmpProgram nginx = new WnmpProgram();
private void SetupNginx()
{
nginx.Settings = Settings;
nginx.exeName = StartupPath + String.Format("{0}/nginx.exe", Settings.NginxDirName.Value);
nginx.procName = "nginx";
nginx.progName = "Nginx";
nginx.workingDir = StartupPath + Settings.NginxDirName.Value;
nginx.progLogSection = Log.LogSection.WNMP_NGINX;
nginx.startArgs = "";
nginx.stopArgs = "-s stop";
nginx.killStop = false;
nginx.statusLabel = lblNginx;
nginx.confDir = "/conf/";
nginx.logDir = "/logs/";
}
其他功能
配置nginx,php,mysql目录名,管理php扩展
编程语言面板
下载后配置
注意
php 版本为7.0.1 64位版本,需要MSVC14 (Visual C++ 2015)运行库支持,下载:https://download.microsoft.co...
其实用户完全可以选择自己想要的php版本,放到集成环境的目录下即可(改一下配置,重启)
安装
下载集成包后自动配置
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。