Moved P/Invoke wrappers to other files

pull/37/merge
Kohsuke Kawaguchi 2014-04-01 14:27:34 -07:00
parent 2beae94c3f
commit e8036488c8
5 changed files with 95 additions and 79 deletions

View File

@ -4,7 +4,7 @@ using System.Text;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.ComponentModel; using System.ComponentModel;
namespace Advapi32 namespace winsw
{ {
class ServiceManager : IDisposable class ServiceManager : IDisposable
{ {
@ -104,6 +104,9 @@ namespace Advapi32
[DllImport("advapi32.dll", SetLastError = true)] [DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)] [return: MarshalAs(UnmanagedType.Bool)]
internal static extern bool CloseServiceHandle(IntPtr hSCObject); internal static extern bool CloseServiceHandle(IntPtr hSCObject);
[DllImport("ADVAPI32.DLL")]
internal static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
} }
@ -245,6 +248,29 @@ namespace Advapi32
WINSTA_ALL_ACCESS = 0x0000037f WINSTA_ALL_ACCESS = 0x0000037f
} }
public struct SERVICE_STATUS
{
public int serviceType;
public int currentState;
public int controlsAccepted;
public int win32ExitCode;
public int serviceSpecificExitCode;
public int checkPoint;
public int waitHint;
}
public enum State
{
SERVICE_STOPPED = 0x00000001,
SERVICE_START_PENDING = 0x00000002,
SERVICE_STOP_PENDING = 0x00000003,
SERVICE_RUNNING = 0x00000004,
SERVICE_CONTINUE_PENDING = 0x00000005,
SERVICE_PAUSE_PENDING = 0x00000006,
SERVICE_PAUSED = 0x00000007,
}
// http://msdn.microsoft.com/en-us/library/windows/desktop/ms685126(v=vs.85).aspx // http://msdn.microsoft.com/en-us/library/windows/desktop/ms685126(v=vs.85).aspx
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public struct SC_ACTION public struct SC_ACTION

57
Kernel32.cs Executable file
View File

@ -0,0 +1,57 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace winsw
{
/// <summary>
/// kernel32.dll P/Invoke wrappers
/// </summary>
internal class Kernel32
{
[DllImport("Kernel32.dll", SetLastError = true)]
internal static extern int SetStdHandle(int device, IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
internal static extern bool CreateProcess(string lpApplicationName,
string lpCommandLine, IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes, bool bInheritHandles,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
}
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
}

83
Main.cs
View File

@ -12,81 +12,12 @@ using WMI;
using System.Xml; using System.Xml;
using System.Threading; using System.Threading;
using Microsoft.Win32; using Microsoft.Win32;
using Advapi32;
using System.Management; using System.Management;
namespace winsw namespace winsw
{ {
public struct SERVICE_STATUS
{
public int serviceType;
public int currentState;
public int controlsAccepted;
public int win32ExitCode;
public int serviceSpecificExitCode;
public int checkPoint;
public int waitHint;
}
public enum State
{
SERVICE_STOPPED = 0x00000001,
SERVICE_START_PENDING = 0x00000002,
SERVICE_STOP_PENDING = 0x00000003,
SERVICE_RUNNING = 0x00000004,
SERVICE_CONTINUE_PENDING = 0x00000005,
SERVICE_PAUSE_PENDING = 0x00000006,
SERVICE_PAUSED = 0x00000007,
}
public class WrapperService : ServiceBase, EventLogger public class WrapperService : ServiceBase, EventLogger
{ {
[DllImport("ADVAPI32.DLL")]
private static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern int SetStdHandle(int device, IntPtr handle);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CreateProcess(string lpApplicationName,
string lpCommandLine, IntPtr lpProcessAttributes,
IntPtr lpThreadAttributes, bool bInheritHandles,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[StructLayout(LayoutKind.Sequential)]
internal struct PROCESS_INFORMATION
{
public IntPtr hProcess;
public IntPtr hThread;
public int dwProcessId;
public int dwThreadId;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
struct STARTUPINFO
{
public Int32 cb;
public string lpReserved;
public string lpDesktop;
public string lpTitle;
public Int32 dwX;
public Int32 dwY;
public Int32 dwXSize;
public Int32 dwYSize;
public Int32 dwXCountChars;
public Int32 dwYCountChars;
public Int32 dwFillAttribute;
public Int32 dwFlags;
public Int16 wShowWindow;
public Int16 cbReserved2;
public IntPtr lpReserved2;
public IntPtr hStdInput;
public IntPtr hStdOutput;
public IntPtr hStdError;
}
private SERVICE_STATUS wrapperServiceStatus; private SERVICE_STATUS wrapperServiceStatus;
private Process process = new Process(); private Process process = new Process();
@ -430,7 +361,7 @@ namespace winsw
wrapperServiceStatus.waitHint = descriptor.WaitHint.Milliseconds; wrapperServiceStatus.waitHint = descriptor.WaitHint.Milliseconds;
// WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint); // WriteEvent("SignalShutdownPending " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
wrapperServiceStatus.currentState = (int)State.SERVICE_STOP_PENDING; wrapperServiceStatus.currentState = (int)State.SERVICE_STOP_PENDING;
SetServiceStatus(handle, ref wrapperServiceStatus); Advapi32.SetServiceStatus(handle, ref wrapperServiceStatus);
} }
private void SignalShutdownComplete() private void SignalShutdownComplete()
@ -439,7 +370,7 @@ namespace winsw
wrapperServiceStatus.checkPoint++; wrapperServiceStatus.checkPoint++;
// WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint); // WriteEvent("SignalShutdownComplete " + wrapperServiceStatus.checkPoint + ":" + wrapperServiceStatus.waitHint);
wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED; wrapperServiceStatus.currentState = (int)State.SERVICE_STOPPED;
SetServiceStatus(handle, ref wrapperServiceStatus); Advapi32.SetServiceStatus(handle, ref wrapperServiceStatus);
} }
private void StartProcess(Process process, string arguments, String executable) private void StartProcess(Process process, string arguments, String executable)
@ -554,8 +485,8 @@ namespace winsw
Console.SetError(w); Console.SetError(w);
var handle = f.Handle; var handle = f.Handle;
SetStdHandle(-11, handle); // set stdout Kernel32.SetStdHandle(-11, handle); // set stdout
SetStdHandle(-12, handle); // set stder Kernel32.SetStdHandle(-12, handle); // set stder
args = args.GetRange(2, args.Count - 2); args = args.GetRange(2, args.Count - 2);
} }
@ -607,9 +538,9 @@ namespace winsw
var actions = d.FailureActions; var actions = d.FailureActions;
if (actions.Count > 0) if (actions.Count > 0)
{// set the failure actions {// set the failure actions
using (Advapi32.ServiceManager scm = new Advapi32.ServiceManager()) using (ServiceManager scm = new ServiceManager())
{ {
using (Advapi32.Service sc = scm.Open(d.Id)) using (Service sc = scm.Open(d.Id))
{ {
sc.ChangeConfig(d.ResetFailureAfter, actions); sc.ChangeConfig(d.ResetFailureAfter, actions);
} }
@ -664,7 +595,7 @@ namespace winsw
STARTUPINFO si = new STARTUPINFO(); STARTUPINFO si = new STARTUPINFO();
PROCESS_INFORMATION pi = new PROCESS_INFORMATION(); PROCESS_INFORMATION pi = new PROCESS_INFORMATION();
bool result = CreateProcess(null, d.ExecutablePath+" restart", IntPtr.Zero, IntPtr.Zero, false, 0x200/*CREATE_NEW_PROCESS_GROUP*/, IntPtr.Zero, null, ref si, out pi); bool result = Kernel32.CreateProcess(null, d.ExecutablePath+" restart", IntPtr.Zero, IntPtr.Zero, false, 0x200/*CREATE_NEW_PROCESS_GROUP*/, IntPtr.Zero, null, ref si, out pi);
if (!result) if (!result)
{ {
throw new Exception("Failed to invoke restart: "+Marshal.GetLastWin32Error()); throw new Exception("Failed to invoke restart: "+Marshal.GetLastWin32Error());

View File

@ -13,7 +13,6 @@ using WMI;
using System.Xml; using System.Xml;
using System.Threading; using System.Threading;
using Microsoft.Win32; using Microsoft.Win32;
using Advapi32;
namespace winsw namespace winsw
{ {

View File

@ -3,7 +3,7 @@
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>9.0.30729</ProductVersion> <ProductVersion>9.0.21022</ProductVersion>
<SchemaVersion>2.0</SchemaVersion> <SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{0DE77F55-ADE5-43C1-999A-0BC81153B039}</ProjectGuid> <ProjectGuid>{0DE77F55-ADE5-43C1-999A-0BC81153B039}</ProjectGuid>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
@ -40,15 +40,18 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" /> <Reference Include="System.Management" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.ServiceProcess" /> <Reference Include="System.ServiceProcess" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Advapi32.cs" /> <Compile Include="Advapi32.cs" />
<Compile Include="Download.cs" /> <Compile Include="Download.cs" />
<Compile Include="DynamicProxy.cs" /> <Compile Include="DynamicProxy.cs" />
<Compile Include="Kernel32.cs" />
<Compile Include="LogAppenders.cs" /> <Compile Include="LogAppenders.cs" />
<Compile Include="Main.cs"> <Compile Include="Main.cs">
<SubType>Component</SubType> <SubType>Component</SubType>