Skip to content

Commit 43435a8

Browse files
authored
Add Hosting.WindowsServices package #809 (#1083)
1 parent fe4a5b4 commit 43435a8

16 files changed

Lines changed: 316 additions & 39 deletions

Extensions.sln

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "tools", "tools", "{B0D89499
297297
EndProject
298298
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "testassets", "testassets", "{15AC3300-D335-4C5C-9E3A-22F26904AB26}"
299299
EndProject
300+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Hosting.WindowsServices", "src\Hosting\WindowsServices\src\Microsoft.Extensions.Hosting.WindowsServices.csproj", "{452F9F79-40E8-4B1C-8857-404062886080}"
301+
EndProject
302+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Hosting.WindowsServices.Tests", "src\Hosting\WindowsServices\test\Microsoft.Extensions.Hosting.WindowsServices.Tests.csproj", "{47D27C64-B8B7-4D10-9112-1432EACC79B3}"
303+
EndProject
300304
Global
301305
GlobalSection(SolutionConfigurationPlatforms) = preSolution
302306
Debug|Any CPU = Debug|Any CPU
@@ -1771,6 +1775,30 @@ Global
17711775
{DE47CB52-3E6F-4A6A-910E-AE118A00CE1A}.Release|x64.Build.0 = Release|Any CPU
17721776
{DE47CB52-3E6F-4A6A-910E-AE118A00CE1A}.Release|x86.ActiveCfg = Release|Any CPU
17731777
{DE47CB52-3E6F-4A6A-910E-AE118A00CE1A}.Release|x86.Build.0 = Release|Any CPU
1778+
{452F9F79-40E8-4B1C-8857-404062886080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1779+
{452F9F79-40E8-4B1C-8857-404062886080}.Debug|Any CPU.Build.0 = Debug|Any CPU
1780+
{452F9F79-40E8-4B1C-8857-404062886080}.Debug|x64.ActiveCfg = Debug|Any CPU
1781+
{452F9F79-40E8-4B1C-8857-404062886080}.Debug|x64.Build.0 = Debug|Any CPU
1782+
{452F9F79-40E8-4B1C-8857-404062886080}.Debug|x86.ActiveCfg = Debug|Any CPU
1783+
{452F9F79-40E8-4B1C-8857-404062886080}.Debug|x86.Build.0 = Debug|Any CPU
1784+
{452F9F79-40E8-4B1C-8857-404062886080}.Release|Any CPU.ActiveCfg = Release|Any CPU
1785+
{452F9F79-40E8-4B1C-8857-404062886080}.Release|Any CPU.Build.0 = Release|Any CPU
1786+
{452F9F79-40E8-4B1C-8857-404062886080}.Release|x64.ActiveCfg = Release|Any CPU
1787+
{452F9F79-40E8-4B1C-8857-404062886080}.Release|x64.Build.0 = Release|Any CPU
1788+
{452F9F79-40E8-4B1C-8857-404062886080}.Release|x86.ActiveCfg = Release|Any CPU
1789+
{452F9F79-40E8-4B1C-8857-404062886080}.Release|x86.Build.0 = Release|Any CPU
1790+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
1791+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
1792+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Debug|x64.ActiveCfg = Debug|Any CPU
1793+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Debug|x64.Build.0 = Debug|Any CPU
1794+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Debug|x86.ActiveCfg = Debug|Any CPU
1795+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Debug|x86.Build.0 = Debug|Any CPU
1796+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
1797+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Release|Any CPU.Build.0 = Release|Any CPU
1798+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Release|x64.ActiveCfg = Release|Any CPU
1799+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Release|x64.Build.0 = Release|Any CPU
1800+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Release|x86.ActiveCfg = Release|Any CPU
1801+
{47D27C64-B8B7-4D10-9112-1432EACC79B3}.Release|x86.Build.0 = Release|Any CPU
17741802
EndGlobalSection
17751803
GlobalSection(SolutionProperties) = preSolution
17761804
HideSolutionNode = FALSE
@@ -1904,6 +1932,8 @@ Global
19041932
{89B01C5B-42DF-4E99-847E-354B8C5FBA6F} = {6A293FDC-A13B-4137-87F9-C9225CF3542B}
19051933
{DE47CB52-3E6F-4A6A-910E-AE118A00CE1A} = {B0D89499-D1FA-4113-88C7-B82AB1D98EB6}
19061934
{15AC3300-D335-4C5C-9E3A-22F26904AB26} = {36617B81-CF74-4FCB-A7CA-E95DF3CA92FC}
1935+
{452F9F79-40E8-4B1C-8857-404062886080} = {6868A014-43FD-4047-B536-30D5D159D9D4}
1936+
{47D27C64-B8B7-4D10-9112-1432EACC79B3} = {6868A014-43FD-4047-B536-30D5D159D9D4}
19071937
EndGlobalSection
19081938
GlobalSection(ExtensibilityGlobals) = postSolution
19091939
SolutionGuid = {814BFC88-0867-451F-AC8F-20FE107809B4}

eng/Dependencies.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ and are generated based on the last package release.
3131
<LatestPackageReference Include="System.Runtime.InteropServices.RuntimeInformation" Version="$(SystemRuntimeInteropServicesRuntimeInformationPackageVersion)" />
3232
<LatestPackageReference Include="System.Security.Cryptography.Cng" Version="$(SystemSecurityCryptographyCngPackageVersion)" />
3333
<LatestPackageReference Include="System.Security.Cryptography.Xml" Version="$(SystemSecurityCryptographyXmlPackageVersion)" />
34+
<LatestPackageReference Include="System.ServiceProcess.ServiceController" Version="$(SystemServiceProcessServiceControllerPackageVersion)" />
3435
<LatestPackageReference Include="System.Text.Encodings.Web" Version="$(SystemTextEncodingsWebPackageVersion)" />
3536
<LatestPackageReference Include="System.Threading.Tasks.Extensions" Version="$(SystemThreadingTasksExtensionsPackageVersion)" />
3637
<LatestPackageReference Include="System.ValueTuple" Version="$(SystemValueTuplePackageVersion)" />

eng/ProjectReferences.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
<ProjectReferenceProvider Include="Microsoft.Extensions.Diagnostics.HealthChecks" ProjectPath="$(RepoRoot)src\HealthChecks\HealthChecks\src\Microsoft.Extensions.Diagnostics.HealthChecks.csproj" RefProjectPath="$(RepoRoot)src\HealthChecks\HealthChecks\ref\Microsoft.Extensions.Diagnostics.HealthChecks.csproj" />
3636
<ProjectReferenceProvider Include="Microsoft.Extensions.Hosting.Abstractions" ProjectPath="$(RepoRoot)src\Hosting\Abstractions\src\Microsoft.Extensions.Hosting.Abstractions.csproj" RefProjectPath="$(RepoRoot)src\Hosting\Abstractions\ref\Microsoft.Extensions.Hosting.Abstractions.csproj" />
3737
<ProjectReferenceProvider Include="Microsoft.Extensions.Hosting" ProjectPath="$(RepoRoot)src\Hosting\Hosting\src\Microsoft.Extensions.Hosting.csproj" RefProjectPath="$(RepoRoot)src\Hosting\Hosting\ref\Microsoft.Extensions.Hosting.csproj" />
38+
<ProjectReferenceProvider Include="Microsoft.Extensions.Hosting.WindowsServices" ProjectPath="$(RepoRoot)src\Hosting\WindowsServices\src\Microsoft.Extensions.Hosting.WindowsServices.csproj" RefProjectPath="$(RepoRoot)src\Hosting\WindowsServices\ref\Microsoft.Extensions.Hosting.WindowsServices.csproj" />
3839
<ProjectReferenceProvider Include="Microsoft.Extensions.Http" ProjectPath="$(RepoRoot)src\HttpClientFactory\Http\src\Microsoft.Extensions.Http.csproj" RefProjectPath="$(RepoRoot)src\HttpClientFactory\Http\ref\Microsoft.Extensions.Http.csproj" />
3940
<ProjectReferenceProvider Include="Microsoft.Extensions.Http.Polly" ProjectPath="$(RepoRoot)src\HttpClientFactory\Polly\src\Microsoft.Extensions.Http.Polly.csproj" RefProjectPath="$(RepoRoot)src\HttpClientFactory\Polly\ref\Microsoft.Extensions.Http.Polly.csproj" />
4041
<ProjectReferenceProvider Include="Microsoft.JSInterop" ProjectPath="$(RepoRoot)src\JSInterop\Microsoft.JSInterop\src\Microsoft.JSInterop.csproj" RefProjectPath="$(RepoRoot)src\JSInterop\Microsoft.JSInterop\ref\Microsoft.JSInterop.csproj" />

eng/Version.Details.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
<Uri>https://github.com/dotnet/corefx</Uri>
5151
<Sha>53b8e52dbf12355ce845230f6bbe6c5425bb73e6</Sha>
5252
</Dependency>
53+
<Dependency Name="System.ServiceProcess.ServiceController" Version="4.6.0-preview.19105.1">
54+
<Uri>https://github.com/dotnet/corefx</Uri>
55+
<Sha>53b8e52dbf12355ce845230f6bbe6c5425bb73e6</Sha>
56+
</Dependency>
5357
<Dependency Name="System.Text.Encodings.Web" Version="4.6.0-preview.19105.1">
5458
<Uri>https://github.com/dotnet/corefx</Uri>
5559
<Sha>53b8e52dbf12355ce845230f6bbe6c5425bb73e6</Sha>

eng/Versions.props

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
<SystemRuntimeCompilerServicesUnsafePackageVersion>4.6.0-preview.19105.1</SystemRuntimeCompilerServicesUnsafePackageVersion>
3232
<SystemSecurityCryptographyCngPackageVersion>4.6.0-preview.19105.1</SystemSecurityCryptographyCngPackageVersion>
3333
<SystemSecurityCryptographyXmlPackageVersion>4.6.0-preview.19105.1</SystemSecurityCryptographyXmlPackageVersion>
34+
<SystemServiceProcessServiceControllerPackageVersion>4.6.0-preview.19105.1</SystemServiceProcessServiceControllerPackageVersion>
3435
<SystemTextEncodingsWebPackageVersion>4.6.0-preview.19105.1</SystemTextEncodingsWebPackageVersion>
3536
<!-- Workaround https://github.com/dotnet/cli/issues/10528-->
3637
<MicrosoftNETCorePlatformsPackageVersion>3.0.0-preview.19105.1</MicrosoftNETCorePlatformsPackageVersion>

src/Hosting/Hosting.sln

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
3-
# Visual Studio 15
4-
VisualStudioVersion = 15.0.28306.52
3+
# Visual Studio Version 16
4+
VisualStudioVersion = 16.0.28527.54
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Hosting", "Hosting\src\Microsoft.Extensions.Hosting.csproj", "{1F452D39-FCB3-440C-8198-D0D1AA05E33E}"
77
EndProject
@@ -15,6 +15,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SampleMsmqHost", "samples\S
1515
EndProject
1616
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{D754FD75-091F-48DF-B3DA-91D0DB601E8B}"
1717
EndProject
18+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Hosting.WindowsServices", "WindowsServices\src\Microsoft.Extensions.Hosting.WindowsServices.csproj", "{EC466ABD-86DF-42A8-A307-1F0B28B36A2F}"
19+
EndProject
20+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Extensions.Hosting.WindowsServices.Tests", "WindowsServices\test\Microsoft.Extensions.Hosting.WindowsServices.Tests.csproj", "{1A3BC0DA-CB53-4C21-BDD0-2B2CF83655FA}"
21+
EndProject
1822
Global
1923
GlobalSection(SolutionConfigurationPlatforms) = preSolution
2024
Debug|Any CPU = Debug|Any CPU
@@ -41,6 +45,14 @@ Global
4145
{50586D64-6326-4CDB-9023-3A4D027263CF}.Debug|Any CPU.Build.0 = Debug|Any CPU
4246
{50586D64-6326-4CDB-9023-3A4D027263CF}.Release|Any CPU.ActiveCfg = Release|Any CPU
4347
{50586D64-6326-4CDB-9023-3A4D027263CF}.Release|Any CPU.Build.0 = Release|Any CPU
48+
{EC466ABD-86DF-42A8-A307-1F0B28B36A2F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
49+
{EC466ABD-86DF-42A8-A307-1F0B28B36A2F}.Debug|Any CPU.Build.0 = Debug|Any CPU
50+
{EC466ABD-86DF-42A8-A307-1F0B28B36A2F}.Release|Any CPU.ActiveCfg = Release|Any CPU
51+
{EC466ABD-86DF-42A8-A307-1F0B28B36A2F}.Release|Any CPU.Build.0 = Release|Any CPU
52+
{1A3BC0DA-CB53-4C21-BDD0-2B2CF83655FA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
53+
{1A3BC0DA-CB53-4C21-BDD0-2B2CF83655FA}.Debug|Any CPU.Build.0 = Debug|Any CPU
54+
{1A3BC0DA-CB53-4C21-BDD0-2B2CF83655FA}.Release|Any CPU.ActiveCfg = Release|Any CPU
55+
{1A3BC0DA-CB53-4C21-BDD0-2B2CF83655FA}.Release|Any CPU.Build.0 = Release|Any CPU
4456
EndGlobalSection
4557
GlobalSection(SolutionProperties) = preSolution
4658
HideSolutionNode = FALSE
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!-- This file is automatically generated. -->
2+
<Project Sdk="Microsoft.NET.Sdk">
3+
<PropertyGroup>
4+
<TargetFrameworks>netstandard2.0</TargetFrameworks>
5+
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
6+
</PropertyGroup>
7+
<ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0'">
8+
<Compile Include="Microsoft.Extensions.Hosting.WindowsServices.netstandard2.0.cs" />
9+
<Reference Include="Microsoft.Extensions.Hosting" />
10+
<Reference Include="System.ServiceProcess.ServiceController" />
11+
</ItemGroup>
12+
</Project>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
namespace Microsoft.Extensions.Hosting
5+
{
6+
public static partial class ServiceBaseLifetimeHostBuilderExtensions
7+
{
8+
public static Microsoft.Extensions.Hosting.IHostBuilder UseServiceBaseLifetime(this Microsoft.Extensions.Hosting.IHostBuilder hostBuilder) { throw null; }
9+
}
10+
}
11+
namespace Microsoft.Extensions.Hosting.WindowsServices
12+
{
13+
public partial class ServiceBaseLifetime : System.ServiceProcess.ServiceBase, Microsoft.Extensions.Hosting.IHostLifetime
14+
{
15+
public ServiceBaseLifetime(Microsoft.Extensions.Hosting.IHostingEnvironment environment, Microsoft.Extensions.Hosting.IApplicationLifetime applicationLifetime, Microsoft.Extensions.Logging.ILoggerFactory loggerFactory) { }
16+
public Microsoft.Extensions.Hosting.IHostingEnvironment Environment { [System.Runtime.CompilerServices.CompilerGeneratedAttribute]get { throw null; } }
17+
protected override void OnStart(string[] args) { }
18+
protected override void OnStop() { }
19+
public System.Threading.Tasks.Task StopAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
20+
public System.Threading.Tasks.Task WaitForStartAsync(System.Threading.CancellationToken cancellationToken) { throw null; }
21+
}
22+
}
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Diagnostics;
6+
using System.Runtime.InteropServices;
7+
8+
namespace Microsoft.Extensions.Hosting.WindowsServices.Internal
9+
{
10+
internal static class Win32
11+
{
12+
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-createtoolhelp32snapshot
13+
[DllImport("kernel32", SetLastError = true)]
14+
private static extern IntPtr CreateToolhelp32Snapshot(SnapshotFlags dwFlags, uint th32ProcessID);
15+
16+
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-process32first
17+
[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
18+
private static extern bool Process32First([In]IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
19+
20+
// https://docs.microsoft.com/en-us/windows/desktop/api/tlhelp32/nf-tlhelp32-process32next
21+
[DllImport("kernel32", SetLastError = true, CharSet = System.Runtime.InteropServices.CharSet.Auto)]
22+
private static extern bool Process32Next([In]IntPtr hSnapshot, ref PROCESSENTRY32 lppe);
23+
24+
[DllImport("kernel32", SetLastError = true)]
25+
[return: MarshalAs(UnmanagedType.Bool)]
26+
private static extern bool CloseHandle([In] IntPtr hObject);
27+
28+
internal static Process GetParentProcess()
29+
{
30+
var snapshotHandle = IntPtr.Zero;
31+
try
32+
{
33+
// Get a list of all processes
34+
snapshotHandle = CreateToolhelp32Snapshot(SnapshotFlags.Process, 0);
35+
36+
PROCESSENTRY32 procEntry = new PROCESSENTRY32();
37+
procEntry.dwSize = (UInt32)Marshal.SizeOf(typeof(PROCESSENTRY32));
38+
if (Process32First(snapshotHandle, ref procEntry))
39+
{
40+
var currentProcessId = Process.GetCurrentProcess().Id;
41+
do
42+
{
43+
if (currentProcessId == procEntry.th32ProcessID)
44+
{
45+
return Process.GetProcessById((int)procEntry.th32ParentProcessID);
46+
}
47+
}
48+
while (Process32Next(snapshotHandle, ref procEntry));
49+
}
50+
}
51+
catch (Exception)
52+
{
53+
}
54+
finally
55+
{
56+
CloseHandle(snapshotHandle);
57+
}
58+
59+
return null;
60+
}
61+
62+
[Flags]
63+
private enum SnapshotFlags : uint
64+
{
65+
HeapList = 0x00000001,
66+
Process = 0x00000002,
67+
Thread = 0x00000004,
68+
Module = 0x00000008,
69+
Module32 = 0x00000010,
70+
All = (HeapList | Process | Thread | Module),
71+
Inherit = 0x80000000,
72+
NoHeaps = 0x40000000
73+
}
74+
75+
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
76+
private struct PROCESSENTRY32
77+
{
78+
const int MAX_PATH = 260;
79+
internal UInt32 dwSize;
80+
internal UInt32 cntUsage;
81+
internal UInt32 th32ProcessID;
82+
internal IntPtr th32DefaultHeapID;
83+
internal UInt32 th32ModuleID;
84+
internal UInt32 cntThreads;
85+
internal UInt32 th32ParentProcessID;
86+
internal Int32 pcPriClassBase;
87+
internal UInt32 dwFlags;
88+
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = MAX_PATH)]
89+
internal string szExeFile;
90+
}
91+
}
92+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<Description>.NET hosting infrastructure for Windows Services.</Description>
5+
<TargetFramework>netstandard2.0</TargetFramework>
6+
<GenerateDocumentationFile>true</GenerateDocumentationFile>
7+
<PackageTags>hosting</PackageTags>
8+
<IsShipping>true</IsShipping>
9+
</PropertyGroup>
10+
11+
<ItemGroup>
12+
<Reference Include="Microsoft.Extensions.Hosting" />
13+
<Reference Include="System.ServiceProcess.ServiceController" />
14+
</ItemGroup>
15+
16+
</Project>

0 commit comments

Comments
 (0)