Merge branch 'master' into winsw-2.0

Conflicts:
	src/Core/ServiceWrapper/Main.cs
	src/Test/winswTests/winswTests.csproj

Signed-off-by: Oleg Nenashev <o.v.nenashev@gmail.com>
pull/71/head
Oleg Nenashev 2015-02-08 13:44:30 +03:00
commit 4a2249d30c
12 changed files with 397 additions and 36 deletions

View File

@ -171,6 +171,9 @@ Long human-readable description of the service. This gets displayed in Windows s
### executable ### executable
This element specifies the executable to be launched. It can be either absolute path, or you can just specify the executable name and let it be searched from `PATH` (although note that the services often run in a different user account and therefore it might have different `PATH` than your shell does.) This element specifies the executable to be launched. It can be either absolute path, or you can just specify the executable name and let it be searched from `PATH` (although note that the services often run in a different user account and therefore it might have different `PATH` than your shell does.)
### startmode - Optional Element
This element specifies the start mode of the Windows service. It can be one of the following values: Boot, System, Automatic, or Manual. See [MSDN](https://msdn.microsoft.com/en-us/library/aa384896%28v=vs.85%29.aspx) for details. The default is Automatic.
### depend ### depend
Specify IDs of other services that this service depends on. When service X depends on service Y, X can only run if Y is running. Specify IDs of other services that this service depends on. When service X depends on service Y, X can only run if Y is running.
@ -305,6 +308,17 @@ Optionally specify the order of service shutdown. If true, the parent process is
Developer info Developer info
---------------------- ----------------------
### Project status
* WinSW 1.x - Maintenance only
* [winsw-1.17] fixes the most of active issues
* [winsw-1.17-beta.2] is available for the evaluation
* New versions may be released on-demand
* All new fixes will be ported to WinSW-2.x
* WinSW 2.x - Active development, no stable releases available
* [winsw-2.0] - Current development branch
* API stability is not guaranteed till the first release, the project structure is in flux
### Build Environment ### Build Environment
* IDE: [Visual Studio Community 2013][MVS2013] (free for open-source projects) * IDE: [Visual Studio Community 2013][MVS2013] (free for open-source projects)
@ -313,3 +327,6 @@ Developer info
* The certificate is in <code>.gitignore</code> list. Please do not add it to the repository * The certificate is in <code>.gitignore</code> list. Please do not add it to the repository
[MVS2013]: http://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx [MVS2013]: http://www.visualstudio.com/en-us/news/vs2013-community-vs.aspx
[winsw-1.17]: https://github.com/kohsuke/winsw/milestones/winsw-1.17
[winsw-1.17-beta.2]: https://github.com/kohsuke/winsw/releases/tag/1.17-beta.2
[WinSW-2.0]: https://github.com/kohsuke/winsw/milestones/winsw-2.0

View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<repositories>
<repository path="..\Tests\winswTests\packages.config" />
</repositories>

View File

@ -16,6 +16,7 @@ using log4net.Repository.Hierarchy;
using Microsoft.Win32; using Microsoft.Win32;
using WMI; using WMI;
using ServiceType = WMI.ServiceType; using ServiceType = WMI.ServiceType;
using System.Reflection;
namespace winsw namespace winsw
{ {
@ -36,9 +37,20 @@ namespace winsw
private bool _orderlyShutdown; private bool _orderlyShutdown;
private bool _systemShuttingdown; private bool _systemShuttingdown;
public WrapperService() /// <summary>
/// Version of Windows service wrapper
/// </summary>
/// <remarks>
/// The version will be taken from <see cref="AssemblyInfo"/>
/// </remarks>
public static Version Version
{ {
_descriptor = new ServiceDescriptor(); get { return Assembly.GetExecutingAssembly().GetName().Version; }
}
public WrapperService(ServiceDescriptor descriptor)
{
_descriptor = descriptor;
ServiceName = _descriptor.Id; ServiceName = _descriptor.Id;
CanShutdown = true; CanShutdown = true;
CanStop = true; CanStop = true;
@ -47,6 +59,10 @@ namespace winsw
_systemShuttingdown = false; _systemShuttingdown = false;
} }
public WrapperService() : this (new ServiceDescriptor())
{
}
/// <summary> /// <summary>
/// Process the file copy instructions, so that we can replace files that are always in use while /// Process the file copy instructions, so that we can replace files that are always in use while
/// the service runs. /// the service runs.
@ -517,17 +533,17 @@ namespace winsw
} }
// ReSharper disable once InconsistentNaming // ReSharper disable once InconsistentNaming
public static void Run(string[] _args) public static void Run(string[] _args, ServiceDescriptor descriptor = null)
{ {
bool isCLIMode = _args.Length > 0; bool isCLIMode = _args.Length > 0;
var d = new ServiceDescriptor(); var d = descriptor ?? new ServiceDescriptor();
// Configure the wrapper-internal logging // Configure the wrapper-internal logging
// STDIN and STDOUT of the child process will be handled independently // STDIN and STDOUT of the child process will be handled independently
InitLoggers(d, isCLIMode); InitLoggers(d, isCLIMode);
if (isCLIMode) // CLI mode if (isCLIMode) // CLI mode
{ {
Log.Debug("Starting ServiceWrapper in CLI mode"); Log.Debug("Starting ServiceWrapper in CLI mode");
// Get service info for the future use // Get service info for the future use
@ -560,6 +576,14 @@ namespace winsw
args[0] = args[0].ToLower(); args[0] = args[0].ToLower();
if (args[0] == "install") if (args[0] == "install")
{ {
// Check if the service exists
if (s != null)
{
Console.WriteLine("Service with id '" + d.Id + "' already exists");
Console.WriteLine("To install the service, delete the existing one or change service Id in the configuration file");
throw new Exception("Installation failure: Service with id '" + d.Id + "' already exists");
}
string username=null, password=null; string username=null, password=null;
bool setallowlogonasaserviceright = false; bool setallowlogonasaserviceright = false;
if (args.Count > 1 && args[1] == "/p") if (args.Count > 1 && args[1] == "/p")
@ -599,7 +623,7 @@ namespace winsw
"\"" + d.ExecutablePath + "\"", "\"" + d.ExecutablePath + "\"",
ServiceType.OwnProcess, ServiceType.OwnProcess,
ErrorControl.UserNotified, ErrorControl.UserNotified,
StartMode.Automatic, d.StartMode,
d.Interactive, d.Interactive,
username, username,
password, password,
@ -627,11 +651,15 @@ namespace winsw
} }
} }
} }
return;
} }
if (args[0] == "uninstall") if (args[0] == "uninstall")
{ {
if (s == null) if (s == null)
{
Console.WriteLine("Warning! The service with id '" + d.Id + "' does not exist. Nothing to uninstall");
return; // there's no such service, so consider it already uninstalled return; // there's no such service, so consider it already uninstalled
}
try try
{ {
s.Delete(); s.Delete();
@ -642,16 +670,19 @@ namespace winsw
return; // it's already uninstalled, so consider it a success return; // it's already uninstalled, so consider it a success
throw e; throw e;
} }
return;
} }
if (args[0] == "start") if (args[0] == "start")
{ {
if (s == null) ThrowNoSuchService(); if (s == null) ThrowNoSuchService();
s.StartService(); s.StartService();
return;
} }
if (args[0] == "stop") if (args[0] == "stop")
{ {
if (s == null) ThrowNoSuchService(); if (s == null) ThrowNoSuchService();
s.StopService(); s.StopService();
return;
} }
if (args[0] == "restart") if (args[0] == "restart")
{ {
@ -668,6 +699,7 @@ namespace winsw
} }
s.StartService(); s.StartService();
return;
} }
if (args[0] == "restart!") if (args[0] == "restart!")
{ {
@ -681,6 +713,7 @@ namespace winsw
{ {
throw new Exception("Failed to invoke restart: "+Marshal.GetLastWin32Error()); throw new Exception("Failed to invoke restart: "+Marshal.GetLastWin32Error());
} }
return;
} }
if (args[0] == "status") if (args[0] == "status")
{ {
@ -691,6 +724,7 @@ namespace winsw
Console.WriteLine("Started"); Console.WriteLine("Started");
else else
Console.WriteLine("Stopped"); Console.WriteLine("Stopped");
return;
} }
if (args[0] == "test") if (args[0] == "test")
{ {
@ -698,8 +732,24 @@ namespace winsw
wsvc.OnStart(args.ToArray()); wsvc.OnStart(args.ToArray());
Thread.Sleep(1000); Thread.Sleep(1000);
wsvc.OnStop(); wsvc.OnStop();
return;
} }
return; if (args[0] == "help" || args[0] == "--help" || args[0] == "-h"
|| args[0] == "-?" || args[0] == "/?")
{
printHelp();
return;
}
if (args[0] == "version")
{
printVersion();
return;
}
Console.WriteLine("Unknown command: " + args[0]);
printAvailableCommandsInfo();
throw new Exception("Unknown command: " + args[0]);
} }
Run(new WrapperService()); Run(new WrapperService());
} }
@ -764,5 +814,43 @@ namespace winsw
} }
} }
} }
private static void printHelp()
{
Console.WriteLine("A wrapper binary that can be used to host executables as Windows services");
Console.WriteLine("");
Console.WriteLine("Usage: winsw [/redirect file] <command> [<args>]");
Console.WriteLine(" Missing arguments trigger the service mode");
Console.WriteLine("");
printAvailableCommandsInfo();
Console.WriteLine("");
Console.WriteLine("Extra options:");
Console.WriteLine("- '/redirect' - redirect the wrapper's STDOUT and STDERR to the specified file");
Console.WriteLine("");
printVersion();
Console.WriteLine("More info: https://github.com/kohsuke/winsw");
Console.WriteLine("Bug tracker: https://github.com/kohsuke/winsw/issues");
}
//TODO: Rework to enum in winsw-2.0
private static void printAvailableCommandsInfo()
{
Console.WriteLine("Available commands:");
Console.WriteLine("- 'install' - install the service to Windows Service Controller");
Console.WriteLine("- 'uninstall' - uninstall the service");
Console.WriteLine("- 'start' - start the service (must be installed before)");
Console.WriteLine("- 'stop' - stop the service");
Console.WriteLine("- 'restart' - restart the service");
Console.WriteLine("- 'restart!' - self-restart (can be called from child processes)");
Console.WriteLine("- 'status' - check the current status of the service");
Console.WriteLine("- 'test' - check if the service can be started and then stopped");
Console.WriteLine("- 'version' - print the version info");
Console.WriteLine("- 'help' - print the help info (aliases: -h,--help,-?,/?)");
}
private static void printVersion()
{
Console.WriteLine("WinSW " + Version);
}
} }
} }

View File

@ -28,5 +28,5 @@ using System.Runtime.InteropServices;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.1.0.0")] [assembly: AssemblyVersion("1.17.0.0")]
[assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyFileVersion("1.17.0.0")]

View File

@ -5,6 +5,7 @@ using System.Diagnostics;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Xml; using System.Xml;
using WMI;
namespace winsw namespace winsw
{ {
@ -36,8 +37,7 @@ namespace winsw
// this returns the executable name as given by the calling process, so // this returns the executable name as given by the calling process, so
// it needs to be absolutized. // it needs to be absolutized.
string p = Environment.GetCommandLineArgs()[0]; string p = Environment.GetCommandLineArgs()[0];
return Path.Combine(AppDomain.CurrentDomain.BaseDirectory, p); return Path.GetFullPath(p);
} }
} }
@ -45,18 +45,24 @@ namespace winsw
{ {
// find co-located configuration xml. We search up to the ancestor directories to simplify debugging, // find co-located configuration xml. We search up to the ancestor directories to simplify debugging,
// as well as trimming off ".vshost" suffix (which is used during debugging) // as well as trimming off ".vshost" suffix (which is used during debugging)
//Get the first parent to go into the recursive loop
string p = ExecutablePath; string p = ExecutablePath;
string baseName = Path.GetFileNameWithoutExtension(p); string baseName = Path.GetFileNameWithoutExtension(p);
if (baseName.EndsWith(".vshost")) baseName = baseName.Substring(0, baseName.Length - 7); if (baseName.EndsWith(".vshost")) baseName = baseName.Substring(0, baseName.Length - 7);
DirectoryInfo d = new DirectoryInfo(Path.GetDirectoryName(p));
while (true) while (true)
{ {
p = Path.GetDirectoryName(p); if (File.Exists(Path.Combine(d.FullName, baseName + ".xml")))
if (File.Exists(Path.Combine(p, baseName + ".xml")))
break; break;
if (d.Parent == null)
throw new FileNotFoundException("Unable to locate "+baseName+".xml file within executable directory or any parents");
d = d.Parent;
} }
BaseName = baseName; BaseName = baseName;
BasePath = Path.Combine(p, BaseName); BasePath = Path.Combine(d.FullName, BaseName);
dom.Load(BasePath + ".xml"); dom.Load(BasePath + ".xml");
@ -393,6 +399,31 @@ namespace winsw
} }
} }
/// <summary>
/// Start mode of the Service
/// </summary>
public StartMode StartMode
{
get
{
var p = SingleElement("startmode", true);
if (p == null) return StartMode.Automatic; // default value
try
{
return (StartMode)Enum.Parse(typeof(StartMode), p, true);
}
catch
{
Console.WriteLine("Start mode in XML must be one of the following:");
foreach (string sm in Enum.GetNames(typeof(StartMode)))
{
Console.WriteLine(sm);
}
throw;
}
}
}
/// <summary> /// <summary>
/// True if the service should when finished on shutdown. /// True if the service should when finished on shutdown.
/// This doesn't work on some OSes. See http://msdn.microsoft.com/en-us/library/ms679277%28VS.85%29.aspx /// This doesn't work on some OSes. See http://msdn.microsoft.com/en-us/library/ms679277%28VS.85%29.aspx

View File

@ -45,7 +45,7 @@
<DebugType>full</DebugType> <DebugType>full</DebugType>
<Optimize>false</Optimize> <Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath> <OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants> <DefineConstants>TRACE;DEBUG</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
@ -58,6 +58,8 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks> <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="log4net"> <Reference Include="log4net">

View File

@ -0,0 +1,48 @@
using NUnit.Framework;
using winsw;
using winswTests.Util;
namespace winswTests
{
[TestFixture]
class MainTest
{
[Test]
public void PrintVersion()
{
string expectedVersion = WrapperService.Version.ToString();
string cliOut = CLITestHelper.CLITest(new[] { "version" });
StringAssert.Contains(expectedVersion, cliOut, "Expected that version contains " + expectedVersion);
}
[Test]
public void PrintHelp()
{
string expectedVersion = WrapperService.Version.ToString();
string cliOut = CLITestHelper.CLITest(new[] { "help" });
StringAssert.Contains(expectedVersion, cliOut, "Expected that help contains " + expectedVersion);
StringAssert.Contains("start", cliOut, "Expected that help refers start command");
StringAssert.Contains("help", cliOut, "Expected that help refers help command");
StringAssert.Contains("version", cliOut, "Expected that help refers version command");
//TODO: check all commands after the migration of ccommands to enum
// Extra options
StringAssert.Contains("/redirect", cliOut, "Expected that help message refers the redirect message");
}
[Test]
public void FailOnUnsupportedCommand()
{
const string commandName = "nonExistentCommand";
string expectedMessage = "Unknown command: " + commandName.ToLower();
CLITestResult res = CLITestHelper.CLIErrorTest(new[] {commandName});
Assert.True(res.HasException, "Expected an exception due to the wrong command");
StringAssert.Contains(expectedMessage, res.Out, "Expected the message about unknown command");
// ReSharper disable once PossibleNullReferenceException
StringAssert.Contains(expectedMessage, res.Exception.Message, "Expected the message about unknown command");
}
}
}

View File

@ -5,6 +5,9 @@ using winsw;
namespace winswTests namespace winswTests
{ {
using System;
using WMI;
[TestFixture] [TestFixture]
public class ServiceDescriptorTests public class ServiceDescriptorTests
{ {
@ -41,6 +44,66 @@ namespace winswTests
_extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml); _extendedServiceDescriptor = ServiceDescriptor.FromXML(seedXml);
} }
[Test]
public void DefaultStartMode()
{
Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Automatic));
}
[Test]
[ExpectedException(typeof(System.ArgumentException))]
public void IncorrectStartMode()
{
const string SeedXml = "<service>"
+ "<id>service.exe</id>"
+ "<name>Service</name>"
+ "<description>The service.</description>"
+ "<executable>node.exe</executable>"
+ "<arguments>My Arguments</arguments>"
+ "<startmode>rotate</startmode>"
+ "<logmode>rotate</logmode>"
+ "<serviceaccount>"
+ "<domain>" + Domain + "</domain>"
+ "<user>" + Username + "</user>"
+ "<password>" + Password + "</password>"
+ "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
+ "</serviceaccount>"
+ "<workingdirectory>"
+ ExpectedWorkingDirectory
+ "</workingdirectory>"
+ @"<logpath>C:\logs</logpath>"
+ "</service>";
_extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual));
}
[Test]
public void ChangedStartMode()
{
const string SeedXml = "<service>"
+ "<id>service.exe</id>"
+ "<name>Service</name>"
+ "<description>The service.</description>"
+ "<executable>node.exe</executable>"
+ "<arguments>My Arguments</arguments>"
+ "<startmode>manual</startmode>"
+ "<logmode>rotate</logmode>"
+ "<serviceaccount>"
+ "<domain>" + Domain + "</domain>"
+ "<user>" + Username + "</user>"
+ "<password>" + Password + "</password>"
+ "<allowservicelogon>" + AllowServiceAccountLogonRight + "</allowservicelogon>"
+ "</serviceaccount>"
+ "<workingdirectory>"
+ ExpectedWorkingDirectory
+ "</workingdirectory>"
+ @"<logpath>C:\logs</logpath>"
+ "</service>";
_extendedServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
Assert.That(_extendedServiceDescriptor.StartMode, Is.EqualTo(StartMode.Manual));
}
[Test] [Test]
public void VerifyWorkingDirectory() public void VerifyWorkingDirectory()
{ {

View File

@ -0,0 +1,116 @@
using System;
using System.IO;
using JetBrains.Annotations;
using winsw;
namespace winswTests.Util
{
/// <summary>
/// Helper for WinSW CLI testing
/// </summary>
public static class CLITestHelper
{
private const string SeedXml = "<service>"
+ "<id>service.exe</id>"
+ "<name>Service</name>"
+ "<description>The service.</description>"
+ "<executable>node.exe</executable>"
+ "<arguments>My Arguments</arguments>"
+ "<logmode>rotate</logmode>"
+ "<workingdirectory>"
+ @"C:\winsw\workdir"
+ "</workingdirectory>"
+ @"<logpath>C:\winsw\logs</logpath>"
+ "</service>";
private static readonly ServiceDescriptor DefaultServiceDescriptor = ServiceDescriptor.FromXML(SeedXml);
/// <summary>
/// Runs a simle test, which returns the output CLI
/// </summary>
/// <param name="args">CLI arguments to be passed</param>
/// <param name="descriptor">Optional Service descriptor (will be used for initializationpurposes)</param>
/// <returns>STDOUT if there's no exceptions</returns>
/// <exception cref="Exception">Command failure</exception>
[NotNull]
public static string CLITest(String[] args, ServiceDescriptor descriptor = null)
{
using (StringWriter sw = new StringWriter())
{
TextWriter tmp = Console.Out;
Console.SetOut(sw);
WrapperService.Run(args, descriptor ?? DefaultServiceDescriptor);
Console.SetOut(tmp);
Console.Write(sw.ToString());
return sw.ToString();
}
}
/// <summary>
/// Runs a simle test, which returns the output CLI
/// </summary>
/// <param name="args">CLI arguments to be passed</param>
/// <param name="descriptor">Optional Service descriptor (will be used for initializationpurposes)</param>
/// <returns>Test results</returns>
[NotNull]
public static CLITestResult CLIErrorTest(String[] args, ServiceDescriptor descriptor = null)
{
StringWriter swOut, swErr;
Exception testEx = null;
TextWriter tmpOut = Console.Out;
TextWriter tmpErr = Console.Error;
using (swOut = new StringWriter())
using (swErr = new StringWriter())
try
{
Console.SetOut(swOut);
Console.SetError(swErr);
WrapperService.Run(args, descriptor ?? DefaultServiceDescriptor);
}
catch (Exception ex)
{
testEx = ex;
}
finally
{
Console.SetOut(tmpOut);
Console.SetError(tmpErr);
Console.WriteLine("\n>>> Output: ");
Console.Write(swOut.ToString());
Console.WriteLine("\n>>> Error: ");
Console.Write(swErr.ToString());
if (testEx != null)
{
Console.WriteLine("\n>>> Exception: ");
Console.WriteLine(testEx);
}
}
return new CLITestResult(swOut.ToString(), swErr.ToString(), testEx);
}
}
/// <summary>
/// Aggregated test report
/// </summary>
public class CLITestResult
{
[NotNull]
public String Out { get; private set; }
[NotNull]
public String Err { get; private set; }
[CanBeNull]
public Exception Exception { get; private set; }
public bool HasException { get { return Exception != null; } }
public CLITestResult(String output, String err, Exception exception = null)
{
Out = output;
Err = err;
Exception = exception;
}
}
}

View File

@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="NUnit" version="2.6.4" targetFramework="net20" /> <package id="NUnit" version="2.6.4" targetFramework="net20" />
<package id="JetBrains.Annotations" version="8.0.5.0" targetFramework="net20" />
</packages> </packages>

View File

@ -37,18 +37,25 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="JetBrains.Annotations, Version=8.0.5.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\JetBrains.Annotations.8.0.5.0\lib\net20\JetBrains.Annotations.dll</HintPath>
</Reference>
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL"> <Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath> <HintPath>..\..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="MainTest.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="ServiceDescriptorTests.cs" /> <Compile Include="ServiceDescriptorTests.cs" />
<Compile Include="Util\CLITestHelper.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Core\ServiceWrapper\winsw.csproj"> <ProjectReference Include="..\..\Core\ServiceWrapper\winsw.csproj">

View File

@ -16,34 +16,18 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{6BDF40
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|Mixed Platforms = Debug|Mixed Platforms
Debug|Win32 = Debug|Win32 Debug|Win32 = Debug|Win32
Release|Any CPU = Release|Any CPU
Release|Mixed Platforms = Release|Mixed Platforms
Release|Win32 = Release|Win32 Release|Win32 = Release|Win32
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Mixed Platforms.ActiveCfg = Release|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Mixed Platforms.Build.0 = Release|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Win32.ActiveCfg = Debug|Any CPU {0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Win32.ActiveCfg = Debug|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Any CPU.ActiveCfg = Release|Any CPU {0DE77F55-ADE5-43C1-999A-0BC81153B039}.Debug|Win32.Build.0 = Debug|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Any CPU.Build.0 = Release|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Win32.ActiveCfg = Release|Any CPU {0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Win32.ActiveCfg = Release|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {0DE77F55-ADE5-43C1-999A-0BC81153B039}.Release|Win32.Build.0 = Release|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Any CPU.Build.0 = Debug|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Win32.ActiveCfg = Debug|Any CPU {93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Win32.ActiveCfg = Debug|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Release|Any CPU.ActiveCfg = Release|Any CPU {93843402-842B-44B4-B303-AEE829BE0B43}.Debug|Win32.Build.0 = Debug|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Release|Any CPU.Build.0 = Release|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Release|Win32.ActiveCfg = Release|Any CPU {93843402-842B-44B4-B303-AEE829BE0B43}.Release|Win32.ActiveCfg = Release|Any CPU
{93843402-842B-44B4-B303-AEE829BE0B43}.Release|Win32.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE