Annotate other libraries for nullable reference types

pull/356/head
NextTurn 2018-12-04 00:00:00 +08:00
parent 93b2212774
commit 466b5264e1
No known key found for this signature in database
GPG Key ID: 17A0D50ADDE1A0C4
12 changed files with 57 additions and 31 deletions

View File

@ -7,11 +7,11 @@ namespace winsw.Logging
/// </summary> /// </summary>
public class WrapperServiceEventLogProvider : IServiceEventLogProvider public class WrapperServiceEventLogProvider : IServiceEventLogProvider
{ {
public WrapperService service { get; set; } public WrapperService? service { get; set; }
public EventLog locate() public EventLog? locate()
{ {
WrapperService _service = service; WrapperService? _service = service;
if (_service != null && !_service.IsShuttingDown) if (_service != null && !_service.IsShuttingDown)
{ {
return _service.EventLog; return _service.EventLog;

View File

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Reflection; using System.Reflection;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -28,7 +29,7 @@ namespace winsw
private readonly Process _process = new Process(); private readonly Process _process = new Process();
private readonly ServiceDescriptor _descriptor; private readonly ServiceDescriptor _descriptor;
private Dictionary<string, string> _envs; private Dictionary<string, string>? _envs;
internal WinSWExtensionManager ExtensionManager { get; private set; } internal WinSWExtensionManager ExtensionManager { get; private set; }
@ -52,7 +53,7 @@ namespace winsw
/// <remarks> /// <remarks>
/// The version will be taken from <see cref="AssemblyInfo"/> /// The version will be taken from <see cref="AssemblyInfo"/>
/// </remarks> /// </remarks>
public static Version Version => Assembly.GetExecutingAssembly().GetName().Version; public static Version Version => Assembly.GetExecutingAssembly().GetName().Version!;
/// <summary> /// <summary>
/// Indicates that the system is shutting down. /// Indicates that the system is shutting down.
@ -92,7 +93,7 @@ namespace winsw
{ {
using (var tr = new StreamReader(file, Encoding.UTF8)) using (var tr = new StreamReader(file, Encoding.UTF8))
{ {
string line; string? line;
while ((line = tr.ReadLine()) != null) while ((line = tr.ReadLine()) != null)
{ {
LogEvent("Handling copy: " + line); LogEvent("Handling copy: " + line);
@ -223,7 +224,7 @@ namespace winsw
} }
} }
string startarguments = _descriptor.Startarguments; string? startarguments = _descriptor.Startarguments;
if (startarguments == null) if (startarguments == null)
{ {
@ -282,7 +283,7 @@ namespace winsw
/// </summary> /// </summary>
private void StopIt() private void StopIt()
{ {
string stoparguments = _descriptor.Stoparguments; string? stoparguments = _descriptor.Stoparguments;
LogEvent("Stopping " + _descriptor.Id); LogEvent("Stopping " + _descriptor.Id);
Log.Info("Stopping " + _descriptor.Id); Log.Info("Stopping " + _descriptor.Id);
_orderlyShutdown = true; _orderlyShutdown = true;
@ -307,7 +308,7 @@ namespace winsw
stoparguments += " " + _descriptor.Arguments; stoparguments += " " + _descriptor.Arguments;
Process stopProcess = new Process(); Process stopProcess = new Process();
string executable = _descriptor.StopExecutable; string? executable = _descriptor.StopExecutable;
if (executable == null) if (executable == null)
{ {
@ -399,7 +400,7 @@ namespace winsw
Advapi32.SetServiceStatus(handle, ref _wrapperServiceStatus); Advapi32.SetServiceStatus(handle, ref _wrapperServiceStatus);
} }
private void StartProcess(Process processToStart, string arguments, string executable, LogHandler logHandler, bool redirectStdin) private void StartProcess(Process processToStart, string arguments, string executable, LogHandler? logHandler, bool redirectStdin)
{ {
// Define handler of the completed process // Define handler of the completed process
void OnProcessCompleted(Process proc) void OnProcessCompleted(Process proc)
@ -470,6 +471,7 @@ namespace winsw
} }
} }
[DoesNotReturn]
private static void ThrowNoSuchService() private static void ThrowNoSuchService()
{ {
throw new WmiException(ReturnValue.NoSuchService); throw new WmiException(ReturnValue.NoSuchService);
@ -483,7 +485,7 @@ namespace winsw
/// <param name="descriptor">Service descriptor. If null, it will be initialized within the method. /// <param name="descriptor">Service descriptor. If null, it will be initialized within the method.
/// In such case configs will be loaded from the XML Configuration File.</param> /// In such case configs will be loaded from the XML Configuration File.</param>
/// <exception cref="Exception">Any unhandled exception</exception> /// <exception cref="Exception">Any unhandled exception</exception>
public static void Run(string[] _args, ServiceDescriptor descriptor = null) public static void Run(string[] _args, ServiceDescriptor? descriptor = null)
{ {
bool isCLIMode = _args.Length > 0; bool isCLIMode = _args.Length > 0;
@ -538,8 +540,9 @@ namespace winsw
throw new Exception("Installation failure: Service with id '" + d.Id + "' already exists"); throw new Exception("Installation failure: Service with id '" + d.Id + "' already exists");
} }
string username = null, password = null; string? username = null;
bool setallowlogonasaserviceright = false; string? password = null;
bool setallowlogonasaserviceright = false; // This variable is very readable.
if (args.Count > 1 && args[1] == "/p") if (args.Count > 1 && args[1] == "/p")
{ {
// we expected username/password on stdin // we expected username/password on stdin
@ -568,7 +571,7 @@ namespace winsw
if (setallowlogonasaserviceright) if (setallowlogonasaserviceright)
{ {
LogonAsAService.AddLogonAsAServiceRight(username); LogonAsAService.AddLogonAsAServiceRight(username!);
} }
svc.Create( svc.Create(

View File

@ -0,0 +1,8 @@
#if !NETCOREAPP
namespace System.Diagnostics.CodeAnalysis
{
/// <summary>Applied to a method that will never return under any circumstance.</summary>
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
internal sealed class DoesNotReturnAttribute : Attribute { }
}
#endif

View File

@ -15,7 +15,7 @@ namespace winsw
private static extern bool FreeConsole(); private static extern bool FreeConsole();
[DllImport(KERNEL32)] [DllImport(KERNEL32)]
private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add); private static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate? HandlerRoutine, bool Add);
// Delegate type to be used as the Handler Routine for SCCH // Delegate type to be used as the Handler Routine for SCCH
private delegate bool ConsoleCtrlDelegate(CtrlTypes CtrlType); private delegate bool ConsoleCtrlDelegate(CtrlTypes CtrlType);

View File

@ -3,6 +3,8 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFrameworks>net20;net40;net461;netcoreapp3.1</TargetFrameworks> <TargetFrameworks>net20;net40;net461;netcoreapp3.1</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<Version><!-- Populated by AppVeyor --></Version> <Version><!-- Populated by AppVeyor --></Version>
<AssemblyTitle>Windows Service Wrapper</AssemblyTitle> <AssemblyTitle>Windows Service Wrapper</AssemblyTitle>
<Description>Allows arbitrary process to run as a Windows service by wrapping it.</Description> <Description>Allows arbitrary process to run as a Windows service by wrapping it.</Description>

View File

@ -11,6 +11,6 @@ namespace winsw.Logging
/// Locates Event Log for the service. /// Locates Event Log for the service.
/// </summary> /// </summary>
/// <returns>Event Log or null if it is not avilable</returns> /// <returns>Event Log or null if it is not avilable</returns>
EventLog locate(); EventLog? locate();
} }
} }

View File

@ -13,12 +13,17 @@ namespace winsw.Native
public static extern bool SetStdHandle(int nStdHandle, SafeFileHandle handle); public static extern bool SetStdHandle(int nStdHandle, SafeFileHandle handle);
[DllImport("kernel32.dll", SetLastError = true)] [DllImport("kernel32.dll", SetLastError = true)]
public static extern bool CreateProcess(string lpApplicationName, public static extern bool CreateProcess(
string lpCommandLine, IntPtr lpProcessAttributes, string? lpApplicationName,
IntPtr lpThreadAttributes, bool bInheritHandles, string lpCommandLine,
uint dwCreationFlags, IntPtr lpEnvironment, string lpCurrentDirectory, IntPtr lpProcessAttributes,
[In] ref STARTUPINFO lpStartupInfo, IntPtr lpThreadAttributes,
out PROCESS_INFORMATION lpProcessInformation); bool bInheritHandles,
uint dwCreationFlags,
IntPtr lpEnvironment,
string? lpCurrentDirectory,
[In] ref STARTUPINFO lpStartupInfo,
out PROCESS_INFORMATION lpProcessInformation);
[DllImport("kernel32.dll")] [DllImport("kernel32.dll")]
public static extern int GetLastError(); public static extern int GetLastError();

View File

@ -48,7 +48,7 @@ namespace WMI
public interface Win32Services : IWmiCollection public interface Win32Services : IWmiCollection
{ {
// ReturnValue Create(bool desktopInteract, string displayName, int errorControl, string loadOrderGroup, string loadOrderGroupDependencies, string name, string pathName, string serviceDependencies, string serviceType, string startMode, string startName, string startPassword); // ReturnValue Create(bool desktopInteract, string displayName, int errorControl, string loadOrderGroup, string loadOrderGroupDependencies, string name, string pathName, string serviceDependencies, string serviceType, string startMode, string startName, string startPassword);
void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, StartMode startMode, bool desktopInteract, string startName, string startPassword, string[] serviceDependencies); void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, StartMode startMode, bool desktopInteract, string? startName, string? startPassword, string[] serviceDependencies);
void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, StartMode startMode, bool desktopInteract, string[] serviceDependencies); void Create(string name, string displayName, string pathName, ServiceType serviceType, ErrorControl errorControl, StartMode startMode, bool desktopInteract, string[] serviceDependencies);

View File

@ -2,6 +2,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net20;net40;net461;netcoreapp3.1</TargetFrameworks> <TargetFrameworks>net20;net40;net461;netcoreapp3.1</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<Version><!-- Populated by AppVeyor --></Version> <Version><!-- Populated by AppVeyor --></Version>
<RootNamespace>winsw.Plugins.RunawayProcessKiller</RootNamespace> <RootNamespace>winsw.Plugins.RunawayProcessKiller</RootNamespace>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>

View File

@ -40,12 +40,16 @@ namespace winsw.Plugins.RunawayProcessKiller
private static readonly ILog Logger = LogManager.GetLogger(typeof(RunawayProcessKillerExtension)); private static readonly ILog Logger = LogManager.GetLogger(typeof(RunawayProcessKillerExtension));
#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
public RunawayProcessKillerExtension() public RunawayProcessKillerExtension()
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
{ {
// Default initializer // Default initializer
} }
#pragma warning disable CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
public RunawayProcessKillerExtension(string pidfile, int stopTimeoutMs = 5000, bool stopParentFirst = false, bool checkWinSWEnvironmentVariable = true) public RunawayProcessKillerExtension(string pidfile, int stopTimeoutMs = 5000, bool stopParentFirst = false, bool checkWinSWEnvironmentVariable = true)
#pragma warning restore CS8618 // Non-nullable field is uninitialized. Consider declaring as nullable.
{ {
this.Pidfile = pidfile; this.Pidfile = pidfile;
this.StopTimeout = TimeSpan.FromMilliseconds(stopTimeoutMs); this.StopTimeout = TimeSpan.FromMilliseconds(stopTimeoutMs);
@ -57,9 +61,9 @@ namespace winsw.Plugins.RunawayProcessKiller
{ {
// We expect the upper logic to process any errors // We expect the upper logic to process any errors
// TODO: a better parser API for types would be useful // TODO: a better parser API for types would be useful
Pidfile = XmlHelper.SingleElement(node, "pidfile", false); Pidfile = XmlHelper.SingleElement(node, "pidfile", false)!;
StopTimeout = TimeSpan.FromMilliseconds(int.Parse(XmlHelper.SingleElement(node, "stopTimeout", false))); StopTimeout = TimeSpan.FromMilliseconds(int.Parse(XmlHelper.SingleElement(node, "stopTimeout", false)!));
StopParentProcessFirst = bool.Parse(XmlHelper.SingleElement(node, "stopParentFirst", false)); StopParentProcessFirst = bool.Parse(XmlHelper.SingleElement(node, "stopParentFirst", false)!);
ServiceId = descriptor.Id; ServiceId = descriptor.Id;
// TODO: Consider making it documented // TODO: Consider making it documented
var checkWinSWEnvironmentVariable = XmlHelper.SingleElement(node, "checkWinSWEnvironmentVariable", true); var checkWinSWEnvironmentVariable = XmlHelper.SingleElement(node, "checkWinSWEnvironmentVariable", true);
@ -117,7 +121,7 @@ namespace winsw.Plugins.RunawayProcessKiller
} }
// Ensure the process references the service // Ensure the process references the service
string affiliatedServiceId; string? affiliatedServiceId;
// TODO: This method is not ideal since it works only for vars explicitly mentioned in the start info // TODO: This method is not ideal since it works only for vars explicitly mentioned in the start info
// No Windows 10- compatible solution for EnvVars retrieval, see https://blog.gapotchenko.com/eazfuscator.net/reading-environment-variables // No Windows 10- compatible solution for EnvVars retrieval, see https://blog.gapotchenko.com/eazfuscator.net/reading-environment-variables
StringDictionary previousProcessEnvVars = proc.StartInfo.EnvironmentVariables; StringDictionary previousProcessEnvVars = proc.StartInfo.EnvironmentVariables;

View File

@ -28,12 +28,12 @@ namespace winsw.Plugins.SharedDirectoryMapper
public override void Configure(ServiceDescriptor descriptor, XmlNode node) public override void Configure(ServiceDescriptor descriptor, XmlNode node)
{ {
var nodes = XmlHelper.SingleNode(node, "mapping", false).SelectNodes("map"); var mapNodes = XmlHelper.SingleNode(node, "mapping", false)!.SelectNodes("map");
if (nodes != null) if (mapNodes != null)
{ {
foreach (XmlNode mapNode in nodes) for (int i = 0; i < mapNodes.Count; i++)
{ {
if (mapNode is XmlElement mapElement) if (mapNodes[i] is XmlElement mapElement)
{ {
var config = SharedDirectoryMapperConfig.FromXml(mapElement); var config = SharedDirectoryMapperConfig.FromXml(mapElement);
_entries.Add(config); _entries.Add(config);

View File

@ -2,6 +2,8 @@
<PropertyGroup> <PropertyGroup>
<TargetFrameworks>net20;net40;net461;netcoreapp3.1</TargetFrameworks> <TargetFrameworks>net20;net40;net461;netcoreapp3.1</TargetFrameworks>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<Version><!-- Populated by AppVeyor --></Version> <Version><!-- Populated by AppVeyor --></Version>
<RootNamespace>winsw.Plugins.SharedDirectoryMapper</RootNamespace> <RootNamespace>winsw.Plugins.SharedDirectoryMapper</RootNamespace>
<SignAssembly>true</SignAssembly> <SignAssembly>true</SignAssembly>