improving code to work better in UAC environment

pull/1/head
Kohsuke Kawaguchi 2010-11-17 22:04:49 -08:00
parent 2fa75e700f
commit f86f622f0b
3 changed files with 53 additions and 5 deletions

38
Main.cs
View File

@ -435,8 +435,12 @@ namespace winsw
public class WrapperService : ServiceBase public class WrapperService : ServiceBase
{ {
[DllImport("ADVAPI32.DLL", EntryPoint = "SetServiceStatus")] [DllImport("ADVAPI32.DLL")]
private static extern bool SetServiceStatus(IntPtr hServiceStatus, ref SERVICE_STATUS lpServiceStatus); 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);
private SERVICE_STATUS wrapperServiceStatus; private SERVICE_STATUS wrapperServiceStatus;
private Process process = new Process(); private Process process = new Process();
@ -672,7 +676,7 @@ namespace winsw
log.Close(); log.Close();
} }
protected override void OnStart(string[] args) protected override void OnStart(string[] _)
{ {
envs = descriptor.EnvironmentVariables; envs = descriptor.EnvironmentVariables;
foreach (string key in envs.Keys) foreach (string key in envs.Keys)
@ -915,14 +919,38 @@ namespace winsw
throw new WmiException(ReturnValue.NoSuchService); throw new WmiException(ReturnValue.NoSuchService);
} }
public static void Run(string[] args) public static void Run(string[] _args)
{ {
if (args.Length > 0) if (_args.Length > 0)
{ {
var d = new ServiceDescriptor(); var d = new ServiceDescriptor();
Win32Services svc = new WmiRoot().GetCollection<Win32Services>(); Win32Services svc = new WmiRoot().GetCollection<Win32Services>();
Win32Service s = svc.Select(d.Id); Win32Service s = svc.Select(d.Id);
var args = new List<string>(Array.AsReadOnly(_args));
if (args[0] == "/redirect")
{
// Redirect output
// One might ask why we support this when the caller
// can redirect the output easily. The answer is for supporting UAC.
// On UAC-enabled Windows such as Vista, SCM operation requires
// elevated privileges, thus winsw.exe needs to be launched
// accordingly. This in turn limits what the caller can do,
// and among other things it makes it difficult for the caller
// to read stdout/stderr. Thus redirection becomes handy.
var f = new FileStream(args[1], FileMode.Create);
var w = new StreamWriter(f);
w.AutoFlush = true;
Console.SetOut(w);
Console.SetError(w);
var handle = f.Handle;
SetStdHandle(-11, handle); // set stdout
SetStdHandle(-12, handle); // set stder
args = args.GetRange(2, args.Count - 2);
}
args[0] = args[0].ToLower(); args[0] = args[0].ToLower();
if (args[0] == "install") if (args[0] == "install")
{ {
@ -999,7 +1027,7 @@ namespace winsw
if (args[0] == "test") if (args[0] == "test")
{ {
WrapperService wsvc = new WrapperService(); WrapperService wsvc = new WrapperService();
wsvc.OnStart(args); wsvc.OnStart(args.ToArray());
Thread.Sleep(1000); Thread.Sleep(1000);
wsvc.OnStop(); wsvc.OnStop();
} }

10
manifest.xml Executable file
View File

@ -0,0 +1,10 @@
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="winsw" type="win32"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator"/>
</requestedPrivileges>
</security>
</trustInfo>
</assembly>

View File

@ -14,6 +14,10 @@
<FileAlignment>512</FileAlignment> <FileAlignment>512</FileAlignment>
<StartupObject> <StartupObject>
</StartupObject> </StartupObject>
<SignManifests>false</SignManifests>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>
</AssemblyOriginatorKeyFile>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@ -51,6 +55,7 @@
<Compile Include="WmiSchema.cs" /> <Compile Include="WmiSchema.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Content Include="manifest.xml" />
<Content Include="winsw.xml" /> <Content Include="winsw.xml" />
</ItemGroup> </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
@ -61,4 +66,9 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
<PropertyGroup>
<PostBuildEvent>"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\mt.exe" -manifest "$(ProjectDir)manifest.xml" outputresource:"$(TargetDir)$(TargetFileName)";#1
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\signtool.exe" sign /f c:\winsw-do-not-add-to-scm.pfx /p winsw /t http://timestamp.comodoca.com/authenticode $(TargetFileName)</PostBuildEvent>
</PropertyGroup>
</Project> </Project>