Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Sascha Kiefer
committed
Mar 30, 2010
0 parents
commit 22bd00a
Showing
10 changed files
with
956 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
Microsoft Visual Studio Solution File, Format Version 10.00 | ||
# Visual Studio 2008 | ||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AnyService", "AnyService\AnyService.csproj", "{E600FAE1-2DAA-4175-831A-C917E8E72050}" | ||
EndProject | ||
Global | ||
GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||
Debug|Any CPU = Debug|Any CPU | ||
Release|Any CPU = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(ProjectConfigurationPlatforms) = postSolution | ||
{E600FAE1-2DAA-4175-831A-C917E8E72050}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||
{E600FAE1-2DAA-4175-831A-C917E8E72050}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||
{E600FAE1-2DAA-4175-831A-C917E8E72050}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||
{E600FAE1-2DAA-4175-831A-C917E8E72050}.Release|Any CPU.Build.0 = Release|Any CPU | ||
EndGlobalSection | ||
GlobalSection(SolutionProperties) = preSolution | ||
HideSolutionNode = FALSE | ||
EndGlobalSection | ||
EndGlobal |
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,42 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
|
||
namespace AnyService | ||
{ | ||
public class Disposable : IDisposable | ||
{ | ||
~Disposable() | ||
{ | ||
this.Dispose(false); | ||
} | ||
|
||
protected virtual void Dispose(bool disposing) | ||
{ | ||
if (!this.Disposed) | ||
{ | ||
if (disposing) this.Release(); | ||
this.Disposed = true; | ||
} | ||
} | ||
|
||
protected virtual void Release() { } | ||
|
||
protected bool Disposed | ||
{ | ||
get; | ||
private set; | ||
} | ||
|
||
#region IDisposable Members | ||
|
||
public void Dispose() | ||
{ | ||
this.Dispose(true); | ||
GC.SuppressFinalize(this); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
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,156 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Text; | ||
using System.IO; | ||
|
||
namespace AnyService | ||
{ | ||
class Program | ||
{ | ||
public enum Cmd | ||
{ | ||
Install, Uninstall, Start, Stop, Help, Run | ||
}; | ||
|
||
static int Main(string[] args) | ||
{ | ||
if (args.Length == 0) | ||
args = new string[] { "help" }; | ||
|
||
int rc = 0; | ||
|
||
string command = args[0].ToLowerInvariant(); | ||
try | ||
{ | ||
Cmd cmd = (Cmd)Enum.Parse(typeof(Cmd), command, true); | ||
switch(cmd) | ||
{ | ||
case Cmd.Install: rc = Program.HandleInstall(args); break; | ||
case Cmd.Uninstall: rc = Program.HandleUninstall(args); break; | ||
case Cmd.Start: rc = Program.HandleStart(args); break; | ||
case Cmd.Stop: rc = Program.HandleStop(args); break; | ||
case Cmd.Run: rc = Program.HandleRun(args); break; | ||
case Cmd.Help: | ||
default: rc = Program.HandleHelp(null); break; | ||
} | ||
|
||
} | ||
catch(Exception e) | ||
{ | ||
rc = Program.HandleHelp(e.Message); | ||
} | ||
|
||
return rc; | ||
} | ||
|
||
static int HandleInstall(string[] args) | ||
{ | ||
int retval = 0; | ||
|
||
if (args.Length < 3) | ||
throw new ArgumentException("Not enough arguments for 'install' command."); | ||
string serviceName = args[1]; | ||
string externalCommandLine = args[args.Length - 1]; | ||
|
||
try | ||
{ | ||
|
||
Service s = new Service(serviceName); | ||
if (!s.CheckExternalImagePath(externalCommandLine)) | ||
throw new Exception("I do not understand your external program argument."); | ||
s.Install(externalCommandLine); | ||
|
||
Console.WriteLine(string.Format("Successfully installed an AnyService called: {0}", serviceName)); | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.Error.WriteLine("Unable to install service: " + e.Message); | ||
retval = -1; | ||
} | ||
return retval; | ||
} | ||
|
||
static int HandleUninstall(string[] args) | ||
{ | ||
int retval = 0; | ||
|
||
if (args.Length < 2) | ||
throw new ArgumentException("Not enough arguments for 'uninstall' command."); | ||
string serviceName = args[1]; | ||
|
||
try | ||
{ | ||
Service s = new Service(serviceName); | ||
s.Uninstall(); | ||
|
||
Console.WriteLine("Successfully uninstalled an AnyService called: " + serviceName); | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.Error.WriteLine("Unable to uninstall service: " + e.Message); | ||
retval = -1; | ||
} | ||
return retval; | ||
} | ||
|
||
static int HandleRun(string[] args) | ||
{ | ||
int retval = 0; | ||
|
||
if (args.Length < 2) | ||
throw new ArgumentException("Not enough arguments for 'run' command."); | ||
string serviceName = args[1]; | ||
try | ||
{ | ||
|
||
Service s = new Service(serviceName); | ||
s.Run(); | ||
} | ||
catch (Exception e) | ||
{ | ||
Console.Error.WriteLine("Unable to install service: " + e.Message); | ||
retval = -1; | ||
} | ||
return retval; | ||
} | ||
|
||
static int HandleStart(string[] args) | ||
{ | ||
int retval = 0; | ||
|
||
return retval; | ||
} | ||
|
||
static int HandleStop(string[] args) | ||
{ | ||
int retval = 0; | ||
|
||
return retval; | ||
} | ||
|
||
static int HandleHelp(string message) | ||
{ | ||
int retval = 0; | ||
|
||
if (!string.IsNullOrEmpty(message)) | ||
{ | ||
Console.WriteLine("Error handling command: " + message + Environment.NewLine); | ||
retval = 1; | ||
} | ||
Console.WriteLine("AnyService, Copyright © 2010, Sascha Kiefer." + Environment.NewLine); | ||
Console.WriteLine("Usage: AnyService.exe <command> <service name> [options] [file]" + Environment.NewLine); | ||
Console.WriteLine("Command:"); | ||
Console.WriteLine("\tinstall\t\t- Installs an AnyService named <service name> with application [file]"); | ||
Console.WriteLine("\tuninstall\t- Uninstalls an AnyService name <service name>"); | ||
Console.WriteLine("\tstart\t\t- Tries to start an AnyService named <service name>"); | ||
Console.WriteLine("\tstop\t\t- Tries to stop an AnyService named <service name>"); | ||
Console.WriteLine("\thelp\t\t- Displays this help message."); | ||
Console.WriteLine(); | ||
Console.WriteLine("Examples:"); | ||
Console.WriteLine("\tAnyService.exe install MyService c:\\Path\\To\\MyNotYetAService.exe"); | ||
|
||
return retval; | ||
} | ||
} | ||
} |
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,36 @@ | ||
using System.Reflection; | ||
using System.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
// General Information about an assembly is controlled through the following | ||
// set of attributes. Change these attribute values to modify the information | ||
// associated with an assembly. | ||
[assembly: AssemblyTitle("AnyService")] | ||
[assembly: AssemblyDescription("Run anything as a service")] | ||
[assembly: AssemblyConfiguration("")] | ||
[assembly: AssemblyCompany("Sascha Kiefer")] | ||
[assembly: AssemblyProduct("AnyService")] | ||
[assembly: AssemblyCopyright("Copyright © 2010, Sascha Kiefer")] | ||
[assembly: AssemblyTrademark("")] | ||
[assembly: AssemblyCulture("")] | ||
|
||
// Setting ComVisible to false makes the types in this assembly not visible | ||
// to COM components. If you need to access a type in this assembly from | ||
// COM, set the ComVisible attribute to true on that type. | ||
[assembly: ComVisible(false)] | ||
|
||
// The following GUID is for the ID of the typelib if this project is exposed to COM | ||
[assembly: Guid("f3938e67-a846-4d2b-9478-5e85d9b01d10")] | ||
|
||
// Version information for an assembly consists of the following four values: | ||
// | ||
// Major Version | ||
// Minor Version | ||
// Build Number | ||
// Revision | ||
// | ||
// You can specify all the values or you can default the Build and Revision Numbers | ||
// by using the '*' as shown below: | ||
// [assembly: AssemblyVersion("1.0.*")] | ||
[assembly: AssemblyVersion("1.0.*")] | ||
[assembly: AssemblyFileVersion("1.0.0.0")] |
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,122 @@ | ||
using System; | ||
using System.IO; | ||
using System.ComponentModel; | ||
using System.Diagnostics; | ||
using System.Threading; | ||
|
||
using AnyService.Win32; | ||
|
||
namespace AnyService | ||
{ | ||
public class Service : Win32.WinService | ||
{ | ||
private RegistryHelper m_registry = null; | ||
private Process m_externalProgram = null; | ||
|
||
public Service(string name) | ||
: base(name) | ||
{ | ||
m_registry = new RegistryHelper(Microsoft.Win32.Registry.LocalMachine, @"SYSTEM\CurrentControlSet\Services\" + name); | ||
} | ||
|
||
public string ExternalImagePath | ||
{ | ||
get { return m_registry.LoadString("ExternalImagePath", "", true); } | ||
set | ||
{ | ||
if (value == null) value = ""; | ||
value = value.Replace('\'', '"'); | ||
m_registry.SaveString("ExternalImagePath", value, true); | ||
} | ||
} | ||
|
||
public bool CheckExternalImagePath(string externalImagePath) | ||
{ | ||
string t1, t2; | ||
return this.CheckExternalImagePath(externalImagePath, out t1, out t2); | ||
} | ||
|
||
private bool CheckExternalImagePath(string externalImagePath, out string imagePath, out string arguments) | ||
{ | ||
bool retval = false; | ||
imagePath = arguments = null; | ||
|
||
int pos = externalImagePath.IndexOf(".exe", StringComparison.InvariantCultureIgnoreCase); | ||
if (pos > 0) | ||
{ | ||
imagePath = externalImagePath.Substring(0, pos + 4); | ||
arguments = externalImagePath.Substring(pos + 4).Trim(); | ||
retval = true; | ||
} | ||
|
||
return retval; | ||
} | ||
|
||
protected override void OnStart(string[] args) | ||
{ | ||
string externalImagePath = this.ExternalImagePath; | ||
// cleanup and devide into imagepath and arguments | ||
string imagePath = null, arguments = null; | ||
if (this.CheckExternalImagePath(this.ExternalImagePath, out imagePath, out arguments)) | ||
{ | ||
ProcessStartInfo psi = new ProcessStartInfo(imagePath, arguments); | ||
psi.WorkingDirectory = Path.GetDirectoryName(imagePath); | ||
|
||
m_externalProgram = new Process(); | ||
m_externalProgram.Exited += new EventHandler(HandleProcessExited); | ||
m_externalProgram.StartInfo = psi; | ||
if(m_externalProgram.Start()) | ||
base.OnStart(args); | ||
} | ||
} | ||
|
||
protected override void OnStop() | ||
{ | ||
if (m_externalProgram != null) | ||
{ | ||
m_externalProgram.Exited -= new EventHandler(HandleProcessExited); | ||
|
||
int count = 4; | ||
while (count < 8) | ||
{ | ||
try { m_externalProgram.Kill(); break; } | ||
catch (Win32Exception) { count++; Thread.Sleep(count * 50); } | ||
catch { break; } | ||
} | ||
m_externalProgram.Close(); | ||
m_externalProgram = null; | ||
} | ||
|
||
base.OnStop(); | ||
} | ||
|
||
private void HandleProcessExited(object sender, EventArgs e) | ||
{ | ||
// External Program died or stopped | ||
// so exit as well | ||
int exitCode = -1; | ||
try { exitCode = m_externalProgram.ExitCode; } | ||
catch { } | ||
Environment.Exit(exitCode); | ||
} | ||
|
||
protected override void Dispose(bool disposing) | ||
{ | ||
if (disposing) | ||
{ | ||
if (m_registry != null) | ||
{ | ||
m_registry.Dispose(); | ||
m_registry = null; | ||
} | ||
} | ||
base.Dispose(disposing); | ||
} | ||
|
||
public void Install(string externalCommandLine) | ||
{ | ||
this.Install(false); | ||
this.ExternalImagePath = externalCommandLine; | ||
} | ||
} | ||
} |
Oops, something went wrong.