Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merged Dru's OS changes

  • Loading branch information...
commit 045414efa0c8a7cfea544b9cfc37adbbe3266e9f 2 parents 3976163 + e7dd482
Chris Patterson authored
Showing with 213 additions and 24 deletions.
  1. +1 −1  README.md
  2. +8 −3 src/Topshelf/Config/Builders/RunBuilder.cs
  3. +10 −1 src/Topshelf/Config/CommandLineConfigurator.cs
  4. +3 −0  src/Topshelf/Config/HostConfigurators/RunAsHostConfigurator.cs
  5. +20 −0 src/Topshelf/Config/Options/DisplayNameOption.cs
  6. +13 −0 src/Topshelf/Config/Options/InteractiveOption.cs
  7. +20 −0 src/Topshelf/Config/Options/ServiceDescriptionOption.cs
  8. +20 −0 src/Topshelf/Config/Options/ServiceNameOption.cs
  9. +12 −0 src/Topshelf/Config/RunAsExtensions.cs
  10. +10 −1 src/Topshelf/HelpText.txt
  11. +6 −0 src/Topshelf/Hosts/AbstractInstallerHost.cs
  12. +11 −10 src/Topshelf/Hosts/ConsoleRunHost.cs
  13. +0 −1  src/Topshelf/Hosts/HelpHost.cs
  14. +64 −0 src/Topshelf/OS/OsDetector.cs
  15. 0  src/Topshelf/{ → OS}/Windows/ServiceRecoveryAction.cs
  16. 0  src/Topshelf/{ → OS}/Windows/ServiceRecoveryOptions.cs
  17. 0  src/Topshelf/{ → OS}/Windows/WindowsServiceControlManager.cs
  18. 0  src/Topshelf/{ → OS}/Windows/WindowsServiceHost.cs
  19. 0  src/Topshelf/{ → OS}/Windows/WindowsUserAccessControl.cs
  20. 0  src/Topshelf/{ → OS}/WindowsServiceCode/HostInstaller.cs
  21. 0  src/Topshelf/{ → OS}/WindowsServiceCode/Kernel32.cs
  22. +15 −7 src/Topshelf/Topshelf.csproj
View
2  README.md
@@ -53,7 +53,7 @@ Get started in four simple steps!
1. Clone the source down to your machine.
`git clone git://github.com/Topshelf/Topshelf.git`
2. Download git, ruby and gems. Install – a tutorial is [here][gems]
- 3. Install albacore. Run "gem install albacore"
+ 3. gem install rake albacore
4. **Important:** Run `rake global_version` in order to generate the SolutionVersion.cs file which is otherwise missing.
* You must have git on the path in order to do this. (Right click on `Computer` > `Advanced System Settings`, `Advanced` (tab) > `Environment Variables...` > Append the git executable's directory at the end of the PATH environment variable.
5. Edit with Visual Studio 2010 or alternatively edit and run `rake`. `rake help` displays all possible tasks that you can run. The `package` task, is what the build server does.
View
11 src/Topshelf/Config/Builders/RunBuilder.cs
@@ -21,6 +21,7 @@ namespace Topshelf.Builders
using log4net;
using Magnum.Extensions;
using Model;
+ using OS;
using Stact;
using Windows;
@@ -68,7 +69,11 @@ public virtual Host Build()
_serviceBuilders.Each(x => { _coordinator.CreateService(x.Name, x.Build); });
- return CreateHost(_coordinator);
+ //TODO: feels like it should be a builder
+ var osCommands = OsDetector.DetectOs();
+
+
+ return CreateHost(_coordinator, osCommands);
}
public void Match<T>([NotNull] Action<T> callback)
@@ -81,7 +86,7 @@ public void Match<T>([NotNull] Action<T> callback)
callback(this as T);
}
- Host CreateHost(IServiceCoordinator coordinator)
+ Host CreateHost(IServiceCoordinator coordinator, Os osCommands)
{
var process = Process.GetCurrentProcess().GetParent();
if (process != null && process.ProcessName == "services")
@@ -92,7 +97,7 @@ Host CreateHost(IServiceCoordinator coordinator)
}
_log.Debug("Running as a console application, using the console host");
- return new ConsoleRunHost(_description, coordinator);
+ return new ConsoleRunHost(_description, coordinator, osCommands);
}
public void AddServiceBuilder(ServiceBuilder serviceBuilder)
View
11 src/Topshelf/Config/CommandLineConfigurator.cs
@@ -12,7 +12,8 @@
// specific language governing permissions and limitations under the License.
namespace Topshelf
{
- using HostConfigurators;
+ using System;
+ using HostConfigurators;
using Magnum.CommandLineParser;
using Magnum.Extensions;
using Magnum.Monads.Parser;
@@ -54,12 +55,20 @@ static void InitializeCommandLineParser(ICommandLineElementParser<Option> x)
select (Option)new ServiceAccountOption(username.Value, password.Value))
.Or(from autostart in x.Switch("autostart")
select (Option)new AutostartOption())
+ .Or(from interactive in x.Switch("interactive")
+ select (Option)new InteractiveOption())
.Or(from autostart in x.Switch("localservice")
select (Option)new LocalServiceOption())
.Or(from autostart in x.Switch("networkservice")
select (Option)new NetworkServiceOption())
.Or(from autostart in x.Switch("help")
select (Option)new HelpOption())
+ .Or(from svcname in x.Definition("servicename")
+ select (Option)new ServiceNameOption(svcname.Value))
+ .Or(from desc in x.Definition("description")
+ select (Option)new ServiceDescriptionOption(desc.Value))
+ .Or(from disp in x.Definition("displayname")
+ select (Option)new DisplayNameOption(disp.Value))
.Or(from instance in x.Definition("instance")
select (Option)new InstanceOption(instance.Value)));
}
View
3  src/Topshelf/Config/HostConfigurators/RunAsHostConfigurator.cs
@@ -48,6 +48,9 @@ public void Validate()
"The service account must be a user account when a username and password are specified");
}
+ if (_username.IsEmpty() && _password.IsEmpty() && _accountType == ServiceAccount.User)
+ return; //interactive
+
if (_accountType == ServiceAccount.User && (_username.IsEmpty() || _password.IsEmpty()))
throw new HostConfigurationException("The username and password must be specified for a user account");
}
View
20 src/Topshelf/Config/Options/DisplayNameOption.cs
@@ -0,0 +1,20 @@
+namespace Topshelf.Options
+{
+ using HostConfigurators;
+
+
+ public class DisplayNameOption : Option
+ {
+ string _name;
+
+ public DisplayNameOption(string name)
+ {
+ _name = name;
+ }
+
+ public void ApplyTo(HostConfigurator configurator)
+ {
+ configurator.SetDisplayName(_name);
+ }
+ }
+}
View
13 src/Topshelf/Config/Options/InteractiveOption.cs
@@ -0,0 +1,13 @@
+namespace Topshelf.Options
+{
+ using HostConfigurators;
+
+
+ public class InteractiveOption : Option
+ {
+ public void ApplyTo(HostConfigurator configurator)
+ {
+ configurator.RunAsPrompt();
+ }
+ }
+}
View
20 src/Topshelf/Config/Options/ServiceDescriptionOption.cs
@@ -0,0 +1,20 @@
+namespace Topshelf.Options
+{
+ using HostConfigurators;
+
+
+ public class ServiceDescriptionOption : Option
+ {
+ string _description;
+
+ public ServiceDescriptionOption(string description)
+ {
+ _description = description;
+ }
+
+ public void ApplyTo(HostConfigurator configurator)
+ {
+ configurator.SetDescription(_description);
+ }
+ }
+}
View
20 src/Topshelf/Config/Options/ServiceNameOption.cs
@@ -0,0 +1,20 @@
+namespace Topshelf.Options
+{
+ using HostConfigurators;
+
+
+ public class ServiceNameOption : Option
+ {
+ string _serviceName;
+
+ public ServiceNameOption(string name)
+ {
+ _serviceName = name;
+ }
+
+ public void ApplyTo(HostConfigurator configurator)
+ {
+ configurator.SetServiceName(_serviceName);
+ }
+ }
+}
View
12 src/Topshelf/Config/RunAsExtensions.cs
@@ -32,6 +32,18 @@ public static HostConfigurator RunAs([NotNull] this HostConfigurator configurato
return configurator;
}
+ public static HostConfigurator RunAsPrompt([NotNull]this HostConfigurator configurator)
+ {
+ if (configurator == null)
+ throw new ArgumentNullException("configurator");
+
+ var runAsConfigurator = new RunAsHostConfigurator(ServiceAccount.User);
+
+ configurator.AddConfigurator(runAsConfigurator);
+
+ return configurator;
+ }
+
public static HostConfigurator RunAsNetworkService([NotNull] this HostConfigurator configurator)
{
if (configurator == null)
View
11 src/Topshelf/HelpText.txt
@@ -16,11 +16,20 @@ Command-Line Reference
-password The password for the specified username
--localservice Run the service with the local service account
--networkservice Run the service with the network service permission
+ --interactive The service will prompt the user at installation for
+ the service credentials
start Start the service after it has been installed
--sudo Prompts for UAC if running on Vista/W7/2008
- start Starts the service if it is not already running
+ -servicename The name that the service should use when
+ installing
+ -description The service description the service should use when
+ installing
+ -displayname The display name the the service should use when
+ installing
+ start Starts the service if it is not already running
+
stop Stops the service if it is running
uninstall Uninstalls the service
View
6 src/Topshelf/Hosts/AbstractInstallerHost.cs
@@ -108,6 +108,12 @@ Installer CreateInstaller()
if (_description.InstanceName.IsNotEmpty())
arguments += " -instance:{0}".FormatWith(_description.InstanceName);
+ if (_description.DisplayName.IsNotEmpty())
+ arguments += " -displayname \"{0}\"".FormatWith(_description.DisplayName);
+
+ if (_description.Name.IsNotEmpty())
+ arguments += " -servicename:{0}".FormatWith(_description.Name);
+
var installer = new HostInstaller(_description, arguments, installers);
return installer;
View
21 src/Topshelf/Hosts/ConsoleRunHost.cs
@@ -21,33 +21,38 @@ namespace Topshelf.Hosts
using Internal;
using log4net;
using Model;
+ using OS;
- public class ConsoleRunHost :
+ public class ConsoleRunHost :
Host, IDisposable
{
readonly ServiceDescription _description;
readonly ILog _log = LogManager.GetLogger("Topshelf.Hosts.ConsoleRunHost");
IServiceCoordinator _coordinator;
ManualResetEvent _exit;
- volatile bool _hasCancelled;
+ volatile bool _hasCancelled;
+ Os _osCommands;
- public ConsoleRunHost([NotNull] ServiceDescription description, [NotNull] IServiceCoordinator coordinator)
+ public ConsoleRunHost([NotNull] ServiceDescription description, [NotNull] IServiceCoordinator coordinator, [NotNull]Os osCommands)
{
if (description == null)
throw new ArgumentNullException("description");
if (coordinator == null)
throw new ArgumentNullException("coordinator");
+ if(osCommands ==null)
+ throw new ArgumentNullException("osCommands");
_description = description;
_coordinator = coordinator;
+ _osCommands = osCommands;
}
public void Run()
{
Directory.SetCurrentDirectory(AppDomain.CurrentDomain.BaseDirectory);
- CheckToSeeIfWinServiceRunning();
+ _osCommands.CheckToSeeIfServiceRunning(_description);
try
{
@@ -115,15 +120,11 @@ void HandleCancelKeyPress(object sender, ConsoleCancelEventArgs consoleCancelEve
_hasCancelled = true;
}
- void CheckToSeeIfWinServiceRunning()
- {
- if (ServiceController.GetServices().Where(s => s.ServiceName == _description.GetServiceName()).Any())
- _log.WarnFormat("There is an instance of this {0} running as a windows service", _description);
- }
+
bool _disposed;
- public void Dispose()
+ public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
View
1  src/Topshelf/Hosts/HelpHost.cs
@@ -43,7 +43,6 @@ public void Run()
using (TextReader reader = new StreamReader(stream))
{
string text = reader.ReadToEnd();
-
Console.WriteLine(text);
}
}
View
64 src/Topshelf/OS/OsDetector.cs
@@ -0,0 +1,64 @@
+namespace Topshelf.OS
+{
+ using System;
+ using System.IO;
+ using System.Linq;
+ using System.ServiceProcess;
+ using log4net;
+
+
+ public static class OsDetector
+ {
+ static ILog _log = LogManager.GetLogger("OsDetector");
+
+ public static Os DetectOs()
+ {
+ Os osCommands = new Nix();
+
+ if (Path.DirectorySeparatorChar == '\\')
+ osCommands = new Windows();
+
+ _log.InfoFormat("Detected the operating system: '{0}'", osCommands.Description);
+ return osCommands;
+ }
+ }
+
+ public class Windows :
+ Os
+ {
+ static ILog _log = LogManager.GetLogger("Windows");
+
+ public string Description
+ {
+ get { return "win"; }
+ }
+
+ public void CheckToSeeIfServiceRunning(ServiceDescription description)
+ {
+ if (ServiceController.GetServices().Where(s => s.ServiceName == description.GetServiceName()).Any())
+ _log.WarnFormat("There is an instance of this {0} running as a windows service", description);
+ }
+ }
+
+ public class Nix :
+ Os
+ {
+ static ILog _log = LogManager.GetLogger("Windows");
+
+ public string Description
+ {
+ get { return "nix"; }
+ }
+
+ public void CheckToSeeIfServiceRunning(ServiceDescription description)
+ {
+ _log.Warn("Nix not detecting, maybe check the pid?");
+ }
+ }
+
+ public interface Os
+ {
+ string Description { get; }
+ void CheckToSeeIfServiceRunning(ServiceDescription description);
+ }
+}
View
0  ...Topshelf/Windows/ServiceRecoveryAction.cs → ...shelf/OS/Windows/ServiceRecoveryAction.cs
File renamed without changes
View
0  ...opshelf/Windows/ServiceRecoveryOptions.cs → ...helf/OS/Windows/ServiceRecoveryOptions.cs
File renamed without changes
View
0  ...f/Windows/WindowsServiceControlManager.cs → ...S/Windows/WindowsServiceControlManager.cs
File renamed without changes
View
0  src/Topshelf/Windows/WindowsServiceHost.cs → ...Topshelf/OS/Windows/WindowsServiceHost.cs
File renamed without changes
View
0  ...shelf/Windows/WindowsUserAccessControl.cs → ...lf/OS/Windows/WindowsUserAccessControl.cs
File renamed without changes
View
0  ...shelf/WindowsServiceCode/HostInstaller.cs → ...lf/OS/WindowsServiceCode/HostInstaller.cs
File renamed without changes
View
0  src/Topshelf/WindowsServiceCode/Kernel32.cs → ...opshelf/OS/WindowsServiceCode/Kernel32.cs
File renamed without changes
View
22 src/Topshelf/Topshelf.csproj
@@ -119,9 +119,13 @@
<Compile Include="Config\HostConfigurators\KnownServiceNames.cs" />
<Compile Include="Config\HostConfigurators\StartConfigurator.cs" />
<Compile Include="Config\HostConfigurators\SudoConfigurator.cs" />
+ <Compile Include="Config\Options\DisplayNameOption.cs" />
<Compile Include="Config\Options\HelpOption.cs" />
+ <Compile Include="Config\Options\InteractiveOption.cs" />
<Compile Include="Config\Options\LocalServiceOption.cs" />
<Compile Include="Config\Options\NetworkServiceOption.cs" />
+ <Compile Include="Config\Options\ServiceDescriptionOption.cs" />
+ <Compile Include="Config\Options\ServiceNameOption.cs" />
<Compile Include="Config\Options\StartOption.cs" />
<Compile Include="Config\Options\StopOption.cs" />
<Compile Include="Config\Options\SudoOption.cs" />
@@ -231,25 +235,26 @@
<Compile Include="Model\PublishChannel.cs" />
<Compile Include="Messages\ServiceInfo.cs" />
<Compile Include="Messages\ServiceStatus.cs" />
+ <Compile Include="OS\OsDetector.cs" />
<Compile Include="Shelving\ShelfConfiguration.cs" />
<Compile Include="Model\ShelfReference.cs" />
<Compile Include="Model\ShelfServiceController.cs" />
<Compile Include="Model\ShelfType.cs" />
<Compile Include="Internal\ReSharperStaticAnalysis.cs" />
- <Compile Include="Windows\WindowsUserAccessControl.cs" />
- <Compile Include="WindowsServiceCode\HostInstaller.cs">
+ <Compile Include="OS\Windows\WindowsUserAccessControl.cs" />
+ <Compile Include="OS\WindowsServiceCode\HostInstaller.cs">
<SubType>Component</SubType>
</Compile>
- <Compile Include="Windows\ServiceRecoveryAction.cs" />
- <Compile Include="Windows\ServiceRecoveryOptions.cs" />
- <Compile Include="Windows\WindowsServiceControlManager.cs" />
+ <Compile Include="OS\Windows\ServiceRecoveryAction.cs" />
+ <Compile Include="OS\Windows\ServiceRecoveryOptions.cs" />
+ <Compile Include="OS\Windows\WindowsServiceControlManager.cs" />
<Compile Include="Exceptions\BuildServiceException.cs" />
<Compile Include="Hosts\ConsoleRunHost.cs" />
<Compile Include="Host.cs" />
- <Compile Include="Windows\WindowsServiceHost.cs">
+ <Compile Include="OS\Windows\WindowsServiceHost.cs">
<SubType>Component</SubType>
</Compile>
- <Compile Include="WindowsServiceCode\Kernel32.cs" />
+ <Compile Include="OS\WindowsServiceCode\Kernel32.cs" />
<Compile Include="Model\ServiceFactory.cs" />
<Compile Include="Extensions\ProcessExtensions.cs" />
<Compile Include="Shelving\Bootstrapper.cs" />
@@ -301,6 +306,9 @@
<EmbeddedResource Include="Dashboard\images\control_play.png" />
<EmbeddedResource Include="Dashboard\images\control_stop.png" />
</ItemGroup>
+ <ItemGroup>
+ <Folder Include="OS\Osx\" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
Please sign in to comment.
Something went wrong with that request. Please try again.