我有一个用c#编写的Windows服务,我需要从中运行一个控制台应用程序。 控制台应用程序也用c#编写。
控制台应用程序在不是从Windows服务运行时运行正常。当它从ws运行它没有做它应该做的任何事情,因为它应该工作10-20秒我在调试代码中看到立即执行。
我正在使用以下代码启动我的控制台应用程序:
proc.Start(fullPathToConsole, args);
proc.WaitForExit();
控制台的路径是正确的,当我试图从cmd或仅在资源管理器(没有args)中运行它时,它工作正常。但在使用该服务后,我认为没有效果。
我已经尝试转到服务属性并授予它访问桌面的权限,并在系统和我的用户下运行(也在服务属性中指定)。一切都保持不变。
附加:我知道服务没有ui,我不想要一个。我希望服务运行控制台应用程序。无需从中获取任何数据或像ui一样使用此控制台,只需运行它就可以完成它的工作。
更新我发现,运行计算或任何其他Windows应用程序很容易。但仍然无法运行cmd或任何控制台应用程序。实际上我需要在XP SP2和Windows 2003 Server上运行它。因此,无论如何都不需要与Vista进行交互。
很高兴任何评论!
答案 0 :(得分:25)
从Windows Vista开始,服务无法与桌面交互。您将无法看到从服务启动的任何窗口或控制台窗口。请参阅此MSDN forum thread。
在其他操作系统上,服务选项中有一个选项,名为“允许服务与桌面交互”。从技术上讲,你应该为未来编程,即使你没有在Vista上使用它,也应遵循Vista准则。
如果您仍想运行从不与桌面交互的应用程序,请尝试指定该进程不使用该shell。
ProcessStartInfo info = new ProcessStartInfo(@"c:\myprogram.exe");
info.UseShellExecute = false;
info.RedirectStandardError = true;
info.RedirectStandardInput = true;
info.RedirectStandardOutput = true;
info.CreateNoWindow = true;
info.ErrorDialog = false;
info.WindowStyle = ProcessWindowStyle.Hidden;
Process process = Process.Start(info);
看看这是否有效。
首先通知Windows该程序不会使用shell(在Vista中无法访问)。
其次,您将所有控制台交互重定向到内部流(请参阅process.StandardInput
和process.StandardOutput
。
答案 1 :(得分:8)
我在成功之前就完成了这个 - 我在家里有一些代码。当我今晚回到家时,我将使用启动控制台应用程序的服务的工作代码更新此答案。
我以为我会从头开始尝试。这是我编写的一些启动控制台应用程序的代码。我将其作为服务安装并运行并且它正常工作:cmd.exe启动(如任务管理器中所示)并持续10秒,直到我发送退出命令。我希望这可以帮助你解决问题,因为它可以正常运行。
using (System.Diagnostics.Process process = new System.Diagnostics.Process())
{
process.StartInfo = new System.Diagnostics.ProcessStartInfo(@"c:\windows\system32\cmd.exe");
process.StartInfo.CreateNoWindow = true;
process.StartInfo.ErrorDialog = false;
process.StartInfo.RedirectStandardError = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
process.Start();
//// do some other things while you wait...
System.Threading.Thread.Sleep(10000); // simulate doing other things...
process.StandardInput.WriteLine("exit"); // tell console to exit
if (!process.HasExited)
{
process.WaitForExit(120000); // give 2 minutes for process to finish
if (!process.HasExited)
{
process.Kill(); // took too long, kill it off
}
}
}
答案 2 :(得分:4)
Windows服务没有UI。您可以使用this question中显示的代码将控制台应用的输出重定向到您的服务。
答案 3 :(得分:2)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.ServiceProcess;
using System.Runtime.InteropServices;
namespace SystemControl
{
class Services
{
static string strPath = @"D:\";
static void Main(string[] args)
{
string strServiceName = "WindowsService1";
CreateFolderStructure(strPath);
string svcPath = @"D:\Applications\MSC\Agent\bin\WindowsService1.exe";
if (!IsInstalled(strServiceName))
{
InstallAndStart(strServiceName, strServiceName, svcPath + " -k runservice");
}
else
{
Console.Write(strServiceName + " already installed. Do you want to Uninstalled the Service.Y/N.?");
string strKey = Console.ReadLine();
if (!string.IsNullOrEmpty(strKey) && (strKey.StartsWith("y")|| strKey.StartsWith("Y")))
{
StopService(strServiceName);
Uninstall(strServiceName);
ServiceLogs(strServiceName + " Uninstalled.!", strPath);
Console.Write(strServiceName + " Uninstalled.!");
Console.Read();
}
}
}
#region "Environment Variables"
public static string GetEnvironment(string name, bool ExpandVariables = true)
{
if (ExpandVariables)
{
return System.Environment.GetEnvironmentVariable(name);
}
else
{
return (string)Microsoft.Win32.Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\Control\Session Manager\Environment\").GetValue(name, "", Microsoft.Win32.RegistryValueOptions.DoNotExpandEnvironmentNames);
}
}
public static void SetEnvironment(string name, string value)
{
System.Environment.SetEnvironmentVariable(name, value);
}
#endregion
#region "ServiceCalls Native"
public static ServiceController[] List { get { return ServiceController.GetServices(); } }
public static void Start(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch(Exception ex)
{
// ...
}
}
public static void Stop(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
}
catch
{
// ...
}
}
public static void Restart(string serviceName, int timeoutMilliseconds)
{
ServiceController service = new ServiceController(serviceName);
try
{
int millisec1 = Environment.TickCount;
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
// count the rest of the timeout
int millisec2 = Environment.TickCount;
timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));
service.Start();
service.WaitForStatus(ServiceControllerStatus.Running, timeout);
}
catch
{
// ...
}
}
public static bool IsInstalled(string serviceName)
{
// get list of Windows services
ServiceController[] services = ServiceController.GetServices();
// try to find service name
foreach (ServiceController service in services)
{
if (service.ServiceName == serviceName)
return true;
}
return false;
}
#endregion
#region "ServiceCalls API"
private const int STANDARD_RIGHTS_REQUIRED = 0xF0000;
private const int SERVICE_WIN32_OWN_PROCESS = 0x00000010;
[Flags]
public enum ServiceManagerRights
{
Connect = 0x0001,
CreateService = 0x0002,
EnumerateService = 0x0004,
Lock = 0x0008,
QueryLockStatus = 0x0010,
ModifyBootConfig = 0x0020,
StandardRightsRequired = 0xF0000,
AllAccess = (StandardRightsRequired | Connect | CreateService |
EnumerateService | Lock | QueryLockStatus | ModifyBootConfig)
}
[Flags]
public enum ServiceRights
{
QueryConfig = 0x1,
ChangeConfig = 0x2,
QueryStatus = 0x4,
EnumerateDependants = 0x8,
Start = 0x10,
Stop = 0x20,
PauseContinue = 0x40,
Interrogate = 0x80,
UserDefinedControl = 0x100,
Delete = 0x00010000,
StandardRightsRequired = 0xF0000,
AllAccess = (StandardRightsRequired | QueryConfig | ChangeConfig |
QueryStatus | EnumerateDependants | Start | Stop | PauseContinue |
Interrogate | UserDefinedControl)
}
public enum ServiceBootFlag
{
Start = 0x00000000,
SystemStart = 0x00000001,
AutoStart = 0x00000002,
DemandStart = 0x00000003,
Disabled = 0x00000004
}
public enum ServiceState
{
Unknown = -1, // The state cannot be (has not been) retrieved.
NotFound = 0, // The service is not known on the host server.
Stop = 1, // The service is NET stopped.
Run = 2, // The service is NET started.
Stopping = 3,
Starting = 4,
}
public enum ServiceControl
{
Stop = 0x00000001,
Pause = 0x00000002,
Continue = 0x00000003,
Interrogate = 0x00000004,
Shutdown = 0x00000005,
ParamChange = 0x00000006,
NetBindAdd = 0x00000007,
NetBindRemove = 0x00000008,
NetBindEnable = 0x00000009,
NetBindDisable = 0x0000000A
}
public enum ServiceError
{
Ignore = 0x00000000,
Normal = 0x00000001,
Severe = 0x00000002,
Critical = 0x00000003
}
[StructLayout(LayoutKind.Sequential)]
private class SERVICE_STATUS
{
public int dwServiceType = 0;
public ServiceState dwCurrentState = 0;
public int dwControlsAccepted = 0;
public int dwWin32ExitCode = 0;
public int dwServiceSpecificExitCode = 0;
public int dwCheckPoint = 0;
public int dwWaitHint = 0;
}
[DllImport("advapi32.dll", EntryPoint = "OpenSCManagerA")]
private static extern IntPtr OpenSCManager(string lpMachineName, string lpDatabaseName, ServiceManagerRights dwDesiredAccess);
[DllImport("advapi32.dll", EntryPoint = "OpenServiceA", CharSet = CharSet.Ansi)]
private static extern IntPtr OpenService(IntPtr hSCManager, string lpServiceName, ServiceRights dwDesiredAccess);
[DllImport("advapi32.dll", EntryPoint = "CreateServiceA")]
private static extern IntPtr CreateService(IntPtr hSCManager, string lpServiceName, string lpDisplayName, ServiceRights dwDesiredAccess, int dwServiceType, ServiceBootFlag dwStartType, ServiceError dwErrorControl, string lpBinaryPathName, string lpLoadOrderGroup, IntPtr lpdwTagId, string lpDependencies, string lp, string lpPassword);
[DllImport("advapi32.dll")]
private static extern int CloseServiceHandle(IntPtr hSCObject);
[DllImport("advapi32.dll")]
private static extern int QueryServiceStatus(IntPtr hService, SERVICE_STATUS lpServiceStatus);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int DeleteService(IntPtr hService);
[DllImport("advapi32.dll")]
private static extern int ControlService(IntPtr hService, ServiceControl dwControl, SERVICE_STATUS lpServiceStatus);
[DllImport("advapi32.dll", EntryPoint = "StartServiceA")]
private static extern int StartService(IntPtr hService, int dwNumServiceArgs, int lpServiceArgVectors);
/// <summary>
/// Takes a service name and tries to stop and then uninstall the windows serviceError
/// </summary>
/// <param name="ServiceName">The windows service name to uninstall</param>
public static void Uninstall(string ServiceName)
{
IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
try
{
IntPtr service = OpenService(scman, ServiceName, ServiceRights.StandardRightsRequired | ServiceRights.Stop | ServiceRights.QueryStatus);
if (service == IntPtr.Zero)
{
throw new ApplicationException("Service not installed.");
}
try
{
StopService(service);
int ret = DeleteService(service);
if (ret == 0)
{
int error = Marshal.GetLastWin32Error();
throw new ApplicationException("Could not delete service " + error);
}
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scman);
}
}
/// <summary>
/// Accepts a service name and returns true if the service with that service name exists
/// </summary>
/// <param name="ServiceName">The service name that we will check for existence</param>
/// <returns>True if that service exists false otherwise</returns>
public static bool ServiceIsInstalled(string ServiceName)
{
IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
try
{
IntPtr service = OpenService(scman, ServiceName,
ServiceRights.QueryStatus);
if (service == IntPtr.Zero) return false;
CloseServiceHandle(service);
return true;
}
finally
{
CloseServiceHandle(scman);
}
}
/// <summary>
/// Takes a service name, a service display name and the path to the service executable and installs / starts the windows service.
/// </summary>
/// <param name="ServiceName">The service name that this service will have</param>
/// <param name="DisplayName">The display name that this service will have</param>
/// <param name="FileName">The path to the executable of the service</param>
public static void InstallAndStart(string ServiceName, string DisplayName,
string FileName)
{
IntPtr scman = OpenSCManager(ServiceManagerRights.Connect |
ServiceManagerRights.CreateService);
try
{
string strKey = string.Empty;
IntPtr service = OpenService(scman, ServiceName,
ServiceRights.QueryStatus | ServiceRights.Start);
if (service == IntPtr.Zero)
{
service = CreateService(scman, ServiceName, DisplayName,
ServiceRights.QueryStatus | ServiceRights.Start, SERVICE_WIN32_OWN_PROCESS,
ServiceBootFlag.AutoStart, ServiceError.Normal, FileName, null, IntPtr.Zero,
null, null, null);
ServiceLogs(ServiceName + " Installed Sucessfully.!", strPath);
Console.Write(ServiceName + " Installed Sucessfully.! Do you want to Start the Service.Y/N.?");
strKey=Console.ReadLine();
}
if (service == IntPtr.Zero)
{
ServiceLogs("Failed to install service.", strPath);
throw new ApplicationException("Failed to install service.");
}
try
{
if (!string.IsNullOrEmpty(strKey) && (strKey.StartsWith("y") || strKey.StartsWith("Y")))
{
StartService(service);
ServiceLogs(ServiceName + " Started Sucessfully.!", strPath);
Console.Write(ServiceName + " Started Sucessfully.!");
Console.Read();
}
}
finally
{
CloseServiceHandle(service);
}
}
finally
{
CloseServiceHandle(scman);
}
}
/// <summary>
/// Takes a service name and starts it
/// </summary>
/// <param name="Name">The service name</param>
public static void StartService(string Name)
{
IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
try
{
IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus |
ServiceRights.Start);
if (hService == IntPtr.Zero)
{
ServiceLogs("Could not open service.", strPath);
throw new ApplicationException("Could not open service.");
}
try
{
StartService(hService);
}
finally
{
CloseServiceHandle(hService);
}
}
finally
{
CloseServiceHandle(scman);
}
}
/// <summary>
/// Stops the provided windows service
/// </summary>
/// <param name="Name">The service name that will be stopped</param>
public static void StopService(string Name)
{
IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
try
{
IntPtr hService = OpenService(scman, Name, ServiceRights.QueryStatus |
ServiceRights.Stop);
if (hService == IntPtr.Zero)
{
ServiceLogs("Could not open service.", strPath);
throw new ApplicationException("Could not open service.");
}
try
{
StopService(hService);
}
finally
{
CloseServiceHandle(hService);
}
}
finally
{
CloseServiceHandle(scman);
}
}
/// <summary>
/// Stars the provided windows service
/// </summary>
/// <param name="hService">The handle to the windows service</param>
private static void StartService(IntPtr hService)
{
SERVICE_STATUS status = new SERVICE_STATUS();
StartService(hService, 0, 0);
WaitForServiceStatus(hService, ServiceState.Starting, ServiceState.Run);
}
/// <summary>
/// Stops the provided windows service
/// </summary>
/// <param name="hService">The handle to the windows service</param>
private static void StopService(IntPtr hService)
{
SERVICE_STATUS status = new SERVICE_STATUS();
ControlService(hService, ServiceControl.Stop, status);
WaitForServiceStatus(hService, ServiceState.Stopping, ServiceState.Stop);
}
/// <summary>
/// Takes a service name and returns the <code>ServiceState</code> of the corresponding service
/// </summary>
/// <param name="ServiceName">The service name that we will check for his <code>ServiceState</code></param>
/// <returns>The ServiceState of the service we wanted to check</returns>
public static ServiceState GetServiceStatus(string ServiceName)
{
IntPtr scman = OpenSCManager(ServiceManagerRights.Connect);
try
{
IntPtr hService = OpenService(scman, ServiceName,
ServiceRights.QueryStatus);
if (hService == IntPtr.Zero)
{
return ServiceState.NotFound;
}
try
{
return GetServiceStatus(hService);
}
finally
{
CloseServiceHandle(scman);
}
}
finally
{
CloseServiceHandle(scman);
}
}
/// <summary>
/// Gets the service state by using the handle of the provided windows service
/// </summary>
/// <param name="hService">The handle to the service</param>
/// <returns>The <code>ServiceState</code> of the service</returns>
private static ServiceState GetServiceStatus(IntPtr hService)
{
SERVICE_STATUS ssStatus = new SERVICE_STATUS();
if (QueryServiceStatus(hService, ssStatus) == 0)
{
ServiceLogs("Failed to query service status.", strPath);
throw new ApplicationException("Failed to query service status.");
}
return ssStatus.dwCurrentState;
}
/// <summary>
/// Returns true when the service status has been changes from wait status to desired status
/// ,this method waits around 10 seconds for this operation.
/// </summary>
/// <param name="hService">The handle to the service</param>
/// <param name="WaitStatus">The current state of the service</param>
/// <param name="DesiredStatus">The desired state of the service</param>
/// <returns>bool if the service has successfully changed states within the allowed timeline</returns>
private static bool WaitForServiceStatus(IntPtr hService, ServiceState
WaitStatus, ServiceState DesiredStatus)
{
SERVICE_STATUS ssStatus = new SERVICE_STATUS();
int dwOldCheckPoint;
int dwStartTickCount;
QueryServiceStatus(hService, ssStatus);
if (ssStatus.dwCurrentState == DesiredStatus) return true;
dwStartTickCount = Environment.TickCount;
dwOldCheckPoint = ssStatus.dwCheckPoint;
while (ssStatus.dwCurrentState == WaitStatus)
{
// Do not wait longer than the wait hint. A good interval is
// one tenth the wait hint, but no less than 1 second and no
// more than 10 seconds.
int dwWaitTime = ssStatus.dwWaitHint / 10;
if (dwWaitTime < 1000) dwWaitTime = 1000;
else if (dwWaitTime > 10000) dwWaitTime = 10000;
System.Threading.Thread.Sleep(dwWaitTime);
// Check the status again.
if (QueryServiceStatus(hService, ssStatus) == 0) break;
if (ssStatus.dwCheckPoint > dwOldCheckPoint)
{
// The service is making progress.
dwStartTickCount = Environment.TickCount;
dwOldCheckPoint = ssStatus.dwCheckPoint;
}
else
{
if (Environment.TickCount - dwStartTickCount > ssStatus.dwWaitHint)
{
// No progress made within the wait hint
break;
}
}
}
return (ssStatus.dwCurrentState == DesiredStatus);
}
/// <summary>
/// Opens the service manager
/// </summary>
/// <param name="Rights">The service manager rights</param>
/// <returns>the handle to the service manager</returns>
private static IntPtr OpenSCManager(ServiceManagerRights Rights)
{
IntPtr scman = OpenSCManager(null, null, Rights);
if (scman == IntPtr.Zero)
{
try
{
throw new ApplicationException("Could not connect to service control manager.");
}
catch (Exception ex)
{
}
}
return scman;
}
#endregion
#region"CreateFolderStructure"
private static void CreateFolderStructure(string path)
{
if(!System.IO.Directory.Exists(path+"Applications"))
System.IO.Directory.CreateDirectory(path+ "Applications");
if (!System.IO.Directory.Exists(path + "Applications\\MSC"))
System.IO.Directory.CreateDirectory(path + "Applications\\MSC");
if (!System.IO.Directory.Exists(path + "Applications\\MSC\\Agent"))
System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\Agent");
if (!System.IO.Directory.Exists(path + "Applications\\MSC\\Agent\\bin"))
System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\Agent\\bin");
if (!System.IO.Directory.Exists(path + "Applications\\MSC\\AgentService"))
System.IO.Directory.CreateDirectory(path + "Applications\\MSC\\AgentService");
string fullPath = System.IO.Path.GetFullPath("MSCService");
if (System.IO.Directory.Exists(fullPath))
{
foreach (string strFile in System.IO.Directory.GetFiles(fullPath))
{
if (System.IO.File.Exists(strFile))
{
String[] strArr = strFile.Split('\\');
System.IO.File.Copy(strFile, path + "Applications\\MSC\\Agent\\bin\\"+ strArr[strArr.Count()-1], true);
}
}
}
}
#endregion
private static void ServiceLogs(string strLogInfo, string path)
{
string filePath = path + "Applications\\MSC\\AgentService\\ServiceLogs.txt";
System.IO.File.AppendAllLines(filePath, (strLogInfo + "--" + DateTime.Now.ToString()).ToString().Split('|'));
}
}
}
答案 4 :(得分:0)
正如皮埃尔所说,没有办法为Windows服务提供用户界面(或者没有简单的方法)。我在这种情况下所做的是拥有一个设置文件,该文件在服务运行的任何时间间隔内从服务中读取,并且有一个独立的应用程序可以更改设置文件。
答案 5 :(得分:0)
您的控制台应用是否需要用户互动?如果是这样,这是一个严重的禁忌,你应该重新设计你的应用程序。虽然有一些黑客可以在旧版本的操作系统中使用这种方法,但这肯定会在未来中断。
如果您的应用不需要用户互动,那么您的问题可能与运行该服务的用户有关。请确保您以正确的用户身份运行,或者您使用的用户和/或资源具有正确的权限。
如果您需要某种用户交互,那么您将需要创建一个客户端应用程序,并通过rpc,套接字或命名管道与服务和/或子应用程序进行通信。
答案 6 :(得分:0)
服务需要连接到服务控制管理器并在启动时提供反馈(即告诉SCM'我还活着!')。这就是C#应用程序为服务提供不同项目模板的原因。您有两种选择:
答案 7 :(得分:0)
我有一个Windows服务,我将以下行添加到我的服务的构造函数中:
using System.Diagnostics;
try {
Process p = Process.Start(@"C:\Windows\system32\calc.exe");
} catch {
Debugger.Break();
}
当我尝试运行它时,进行了Process.Start()调用,并且没有发生异常。但是,calc.exe应用程序没有显示出来。为了使其工作,我在服务控制管理器中编辑了我的服务的属性,以启用与桌面的交互。执行此操作后,Process.Start()按预期打开了calc.exe。
但正如其他人所说,微软不赞成与桌面的互动,并且在Vista中基本上被禁用。因此即使你可以在XP中使用它,我也不知道你能在Vista中使它工作。
答案 8 :(得分:0)
我使用此类:
class ProcessWrapper : Process, IDisposable
{
public enum PipeType { StdOut, StdErr }
public class Output
{
public string Message { get; set; }
public PipeType Pipe { get; set; }
public override string ToString()
{
return $"{Pipe}: {Message}";
}
}
private readonly string _command;
private readonly string _args;
private readonly bool _showWindow;
private bool _isDisposed;
private readonly Queue<Output> _outputQueue = new Queue<Output>();
private readonly ManualResetEvent[] _waitHandles = new ManualResetEvent[2];
private readonly ManualResetEvent _outputSteamWaitHandle = new ManualResetEvent(false);
public ProcessWrapper(string startCommand, string args, bool showWindow = false)
{
_command = startCommand;
_args = args;
_showWindow = showWindow;
}
public IEnumerable<string> GetMessages()
{
while (!_isDisposed)
{
_outputSteamWaitHandle.WaitOne();
if (_outputQueue.Any())
yield return _outputQueue.Dequeue().ToString();
}
}
public void SendCommand(string command)
{
StandardInput.Write(command);
StandardInput.Flush();
}
public new int Start()
{
ProcessStartInfo startInfo = new ProcessStartInfo
{
FileName = _command,
Arguments = _args,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
RedirectStandardInput = true,
CreateNoWindow = !_showWindow
};
StartInfo = startInfo;
OutputDataReceived += delegate (object sender, DataReceivedEventArgs args)
{
if (args.Data == null)
{
_waitHandles[0].Set();
}
else if (args.Data.Length > 0)
{
_outputQueue.Enqueue(new Output { Message = args.Data, Pipe = PipeType.StdOut });
_outputSteamWaitHandle.Set();
}
};
ErrorDataReceived += delegate (object sender, DataReceivedEventArgs args)
{
if (args.Data == null)
{
_waitHandles[1].Set();
}
else if (args.Data.Length > 0)
{
_outputSteamWaitHandle.Set();
_outputQueue.Enqueue(new Output { Message = args.Data, Pipe = PipeType.StdErr });
}
};
base.Start();
_waitHandles[0] = new ManualResetEvent(false);
BeginErrorReadLine();
_waitHandles[1] = new ManualResetEvent(false);
BeginOutputReadLine();
return Id;
}
public new void Dispose()
{
StandardInput.Flush();
StandardInput.Close();
if (!WaitForExit(1000))
{
Kill();
}
if (WaitForExit(1000))
{
WaitHandle.WaitAll(_waitHandles);
}
base.Dispose();
_isDisposed = true;
}
}
答案 9 :(得分:-12)
在Windows服务中运行任何应用程序,例如“.exe”都很奇怪,因为算法效果不佳。