记HttpListener调用exe程序界面无法打开
需求:项目中需要监听本地端口 收到请求后打开对应的exe文件
开始是使用windowsService启动了一个HttpListener监听服务 后面执行调用的时候只有调用日志 并不能打开界面 但是命令确实是执行了
比如 执行 notepad 就看不到notepad界面 执行docker start mysql 然后用命令查看docker状态是启动了的
问题原因大致就是 listener监听服务和要启动的程序级别不一样
具体要搜索 StartProcessAndBypassUAC 这个方法的使用
解决办法:
先使用在WindowsServer里面使用StartProcessAndBypassUAC 启动一个exe程序 然后再在这个exe程序里面启动一个监听服务 这样就可以调动有界面的程序 了
代码:
Name是监听服务宿主程序名
protected override void OnStart(string[] args) { string path = ConfigHelper.CurrDllLoclPath + Name + ".exe"; ApplicationLoader.PROCESS_INFORMATION procInfo; ApplicationLoader.StartProcessAndBypassUAC(path, out procInfo); t.Interval = 5000; t.Elapsed += new System.Timers.ElapsedEventHandler(ScanProcess); t.Start(); } private void ScanProcess(object obj, System.Timers.ElapsedEventArgs e) { string appName = Name; string path = ConfigHelper.CurrDllLoclPath + Name + ".exe"; Process[] app = Process.GetProcessesByName(appName); if (app.Length <= 0) { ApplicationLoader.PROCESS_INFORMATION procInfo; ApplicationLoader.StartProcessAndBypassUAC(path, out procInfo); } }
exe程序代码就是正常的启动监听
然后监听里面去使用Proccess调用程序
#region 启动http监听线程 //tese string errMsg = ""; try { _listener = new HttpListener(); LogHelper.WirteLog("启动http监听线程Third"); _listener.Start(); //监听地址 _uriPrefix = "http://" + ConfigHelper.GetIP + "/"; string _Port = ConfigHelper.GetPort; if (!string.IsNullOrEmpty(_Port)) { _uriPrefix = "http://" + ConfigHelper.GetIP + ":" + ConfigHelper.GetPort + "/"; } string Mark = ConfigHelper.GetMark; if (!string.IsNullOrEmpty(Mark)) { _uriPrefix = _uriPrefix + Mark + "/"; } string LocalComCode = ConfigHelper.GetLocalComCode; if (!string.IsNullOrEmpty(Mark)) { _uriPrefix = _uriPrefix + LocalComCode + "/"; } _listener.Prefixes.Add(_uriPrefix); LogHelper.WirteLog("监听地址:" + _uriPrefix); _thread = new Thread(new ThreadStart(ListenerThread)); _thread.Start(); } catch (Exception ex) { errMsg = "服务启动异常:" + ex.Message; LogHelper.WirteLog(errMsg); }
然后根据不同的参数去调用exe就好了
var res = StartProcess(exepath,new string[] { command },ref msg);
Process myprocess = new Process(); ProcessStartInfo startInfo = new ProcessStartInfo(filename, s); myprocess.StartInfo = startInfo; myprocess.StartInfo.UseShellExecute = false; myprocess.StartInfo.CreateNoWindow = true; myprocess.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden; myprocess.Start();