德克云技术联盟
标题:
在C#桌面程序中启动、关闭Jetty
[打印本页]
作者:
李昭
时间:
2014-11-4 15:50
标题:
在C#桌面程序中启动、关闭Jetty
这个有意思。这个成果是开发DFAM的副产物。
java程序控制jetty可能更合适一点,但是刚开始编写DFAM本地客户端的时候,我为了加快进度,客户端使用c#写的,这个问题就绕不开了:怎么能用c#来控制jetty呢?
1、先看启动。
一般我们下载jetty包后,首先要做的事是需要添加一个start.bat文件,来方便启动。
start.bat最初代码是:
java -jar start.jar
后来,为了方便在其他地方用DOS命令启动,我把它改成这样:
cd /d e:\jetty-distribution-8.1.11.v20130520\
java -jar start.jar
看懂了吧,也就是先跳到jetty根目录,再启动start.jar。这样就不会爆找不见start.jar文件的错误。
然后呢?
然后就是编写c#页面啦。
在启动按钮里面加入以下代码:
Process p = new Process();
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = " /k " + batPath ;
p.StartInfo.WindowStyle = ProcessWindowStyle.Minimized;
p.Start();
setConsole("\r\n jetty正在启动中……");
//开辟线程,看看jetty是否已启动,DFAM是否能正常访问
Timer timer = new Timer();
timer.Interval = 2000;
timer.Tick += new EventHandler(timer_Tick);
timer.Start();
巡查线程是要创建的:
void timer_Tick(object sender, EventArgs e)
{
if (IsDFAMRunning())
{
Timer theTimer = (Timer)sender;
theTimer.Stop();
}
}
里面的
IsDFAMRunning()
方法是需要jetty里面的项目提供返回值的,这个你得根据自己的应用修改。下面的代码是我的:
private bool IsDFAMRunning()
{
dengdai++;
setConsole( "\r\n 第" + dengdai + "次探测进行中,共60次……");
if (dengdai > 60) {
setConsole("\r\n 等待时间超过了120秒,jetty启动失败。你可以选择手动启动jetty。");
return true;
}
ConfigUtil util = new ConfigUtil();
string DFAMUrl = util.ReadConfig("DFAMUrl");
string strURL = DFAMUrl + "/stuts.do?DFMsg={\"api\":\"DFAM.Stuts.isWorking\"}";
try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(strURL);
request.KeepAlive = true;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
Stream s= response.GetResponseStream();
StreamReader r = new StreamReader(s);
string str=r.ReadToEnd();
if (str.Contains("\"errorcode\":\"-1\"")) {
setConsole("\r\n jetty已启动。");
return true;
}
return false;
}
catch (Exception)
{
return false;
}
}
当巡查线程结束的时候,jetty就启动了,其余的处理就看你自己的了。
2、c#结束jetty。
说实话结束jetty为难了我好半天。找了好些方法,都不是太满意。最后找来找去算是解决了。
先帖代码:
/// <summary>
/// 停止jetty
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button5_Click(object sender, EventArgs e)
{
//获取DFAM目录
ConfigUtil util = new ConfigUtil();
string batPath = util.ReadConfig("batPath");
string jettyUrl = batPath.Substring(0,batPath.Length-9);
//看看相同的进程是否存在
Process[] cmds = Process.GetProcesses();
bool has = false;
foreach (Process cmd in cmds)
{
string windowName = cmd.MainWindowTitle;
if (windowName.Contains("cmd.exe") && windowName.Contains(jettyUrl))
{
cmd.CloseMainWindow();
setConsole("\r\n 开始停止jetty……");
setConsole("\r\n 终止jetty开始巡查线程……");
dengdai = 61;
Timer timer2 = new Timer();
timer2.Interval = 2000;
timer2.Tick += new EventHandler(timer2_Tick);
timer2.Start();
has = true;
break;
}
//还有一种情况是初始文件的名称相同
string cmdname = "";
try
{
cmdname = cmd.MainModule.FileName.ToLower();
}
catch (Exception)
{
}
if (cmdname.Equals(batPath.ToLower()))
{
cmd.CloseMainWindow();
setConsole("\r\n 开始停止jetty……");
setConsole("\r\n 终止jetty开始巡查线程……");
dengdai = 61;
Timer timer2 = new Timer();
timer2.Interval = 2000;
timer2.Tick += new EventHandler(timer2_Tick);
timer2.Start();
has = true;
break;
}
}
if (!has) {
setConsole("没有找到jetty的启动窗口。");
}
}
void timer2_Tick(object sender, EventArgs e)
{
//获取DFAM目录
ConfigUtil util = new ConfigUtil();
string DFAMuri = util.ReadConfig("DFAM");
string jettyUrl = DFAMuri.Replace("webapps\\DFAM", "");
//看看相同的进程是否存在
Process[] cmds = Process.GetProcesses();
bool has = false;
foreach (Process cmd in cmds)
{
string windowName = cmd.MainWindowTitle;
if (windowName.Contains("cmd.exe") && windowName.Contains(jettyUrl))
{
has = true;
}
}
if (!has) {
Timer theTimer = (Timer)sender;
theTimer.Stop();
setConsole("\r\n jetty已停止运行。");
}
}
解释一下:单独的找CDM窗口关闭很难判断出来是不是c#刚才打开的那个,因为存在多个CMD窗口的时候就会误关。所以要根据启动时jetty的url来确定是不是同一个jetty。因为jetty在启动的时候会自我限制,如果一个jetty已经启动了,他是不能启动第二次的,所以不会有两个相同路径的jetty。这就是我关闭时候的唯一性保证。
欢迎光临 德克云技术联盟 (http://www.decoclouds.com/)