├── .gitignore ├── DebuggableService.sln ├── DebuggableService ├── AssemblyInfo.cs ├── ConsoleHarness.cs ├── DebuggableService.csproj ├── DebuggableService.ico ├── DebuggableService.vstemplate ├── IWindowsService.cs ├── Program.cs ├── ProjectTemplate.csproj ├── Properties │ └── AssemblyInfo.cs ├── ServiceImplementation.cs ├── TypeExtensions.cs ├── WindowsServiceAttribute.cs ├── WindowsServiceHarness.Designer.cs ├── WindowsServiceHarness.cs ├── WindowsServiceInstaller.Designer.cs └── WindowsServiceInstaller.cs ├── DebuggableServiceSetup ├── DebuggableService.ico ├── DebuggableServiceSetup.csproj ├── LICENSE.txt ├── Properties │ └── AssemblyInfo.cs ├── source.extension.vsixmanifest └── worm-gear-icon.png ├── LICENSE ├── README.md └── newproject.png /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | 24 | # Visual Studio 2015 cache/options directory 25 | .vs/ 26 | # Uncomment if you have tasks that create the project's static files in wwwroot 27 | #wwwroot/ 28 | 29 | # MSTest test Results 30 | [Tt]est[Rr]esult*/ 31 | [Bb]uild[Ll]og.* 32 | 33 | # NUNIT 34 | *.VisualState.xml 35 | TestResult.xml 36 | 37 | # Build Results of an ATL Project 38 | [Dd]ebugPS/ 39 | [Rr]eleasePS/ 40 | dlldata.c 41 | 42 | # DNX 43 | project.lock.json 44 | artifacts/ 45 | 46 | *_i.c 47 | *_p.c 48 | *_i.h 49 | *.ilk 50 | *.meta 51 | *.obj 52 | *.pch 53 | *.pdb 54 | *.pgc 55 | *.pgd 56 | *.rsp 57 | *.sbr 58 | *.tlb 59 | *.tli 60 | *.tlh 61 | *.tmp 62 | *.tmp_proj 63 | *.log 64 | *.vspscc 65 | *.vssscc 66 | .builds 67 | *.pidb 68 | *.svclog 69 | *.scc 70 | 71 | # Chutzpah Test files 72 | _Chutzpah* 73 | 74 | # Visual C++ cache files 75 | ipch/ 76 | *.aps 77 | *.ncb 78 | *.opendb 79 | *.opensdf 80 | *.sdf 81 | *.cachefile 82 | 83 | # Visual Studio profiler 84 | *.psess 85 | *.vsp 86 | *.vspx 87 | *.sap 88 | 89 | # TFS 2012 Local Workspace 90 | $tf/ 91 | 92 | # Guidance Automation Toolkit 93 | *.gpState 94 | 95 | # ReSharper is a .NET coding add-in 96 | _ReSharper*/ 97 | *.[Rr]e[Ss]harper 98 | *.DotSettings.user 99 | 100 | # JustCode is a .NET coding add-in 101 | .JustCode 102 | 103 | # TeamCity is a build add-in 104 | _TeamCity* 105 | 106 | # DotCover is a Code Coverage Tool 107 | *.dotCover 108 | 109 | # NCrunch 110 | _NCrunch_* 111 | .*crunch*.local.xml 112 | nCrunchTemp_* 113 | 114 | # MightyMoose 115 | *.mm.* 116 | AutoTest.Net/ 117 | 118 | # Web workbench (sass) 119 | .sass-cache/ 120 | 121 | # Installshield output folder 122 | [Ee]xpress/ 123 | 124 | # DocProject is a documentation generator add-in 125 | DocProject/buildhelp/ 126 | DocProject/Help/*.HxT 127 | DocProject/Help/*.HxC 128 | DocProject/Help/*.hhc 129 | DocProject/Help/*.hhk 130 | DocProject/Help/*.hhp 131 | DocProject/Help/Html2 132 | DocProject/Help/html 133 | 134 | # Click-Once directory 135 | publish/ 136 | 137 | # Publish Web Output 138 | *.[Pp]ublish.xml 139 | *.azurePubxml 140 | # TODO: Comment the next line if you want to checkin your web deploy settings 141 | # but database connection strings (with potential passwords) will be unencrypted 142 | *.pubxml 143 | *.publishproj 144 | 145 | # NuGet Packages 146 | *.nupkg 147 | # The packages folder can be ignored because of Package Restore 148 | **/packages/* 149 | # except build/, which is used as an MSBuild target. 150 | !**/packages/build/ 151 | # Uncomment if necessary however generally it will be regenerated when needed 152 | #!**/packages/repositories.config 153 | # NuGet v3's project.json files produces more ignoreable files 154 | *.nuget.props 155 | *.nuget.targets 156 | 157 | # Microsoft Azure Build Output 158 | csx/ 159 | *.build.csdef 160 | 161 | # Microsoft Azure Emulator 162 | ecf/ 163 | rcf/ 164 | 165 | # Microsoft Azure ApplicationInsights config file 166 | ApplicationInsights.config 167 | 168 | # Windows Store app package directory 169 | AppPackages/ 170 | BundleArtifacts/ 171 | 172 | # Visual Studio cache files 173 | # files ending in .cache can be ignored 174 | *.[Cc]ache 175 | # but keep track of directories ending in .cache 176 | !*.[Cc]ache/ 177 | 178 | # Others 179 | ClientBin/ 180 | ~$* 181 | *~ 182 | *.dbmdl 183 | *.dbproj.schemaview 184 | *.pfx 185 | *.publishsettings 186 | node_modules/ 187 | orleans.codegen.cs 188 | 189 | # RIA/Silverlight projects 190 | Generated_Code/ 191 | 192 | # Backup & report files from converting an old project file 193 | # to a newer Visual Studio version. Backup files are not needed, 194 | # because we have git ;-) 195 | _UpgradeReport_Files/ 196 | Backup*/ 197 | UpgradeLog*.XML 198 | UpgradeLog*.htm 199 | 200 | # SQL Server files 201 | *.mdf 202 | *.ldf 203 | 204 | # Business Intelligence projects 205 | *.rdl.data 206 | *.bim.layout 207 | *.bim_*.settings 208 | 209 | # Microsoft Fakes 210 | FakesAssemblies/ 211 | 212 | # GhostDoc plugin setting file 213 | *.GhostDoc.xml 214 | 215 | # Node.js Tools for Visual Studio 216 | .ntvs_analysis.dat 217 | 218 | # Visual Studio 6 build log 219 | *.plg 220 | 221 | # Visual Studio 6 workspace options file 222 | *.opt 223 | 224 | # Visual Studio LightSwitch build output 225 | **/*.HTMLClient/GeneratedArtifacts 226 | **/*.DesktopClient/GeneratedArtifacts 227 | **/*.DesktopClient/ModelManifest.xml 228 | **/*.Server/GeneratedArtifacts 229 | **/*.Server/ModelManifest.xml 230 | _Pvt_Extensions 231 | 232 | # Paket dependency manager 233 | .paket/paket.exe 234 | 235 | # FAKE - F# Make 236 | .fake/ 237 | -------------------------------------------------------------------------------- /DebuggableService.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2027 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebuggableService", "DebuggableService\DebuggableService.csproj", "{38EBE914-5286-4822-822F-F248DB63C973}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebuggableServiceSetup", "DebuggableServiceSetup\DebuggableServiceSetup.csproj", "{5CE9E1DB-7A1B-4425-BD2E-22E9EB5BB5F4}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {38EBE914-5286-4822-822F-F248DB63C973}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {38EBE914-5286-4822-822F-F248DB63C973}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {38EBE914-5286-4822-822F-F248DB63C973}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {38EBE914-5286-4822-822F-F248DB63C973}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {5CE9E1DB-7A1B-4425-BD2E-22E9EB5BB5F4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {5CE9E1DB-7A1B-4425-BD2E-22E9EB5BB5F4}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {5CE9E1DB-7A1B-4425-BD2E-22E9EB5BB5F4}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {5CE9E1DB-7A1B-4425-BD2E-22E9EB5BB5F4}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {67563A84-DD69-497F-A3CD-E2C57C790A9D} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /DebuggableService/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("$projectname$")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("$registeredorganization$")] 12 | [assembly: AssemblyProduct("$projectname$")] 13 | [assembly: AssemblyCopyright("Copyright © $registeredorganization$ $year$")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("$guid1$")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DebuggableService/ConsoleHarness.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace $safeprojectname$.Framework 4 | { 5 | public static class ConsoleHarness 6 | { 7 | // Run a service from the console given a service implementation 8 | public static void Run(string[] args, IWindowsService service) 9 | { 10 | string serviceName = service.GetType().Name; 11 | bool isRunning = true; 12 | 13 | // simulate starting the windows service 14 | service.OnStart(args); 15 | 16 | // let it run as long as Q is not pressed 17 | while (isRunning) 18 | { 19 | WriteToConsole(ConsoleColor.Yellow, "Enter either [Q]uit, [P]ause, [R]esume : "); 20 | isRunning = HandleConsoleInput(service, Console.ReadLine()); 21 | } 22 | 23 | // stop and shutdown 24 | service.OnStop(); 25 | service.OnShutdown(); 26 | } 27 | 28 | 29 | // Private input handler for console commands. 30 | private static bool HandleConsoleInput(IWindowsService service, string line) 31 | { 32 | bool canContinue = true; 33 | 34 | // check input 35 | if (line != null) 36 | { 37 | switch (line.ToUpper()) 38 | { 39 | case "Q": 40 | canContinue = false; 41 | break; 42 | 43 | case "P": 44 | service.OnPause(); 45 | break; 46 | 47 | case "R": 48 | service.OnContinue(); 49 | break; 50 | 51 | default: 52 | WriteToConsole(ConsoleColor.Red, "Did not understand that input, try again."); 53 | break; 54 | } 55 | } 56 | 57 | return canContinue; 58 | } 59 | 60 | 61 | // Helper method to write a message to the console at the given foreground color. 62 | internal static void WriteToConsole(ConsoleColor foregroundColor, string format, 63 | params object[] formatArguments) 64 | { 65 | ConsoleColor originalColor = Console.ForegroundColor; 66 | Console.ForegroundColor = foregroundColor; 67 | 68 | Console.WriteLine(format, formatArguments); 69 | Console.Out.Flush(); 70 | 71 | Console.ForegroundColor = originalColor; 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /DebuggableService/DebuggableService.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 15.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 14.0 9 | 10 | 11 | false 12 | publish\ 13 | true 14 | Disk 15 | false 16 | Foreground 17 | 7 18 | Days 19 | false 20 | false 21 | true 22 | 0 23 | 1.0.0.%2a 24 | false 25 | true 26 | 27 | 28 | 29 | 30 | Debug 31 | AnyCPU 32 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 33 | {38EBE914-5286-4822-822F-F248DB63C973} 34 | Library 35 | Properties 36 | DebuggableService 37 | DebuggableService 38 | v4.7.2 39 | 512 40 | false 41 | false 42 | false 43 | false 44 | false 45 | false 46 | false 47 | false 48 | false 49 | false 50 | 51 | 52 | true 53 | full 54 | false 55 | bin\Debug\ 56 | DEBUG;TRACE 57 | prompt 58 | 4 59 | 60 | 61 | pdbonly 62 | true 63 | bin\Release\ 64 | TRACE 65 | prompt 66 | 4 67 | 68 | 69 | 70 | False 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | WindowsServiceHarness.cs 85 | 86 | 87 | 88 | WindowsServiceInstaller.cs 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | Designer 102 | 103 | 104 | 105 | 106 | False 107 | .NET Framework 3.5 SP1 108 | false 109 | 110 | 111 | 112 | 113 | 120 | -------------------------------------------------------------------------------- /DebuggableService/DebuggableService.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobThree/DebuggableSelfInstallingService/e2d3aca9c0b79e9f9aa39a18b75ef4549dbd9efa/DebuggableService/DebuggableService.ico -------------------------------------------------------------------------------- /DebuggableService/DebuggableService.vstemplate: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | DebuggableService 5 | DebuggableService 6 | DebuggableService.ico 7 | CSharp 8 | 2.0 9 | 1000 10 | 6904508d-e760-44e2-8d0e-038c5f108fdf 11 | true 12 | DebuggableService 13 | true 14 | 15 | 16 | 17 | AssemblyInfo.cs 18 | ServiceImplementation.cs 19 | Program.cs 20 | ConsoleHarness.cs 21 | IWindowsService.cs 22 | TypeExtensions.cs 23 | WindowsServiceAttribute.cs 24 | WindowsServiceHarness.cs 25 | WindowsServiceHarness.Designer.cs 26 | WindowsServiceInstaller.cs 27 | WindowsServiceInstaller.Designer.cs 28 | 29 | 30 | -------------------------------------------------------------------------------- /DebuggableService/IWindowsService.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace $safeprojectname$.Framework 4 | { 5 | /// 6 | /// The interface that any windows service should implement to be used 7 | /// with the GenericWindowsService executable. 8 | /// 9 | public interface IWindowsService : IDisposable 10 | { 11 | /// 12 | /// This method is called when the service gets a request to start. 13 | /// 14 | /// Any command line arguments 15 | void OnStart(string[] args); 16 | 17 | /// 18 | /// This method is called when the service gets a request to stop. 19 | /// 20 | void OnStop(); 21 | 22 | /// 23 | /// This method is called when a service gets a request to pause, 24 | /// but not stop completely. 25 | /// 26 | void OnPause(); 27 | 28 | /// 29 | /// This method is called when a service gets a request to resume 30 | /// after a pause is issued. 31 | /// 32 | void OnContinue(); 33 | 34 | /// 35 | /// This method is called when the machine the service is running on 36 | /// is being shutdown. 37 | /// 38 | void OnShutdown(); 39 | 40 | /// 41 | /// This method is called when a custom command is issued to the service. 42 | /// 43 | /// The command identifier to execute. 44 | void OnCustomCommand(int command); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /DebuggableService/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.ServiceProcess; 4 | using $safeprojectname$.Framework; 5 | 6 | namespace $safeprojectname$ 7 | { 8 | static class Program 9 | { 10 | // The main entry point for the windows service application. 11 | static void Main(string[] args) 12 | { 13 | try 14 | { 15 | // If install was a command line flag, then run the installer at runtime. 16 | if (args.Contains("-install", StringComparer.InvariantCultureIgnoreCase)) 17 | { 18 | WindowsServiceInstaller.RuntimeInstall(); 19 | } 20 | 21 | // If uninstall was a command line flag, run uninstaller at runtime. 22 | else if (args.Contains("-uninstall", StringComparer.InvariantCultureIgnoreCase)) 23 | { 24 | WindowsServiceInstaller.RuntimeUnInstall(); 25 | } 26 | 27 | // Otherwise, fire up the service as either console or windows service based on UserInteractive property. 28 | else 29 | { 30 | var implementation = new ServiceImplementation(); 31 | 32 | // If started from console, file explorer, etc, run as console app. 33 | if (Environment.UserInteractive) 34 | { 35 | ConsoleHarness.Run(args, implementation); 36 | } 37 | 38 | // Otherwise run as a windows service 39 | else 40 | { 41 | ServiceBase.Run(new WindowsServiceHarness(implementation)); 42 | } 43 | } 44 | } 45 | 46 | catch (Exception ex) 47 | { 48 | ConsoleHarness.WriteToConsole(ConsoleColor.Red, "An exception occurred in Main(): {0}", ex); 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /DebuggableService/ProjectTemplate.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | $guid1$ 9 | Exe 10 | Properties 11 | $safeprojectname$ 12 | $safeprojectname$ 13 | v$targetframeworkversion$ 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | $if$ ($targetframeworkversion$ >= 3.5) 37 | 38 | 39 | 40 | $endif$ 41 | $if$ ($targetframeworkversion$ >= 4.0) 42 | 43 | $endif$ 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Component 55 | 56 | 57 | WindowsServiceHarness.cs 58 | 59 | 60 | Component 61 | 62 | 63 | WindowsServiceInstaller.cs 64 | 65 | 66 | 67 | 68 | 69 | 70 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /DebuggableService/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DebuggableService")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DebuggableService")] 13 | [assembly: AssemblyCopyright("Copyright © RobIII 2016 - 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("38ebe914-5286-4822-822f-f248db63c973")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.0.0.0")] 36 | [assembly: AssemblyFileVersion("1.0.0.0")] 37 | -------------------------------------------------------------------------------- /DebuggableService/ServiceImplementation.cs: -------------------------------------------------------------------------------- 1 | using $safeprojectname$.Framework; 2 | using System.ServiceProcess; 3 | 4 | 5 | namespace $safeprojectname$ 6 | { 7 | /// 8 | /// The actual implementation of the windows service goes here... 9 | /// 10 | [WindowsService("$safeprojectname$", 11 | DisplayName = "$safeprojectname$", 12 | Description = "The description of the $safeprojectname$ service.", 13 | EventLogSource = "$safeprojectname$", 14 | StartMode = ServiceStartMode.Automatic)] 15 | public class ServiceImplementation : IWindowsService 16 | { 17 | /// 18 | /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. 19 | /// 20 | /// 2 21 | public void Dispose() 22 | { 23 | } 24 | 25 | /// 26 | /// This method is called when the service gets a request to start. 27 | /// 28 | /// Any command line arguments 29 | public void OnStart(string[] args) 30 | { 31 | } 32 | 33 | /// 34 | /// This method is called when the service gets a request to stop. 35 | /// 36 | public void OnStop() 37 | { 38 | } 39 | 40 | /// 41 | /// This method is called when a service gets a request to pause, 42 | /// but not stop completely. 43 | /// 44 | public void OnPause() 45 | { 46 | } 47 | 48 | /// 49 | /// This method is called when a service gets a request to resume 50 | /// after a pause is issued. 51 | /// 52 | public void OnContinue() 53 | { 54 | } 55 | 56 | /// 57 | /// This method is called when the machine the service is running on 58 | /// is being shutdown. 59 | /// 60 | public void OnShutdown() 61 | { 62 | } 63 | 64 | /// 65 | /// This method is called when a custom command is issued to the service. 66 | /// 67 | /// The command identifier to execute. 68 | public void OnCustomCommand(int command) 69 | { 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /DebuggableService/TypeExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace $safeprojectname$.Framework 6 | { 7 | /// 8 | /// Extension methods for the Type class 9 | /// 10 | public static class TypeExtensions 11 | { 12 | /// 13 | /// Loads the configuration from assembly attributes 14 | /// 15 | /// The type of the custom attribute to find. 16 | /// The calling assembly to search. 17 | /// The custom attribute of type T, if found. 18 | public static T GetAttribute(this Type typeWithAttributes) 19 | where T : Attribute 20 | { 21 | return GetAttributes(typeWithAttributes).FirstOrDefault(); 22 | } 23 | 24 | /// 25 | /// Loads the configuration from assembly attributes 26 | /// 27 | /// The type of the custom attribute to find. 28 | /// The calling assembly to search. 29 | /// An enumeration of attributes of type T that were found. 30 | public static IEnumerable GetAttributes(this Type typeWithAttributes) 31 | where T : Attribute 32 | { 33 | // Try to find the configuration attribute for the default logger if it exists 34 | object[] configAttributes = Attribute.GetCustomAttributes(typeWithAttributes, 35 | typeof(T), false); 36 | 37 | // get just the first one 38 | if (configAttributes != null && configAttributes.Length > 0) 39 | { 40 | foreach (T attribute in configAttributes) 41 | { 42 | yield return attribute; 43 | } 44 | } 45 | } 46 | } 47 | } -------------------------------------------------------------------------------- /DebuggableService/WindowsServiceAttribute.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceProcess; 3 | 4 | namespace $safeprojectname$.Framework 5 | { 6 | [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)] 7 | public class WindowsServiceAttribute : Attribute 8 | { 9 | /// 10 | /// The name of the service. 11 | /// 12 | public string Name { get; set; } 13 | 14 | /// 15 | /// The displayable name that shows in service manager (defaults to Name). 16 | /// 17 | public string DisplayName { get; set; } 18 | 19 | /// 20 | /// A textural description of the service name (defaults to Name). 21 | /// 22 | public string Description { get; set; } 23 | 24 | /// 25 | /// The user to run the service under (defaults to null). A null or empty 26 | /// UserName field causes the service to run as ServiceAccount.LocalService. 27 | /// 28 | public string UserName { get; set; } 29 | 30 | /// 31 | /// The password to run the service under (defaults to null). Ignored 32 | /// if the UserName is empty or null, this property is ignored. 33 | /// 34 | public string Password { get; set; } 35 | 36 | /// 37 | /// Specifies the event log source to set the service's EventLog to. If this is 38 | /// empty or null (the default) no event log source is set. If set, will auto-log 39 | /// start and stop events. 40 | /// 41 | public string EventLogSource { get; set; } 42 | 43 | /// 44 | /// The method to start the service when the machine reboots (defaults to Manual). 45 | /// 46 | public ServiceStartMode StartMode { get; set; } 47 | 48 | /// 49 | /// True if service supports pause and continue (defaults to true). 50 | /// 51 | public bool CanPauseAndContinue { get; set; } 52 | 53 | /// 54 | /// True if service supports shutdown event (defaults to true). 55 | /// 56 | public bool CanShutdown { get; set; } 57 | 58 | /// 59 | /// True if service supports stop event (defaults to true). 60 | /// 61 | public bool CanStop { get; set; } 62 | 63 | /// 64 | /// Services the service depends on 65 | /// 66 | public string[] ServiceDependsOn { get; set; } 67 | 68 | /// 69 | /// Marks an IWindowsService with configuration and installation attributes. 70 | /// 71 | /// The name of the windows service. 72 | public WindowsServiceAttribute(string name) 73 | { 74 | // Set name and default description and display name to name. 75 | Name = name; 76 | Description = name; 77 | DisplayName = name; 78 | 79 | // Default all other attributes. 80 | ServiceDependsOn = new string[0]; 81 | CanStop = true; 82 | CanShutdown = true; 83 | CanPauseAndContinue = true; 84 | StartMode = ServiceStartMode.Manual; 85 | EventLogSource = null; 86 | Password = null; 87 | UserName = null; 88 | } 89 | } 90 | } -------------------------------------------------------------------------------- /DebuggableService/WindowsServiceHarness.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace $safeprojectname$.Framework 2 | { 3 | public partial class WindowsServiceHarness 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | components = new System.ComponentModel.Container(); 32 | this.ServiceName = "$safeprojectname$"; 33 | } 34 | 35 | #endregion 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /DebuggableService/WindowsServiceHarness.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.ServiceProcess; 3 | 4 | 5 | namespace $safeprojectname$.Framework 6 | { 7 | /// 8 | /// A generic Windows Service that can handle any assembly that 9 | /// implements IWindowsService (including AbstractWindowsService) 10 | /// 11 | public partial class WindowsServiceHarness : ServiceBase 12 | { 13 | /// 14 | /// Get the class implementing the windows service 15 | /// 16 | public IWindowsService ServiceImplementation { get; private set; } 17 | 18 | /// 19 | /// Constructor a generic windows service from the given class 20 | /// 21 | /// Service implementation. 22 | public WindowsServiceHarness(IWindowsService serviceImplementation) 23 | { 24 | // make sure service passed in is valid 25 | if (serviceImplementation == null) 26 | { 27 | throw new ArgumentNullException("serviceImplementation", 28 | "IWindowsService cannot be null in call to GenericWindowsService"); 29 | } 30 | 31 | // set instance and backward instance 32 | ServiceImplementation = serviceImplementation; 33 | 34 | // configure our service 35 | ConfigureServiceFromAttributes(serviceImplementation); 36 | } 37 | 38 | /// 39 | /// Override service control on continue 40 | /// 41 | protected override void OnContinue() 42 | { 43 | // perform class specific behavior 44 | ServiceImplementation.OnContinue(); 45 | } 46 | 47 | /// 48 | /// Called when service is paused 49 | /// 50 | protected override void OnPause() 51 | { 52 | // perform class specific behavior 53 | ServiceImplementation.OnPause(); 54 | } 55 | 56 | /// 57 | /// Called when a custom command is requested 58 | /// 59 | /// Id of custom command 60 | protected override void OnCustomCommand(int command) 61 | { 62 | // perform class specific behavior 63 | ServiceImplementation.OnCustomCommand(command); 64 | } 65 | 66 | /// 67 | /// Called when the Operating System is shutting down 68 | /// 69 | protected override void OnShutdown() 70 | { 71 | // perform class specific behavior 72 | ServiceImplementation.OnShutdown(); 73 | } 74 | 75 | /// 76 | /// Called when service is requested to start 77 | /// 78 | /// The startup arguments array. 79 | protected override void OnStart(string[] args) 80 | { 81 | ServiceImplementation.OnStart(args); 82 | } 83 | 84 | /// 85 | /// Called when service is requested to stop 86 | /// 87 | protected override void OnStop() 88 | { 89 | ServiceImplementation.OnStop(); 90 | } 91 | 92 | /// 93 | /// Set configuration data 94 | /// 95 | /// The service with configuration settings. 96 | private void ConfigureServiceFromAttributes(IWindowsService serviceImplementation) 97 | { 98 | var attribute = serviceImplementation.GetType().GetAttribute(); 99 | 100 | if (attribute != null) 101 | { 102 | // wire up the event log source, if provided 103 | if (!string.IsNullOrWhiteSpace(attribute.EventLogSource)) 104 | { 105 | // assign to the base service's EventLog property for auto-log events. 106 | EventLog.Source = attribute.EventLogSource; 107 | } 108 | 109 | CanStop = attribute.CanStop; 110 | CanPauseAndContinue = attribute.CanPauseAndContinue; 111 | CanShutdown = attribute.CanShutdown; 112 | 113 | // we don't handle: laptop power change event 114 | CanHandlePowerEvent = false; 115 | 116 | // we don't handle: Term Services session event 117 | CanHandleSessionChangeEvent = false; 118 | 119 | // always auto-event-log 120 | AutoLog = true; 121 | } 122 | else 123 | { 124 | throw new InvalidOperationException( 125 | string.Format("IWindowsService implementer {0} must have a WindowsServiceAttribute.", 126 | serviceImplementation.GetType().FullName)); 127 | } 128 | } 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /DebuggableService/WindowsServiceInstaller.Designer.cs: -------------------------------------------------------------------------------- 1 | namespace $safeprojectname$.Framework 2 | { 3 | public partial class WindowsServiceInstaller 4 | { 5 | /// 6 | /// Required designer variable. 7 | /// 8 | private System.ComponentModel.IContainer components = null; 9 | 10 | /// 11 | /// Clean up any resources being used. 12 | /// 13 | /// true if managed resources should be disposed; otherwise, false. 14 | protected override void Dispose(bool disposing) 15 | { 16 | if (disposing && (components != null)) 17 | { 18 | components.Dispose(); 19 | } 20 | base.Dispose(disposing); 21 | } 22 | 23 | #region Component Designer generated code 24 | 25 | /// 26 | /// Required method for Designer support - do not modify 27 | /// the contents of this method with the code editor. 28 | /// 29 | private void InitializeComponent() 30 | { 31 | components = new System.ComponentModel.Container(); 32 | } 33 | 34 | #endregion 35 | } 36 | } -------------------------------------------------------------------------------- /DebuggableService/WindowsServiceInstaller.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections; 3 | using System.ComponentModel; 4 | using System.Configuration.Install; 5 | using System.Diagnostics; 6 | using System.Reflection; 7 | using System.ServiceProcess; 8 | using System.Linq; 9 | 10 | namespace $safeprojectname$.Framework 11 | { 12 | /// 13 | /// A generic windows service installer 14 | /// 15 | [RunInstaller(true)] 16 | public partial class WindowsServiceInstaller : Installer 17 | { 18 | /// 19 | /// Gets or sets the type of the windows service to install. 20 | /// 21 | public WindowsServiceAttribute Configuration { get; set; } 22 | 23 | 24 | /// 25 | /// Creates a blank windows service installer with configuration in ServiceImplementation 26 | /// 27 | public WindowsServiceInstaller() : this (typeof(ServiceImplementation)) 28 | { 29 | } 30 | 31 | 32 | /// 33 | /// Creates a windows service installer using the type specified. 34 | /// 35 | /// The type of the windows service to install. 36 | public WindowsServiceInstaller(Type windowsServiceType) 37 | { 38 | if (!windowsServiceType.GetInterfaces().Contains(typeof(IWindowsService))) 39 | { 40 | throw new ArgumentException("Type to install must implement IWindowsService.", 41 | "windowsServiceType"); 42 | } 43 | 44 | var attribute = windowsServiceType.GetAttribute(); 45 | 46 | if (attribute == null) 47 | { 48 | throw new ArgumentException("Type to install must be marked with a WindowsServiceAttribute.", 49 | "windowsServiceType"); 50 | } 51 | 52 | Configuration = attribute; 53 | } 54 | 55 | 56 | /// 57 | /// Performs a transacted installation at run-time of the AutoCounterInstaller and any other listed installers. 58 | /// 59 | /// The other installers to include in the transaction 60 | /// The IWindowsService implementer to install. 61 | public static void RuntimeInstall() 62 | where T : IWindowsService 63 | { 64 | string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location; 65 | 66 | using (var ti = new TransactedInstaller()) 67 | { 68 | ti.Installers.Add(new WindowsServiceInstaller(typeof (T))); 69 | ti.Context = new InstallContext(null, new [] { path }); 70 | ti.Install(new Hashtable()); 71 | } 72 | } 73 | 74 | 75 | /// 76 | /// Performs a transacted un-installation at run-time of the AutoCounterInstaller and any other listed installers. 77 | /// 78 | /// The other installers to include in the transaction 79 | /// The IWindowsService implementer to install. 80 | public static void RuntimeUnInstall(params Installer[] otherInstallers) 81 | where T : IWindowsService 82 | { 83 | string path = "/assemblypath=" + Assembly.GetEntryAssembly().Location; 84 | 85 | using (var ti = new TransactedInstaller()) 86 | { 87 | ti.Installers.Add(new WindowsServiceInstaller(typeof (T))); 88 | ti.Context = new InstallContext(null, new [] { path }); 89 | ti.Uninstall(null); 90 | } 91 | } 92 | 93 | 94 | /// 95 | /// Installer class, to use run InstallUtil against this .exe 96 | /// 97 | /// The saved state for the installation. 98 | public override void Install(System.Collections.IDictionary savedState) 99 | { 100 | ConsoleHarness.WriteToConsole(ConsoleColor.White, "Installing service {0}.", Configuration.Name); 101 | 102 | // install the service 103 | ConfigureInstallers(); 104 | base.Install(savedState); 105 | 106 | // wire up the event log source, if provided 107 | if (!string.IsNullOrWhiteSpace(Configuration.EventLogSource)) 108 | { 109 | // create the source if it doesn't exist 110 | if (!EventLog.SourceExists(Configuration.EventLogSource)) 111 | { 112 | EventLog.CreateEventSource(Configuration.EventLogSource, "Application"); 113 | } 114 | } 115 | } 116 | 117 | 118 | /// 119 | /// Removes the counters, then calls the base uninstall. 120 | /// 121 | /// The saved state for the installation. 122 | public override void Uninstall(System.Collections.IDictionary savedState) 123 | { 124 | ConsoleHarness.WriteToConsole(ConsoleColor.White, "Un-Installing service {0}.", Configuration.Name); 125 | 126 | // load the assembly file name and the config 127 | ConfigureInstallers(); 128 | base.Uninstall(savedState); 129 | 130 | // wire up the event log source, if provided 131 | if (!string.IsNullOrWhiteSpace(Configuration.EventLogSource)) 132 | { 133 | // create the source if it doesn't exist 134 | if (EventLog.SourceExists(Configuration.EventLogSource)) 135 | { 136 | EventLog.DeleteEventSource(Configuration.EventLogSource); 137 | } 138 | } 139 | } 140 | 141 | 142 | /// 143 | /// Rolls back to the state of the counter, and performs the normal rollback. 144 | /// 145 | /// The saved state for the installation. 146 | public override void Rollback(System.Collections.IDictionary savedState) 147 | { 148 | ConsoleHarness.WriteToConsole(ConsoleColor.White, "Rolling back service {0}.", Configuration.Name); 149 | 150 | // load the assembly file name and the config 151 | ConfigureInstallers(); 152 | base.Rollback(savedState); 153 | } 154 | 155 | 156 | /// 157 | /// Method to configure the installers 158 | /// 159 | private void ConfigureInstallers() 160 | { 161 | // load the assembly file name and the config 162 | Installers.Add(ConfigureProcessInstaller()); 163 | Installers.Add(ConfigureServiceInstaller()); 164 | } 165 | 166 | 167 | /// 168 | /// Helper method to configure a process installer for this windows service 169 | /// 170 | /// Process installer for this service 171 | private ServiceProcessInstaller ConfigureProcessInstaller() 172 | { 173 | var result = new ServiceProcessInstaller(); 174 | 175 | // if a user name is not provided, will run under local service acct 176 | if (string.IsNullOrEmpty(Configuration.UserName)) 177 | { 178 | result.Account = ServiceAccount.LocalService; 179 | result.Username = null; 180 | result.Password = null; 181 | } 182 | else 183 | { 184 | // otherwise, runs under the specified user authority 185 | result.Account = ServiceAccount.User; 186 | result.Username = Configuration.UserName; 187 | result.Password = Configuration.Password; 188 | } 189 | 190 | return result; 191 | } 192 | 193 | 194 | /// 195 | /// Helper method to configure a service installer for this windows service 196 | /// 197 | /// Process installer for this service 198 | private ServiceInstaller ConfigureServiceInstaller() 199 | { 200 | // create and config a service installer 201 | var result = new ServiceInstaller 202 | { 203 | ServiceName = Configuration.Name, 204 | DisplayName = Configuration.DisplayName, 205 | Description = Configuration.Description, 206 | StartType = Configuration.StartMode, 207 | ServicesDependedOn = Configuration.ServiceDependsOn 208 | }; 209 | 210 | return result; 211 | } 212 | } 213 | } -------------------------------------------------------------------------------- /DebuggableServiceSetup/DebuggableService.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobThree/DebuggableSelfInstallingService/e2d3aca9c0b79e9f9aa39a18b75ef4549dbd9efa/DebuggableServiceSetup/DebuggableService.ico -------------------------------------------------------------------------------- /DebuggableServiceSetup/DebuggableServiceSetup.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 14.0 5 | $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion) 6 | 7 | 8 | 9 | 10 | Debug 11 | AnyCPU 12 | 2.0 13 | {82b43b9b-a64c-4715-b499-d71e9ca2bd60};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 14 | {5CE9E1DB-7A1B-4425-BD2E-22E9EB5BB5F4} 15 | Library 16 | Properties 17 | DebuggableServiceSetup 18 | DebuggableServiceSetup 19 | v4.7.2 20 | false 21 | false 22 | false 23 | false 24 | false 25 | false 26 | 27 | 28 | true 29 | full 30 | false 31 | bin\Debug\ 32 | DEBUG;TRACE 33 | prompt 34 | 4 35 | 36 | 37 | pdbonly 38 | true 39 | bin\Release\ 40 | TRACE 41 | prompt 42 | 4 43 | 44 | 45 | 46 | 47 | 48 | 49 | Designer 50 | 51 | 52 | 53 | 54 | Always 55 | true 56 | 57 | 58 | Always 59 | true 60 | 61 | 62 | Always 63 | true 64 | 65 | 66 | 67 | 68 | {38EBE914-5286-4822-822F-F248DB63C973} 69 | DebuggableService 70 | ProjectTemplates 71 | false 72 | TemplateProjectOutputGroup%3b 73 | 74 | 75 | 76 | 77 | 84 | -------------------------------------------------------------------------------- /DebuggableServiceSetup/LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Rob Janssen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DebuggableServiceSetup/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("DebuggableServiceSetup")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("DebuggableServiceSetup")] 13 | [assembly: AssemblyCopyright("Copyright © RobIII 2016 - 2018")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // Version information for an assembly consists of the following four values: 23 | // 24 | // Major Version 25 | // Minor Version 26 | // Build Number 27 | // Revision 28 | // 29 | // You can specify all the values or you can default the Build and Revision Numbers 30 | // by using the '*' as shown below: 31 | // [assembly: AssemblyVersion("1.0.*")] 32 | [assembly: AssemblyVersion("1.1.0.0")] 33 | [assembly: AssemblyFileVersion("1.1.0.0")] 34 | -------------------------------------------------------------------------------- /DebuggableServiceSetup/source.extension.vsixmanifest: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DebuggableService 6 | A Windows Service project template that is easier to run and debug than the default Windows Service project template 7 | https://github.com/RobThree/DebuggableSelfInstallingService 8 | LICENSE.txt 9 | https://github.com/RobThree/DebuggableSelfInstallingService/blob/master/README.md 10 | DebuggableService.ico 11 | worm-gear-icon.png 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DebuggableServiceSetup/worm-gear-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobThree/DebuggableSelfInstallingService/e2d3aca9c0b79e9f9aa39a18b75ef4549dbd9efa/DebuggableServiceSetup/worm-gear-icon.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Rob Janssen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Debuggable, Self-Installing, Windows Service 2 | A Debuggable, Self-Installing Windows Service Template based on [James Michael Hare](http://geekswithblogs.net/BlackRabbitCoder)'s excellent blogposts: 3 | 4 | * [C# Toolbox: A Debuggable, Self-Installing Windows Service Template (1 of 2)](http://blackrabbitcoder.net/archive/2010/09/23/c-windows-services-1-of-2-creating-a-debuggable-windows.aspx) 5 | * [C# Toolbox: A Debuggable, Self-Installing Windows Service Template (2 of 2)](http://blackrabbitcoder.net/archive/2010/10/07/c-windows-services-2-of-2-self-installing-windows-service-template.aspx) 6 | 7 | ## How to use ## 8 | 9 | * Download [the Visual Studio template](https://visualstudiogallery.msdn.microsoft.com/013760d0-d02f-45fe-9fc5-740251e1b30c) 10 | * Create a new project and select / search for `DebuggableService` (see screenshot below) 11 | * Implement any of the provided `OnStart()`, `OnStop()`, `OnPause()`, `OnContinue()`, `OnShutDown()` and `OnCustomCommand()` methods 12 | * Run/debug your application as usual, continue your development cycle as always 13 | * When your application is done, open a console (with Administrative privileges!) and execute `MyApp.exe -install`to install your service; now you can start/stop/pause your service. To uninstall your service simply run `MyApp.exe -uninstall`. 14 | 15 | ![Screenshot of project template selector](newproject.png) 16 | 17 | ## More ## 18 | 19 | The `WindowsService.cs` file contains the `ServiceImplementation` class which, as it's name suggests, implements all service methods. This class has been fitted with an `WindowsServiceAttribute` which you can use to control some service-specific properties like `Name`, `DisplayName`, `Description`, `UserName`, `Password`, `EventLogSource`, `StartMode`, `CanPauseAndContinue`, `CanShutdown`, `CanStop` and services your service depends on via `ServiceDependsOn`. 20 | 21 | ## But I want more! ## 22 | 23 | Sure! No problem. I can recommend the excellent [Topshelf](http://topshelf-project.com/) project, also available as [NuGet package](https://www.nuget.org/packages/Topshelf/). This allows for even more control, has [way better documentation](https://topshelf.readthedocs.org/en/latest/) and is [also available on GitHub](https://github.com/Topshelf/Topshelf)! 24 | 25 | ## Project status 26 | 27 | Works (tested) with: 28 | * Visual Studio 2013 29 | * Visual Studio 2015 30 | * Visual Studio 2017 31 | * Visual Studio 2019 32 | 33 | ![Project status](http://riii.nl/womm) 34 | -------------------------------------------------------------------------------- /newproject.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RobThree/DebuggableSelfInstallingService/e2d3aca9c0b79e9f9aa39a18b75ef4549dbd9efa/newproject.png --------------------------------------------------------------------------------