-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Support running custom apps as services
- Loading branch information
Showing
15 changed files
with
1,165 additions
and
190 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
namespace MLocati.ServicesControl | ||
{ | ||
public abstract class ServiceConfig | ||
{ | ||
public readonly string ServiceName; | ||
protected ServiceConfig(string serviceName) | ||
{ | ||
this.ServiceName = serviceName; | ||
} | ||
} | ||
|
||
public class SystemServiceConfig : ServiceConfig | ||
{ | ||
public SystemServiceConfig(string serviceName) | ||
: base(serviceName) | ||
{ | ||
} | ||
|
||
} | ||
|
||
public class ServiceLikeServiceConfig : ServiceConfig | ||
{ | ||
public readonly string Executable; | ||
public readonly string CurrentDirectory; | ||
public readonly string Arguments; | ||
public ServiceLikeServiceConfig(string serviceName, string executable, string currentDirectory, string arguments) | ||
: base(serviceName) | ||
{ | ||
this.Executable = executable; | ||
this.CurrentDirectory = currentDirectory; | ||
this.Arguments = arguments; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Text; | ||
using System.Text.RegularExpressions; | ||
|
||
namespace MLocati.ServicesControl | ||
{ | ||
internal class ServiceConfigManager | ||
{ | ||
private readonly string Filename; | ||
|
||
private ServiceConfig[] _serviceConfigs; | ||
public ServiceConfig[] ServiceConfigs | ||
{ | ||
get { return this._serviceConfigs; } | ||
} | ||
|
||
public ServiceConfigManager(string filename) | ||
{ | ||
this.Filename = filename; | ||
this.Reload(); | ||
} | ||
|
||
public void Reload() | ||
{ | ||
var serviceConfigs = new List<ServiceConfig>(); | ||
var lines = this.ReadFile(); | ||
var rxAttribs = new Regex(@"^[ \t]+(?<name>(executable|currentdirectory|arguments))[ \t]*:[ \t]*(?<value>.*?)[ \t]*$", RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Compiled | RegexOptions.ExplicitCapture); | ||
for (var lineIndex = 0; lineIndex < lines.Length;) | ||
{ | ||
var serviceName = lines[lineIndex++]; | ||
if (serviceName != serviceName.Trim()) | ||
{ | ||
throw new InvalidDataException($"Invalid line {lineIndex}: {serviceName}"); | ||
} | ||
var attribs = new Dictionary<string, string>(); | ||
for (; lineIndex < lines.Length;) | ||
{ | ||
var match = rxAttribs.Match(lines[lineIndex]); | ||
if (!match.Success) | ||
{ | ||
break; | ||
} | ||
var attribName = match.Groups["name"].Value.ToLower(); | ||
if (attribs.ContainsKey(attribName)) | ||
{ | ||
throw new InvalidDataException($"Duplicated attribute: {attribName}"); | ||
} | ||
attribs.Add(attribName, match.Groups["value"].Value); | ||
lineIndex++; | ||
} | ||
if (attribs.ContainsKey("executable")) | ||
{ | ||
serviceConfigs.Add(new ServiceLikeServiceConfig( | ||
serviceName, | ||
attribs["executable"], | ||
attribs.ContainsKey("currentdirectory") ? attribs["currentdirectory"] : "", | ||
attribs.ContainsKey("arguments") ? attribs["arguments"] : "" | ||
)); | ||
} | ||
else | ||
{ | ||
serviceConfigs.Add(new SystemServiceConfig(serviceName)); | ||
} | ||
} | ||
this._serviceConfigs = serviceConfigs.ToArray(); | ||
} | ||
|
||
public void Save(ServiceConfig[] serviceConfigs) | ||
{ | ||
StringBuilder sb = new StringBuilder(); | ||
foreach (var serviceConfig in ServiceConfigs) | ||
{ | ||
sb.AppendLine(serviceConfig.ServiceName); | ||
if (serviceConfig is ServiceLikeServiceConfig) | ||
{ | ||
var sc = (ServiceLikeServiceConfig)serviceConfig; | ||
sb.AppendLine($"\tExecutable: {sc.Executable}"); | ||
sb.AppendLine($"\tCurrentDirectory: {sc.CurrentDirectory}"); | ||
sb.AppendLine($"\tArguments: {sc.Arguments}"); | ||
} | ||
} | ||
using (var configStream = new FileStream(this.Filename, FileMode.OpenOrCreate, FileAccess.Write, FileShare.None)) | ||
{ | ||
configStream.SetLength(0L); | ||
using (var configWriter = new StreamWriter(configStream, Encoding.UTF8)) | ||
{ | ||
configWriter.Write(sb.ToString()); | ||
} | ||
} | ||
this._serviceConfigs = serviceConfigs; | ||
} | ||
private string[] ReadFile() | ||
{ | ||
var result = new List<string>(); | ||
if (File.Exists(this.Filename)) | ||
{ | ||
using (var configStream = new FileStream(this.Filename, FileMode.Open, FileAccess.Read, FileShare.Read)) | ||
{ | ||
using (var configReader = new StreamReader(configStream, Encoding.UTF8)) | ||
{ | ||
string line; | ||
while ((line = configReader.ReadLine()) != null) | ||
{ | ||
line = line.TrimEnd(); | ||
if (line.Length > 0) | ||
{ | ||
result.Add(line); | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return result.ToArray(); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
using System; | ||
using System.ServiceProcess; | ||
|
||
namespace MLocati.ServicesControl | ||
{ | ||
public interface ServiceDriver : IDisposable | ||
{ | ||
string DisplayName { get; } | ||
|
||
ServiceControllerStatus Status { get; } | ||
|
||
bool CanStop { get; } | ||
bool CanPauseAndContinue { get; } | ||
|
||
void Start(); | ||
|
||
void Pause(); | ||
void Continue(); | ||
|
||
void Stop(); | ||
|
||
void Refresh(); | ||
|
||
void WaitForStatus(ServiceControllerStatus desiredStatus, TimeSpan timeout); | ||
} | ||
} |
Oops, something went wrong.