Is there any way to specify a service name in the app.config file? - windows-services

I want to specify my service name in the app.config without needing to recomple and install/uninstall my service repeatedly.
But just retrieving service name from app.config, the service seems ignoring it. Are there any special tricks how to obtain this?
Thanks in advance.
I mean classic windows service. I don't think any code is needed here. I just want to retrieve the service name from app.config dynamically.

After searching a while on the internet and reading articles, it became clearer to me that A service name can't be specified in the app.config in so dynamic way, instead sc command can be used to perform a similar solution. You can specify other configuration variables in the app.config and use sc to rename it
sc.exe create "servicename" binPath="myservicepath.exe"

I am not sure what scenario you have in mind. You would like the name of your Windows service to change. Fair enough. When would it change?
Imagine you have found the solution and created such a Windows service. I presume in your scenario you would install it at least the first time. Then you do not want to uninstall/install it. But presumably you would like to start/stop and do other things with it. Will one of those actions cause the name of the service to change?
If so, I imagine you could launch a process that uninstalls and installs it with a different name for you transparently, based on some kind of naming logic.
I don't see how else you could do it.
Or just come up with a really generic name to cover all possibilities (which might be incredibly simple or incredibly difficult).

http://www.codeproject.com/Articles/21320/Multiple-Instance-NET-Windows-Service
<add key="ServiceName" value="I"/>
[RunInstaller(true)]
public class ServiceInstaller1 : Installer
{
internal static string ServiceNameDefault = "My Service";
internal static string ServiceName = GetConfigurationValue("ServiceName");
/// <summary>
/// Public Constructor for WindowsServiceInstaller.
/// - Put all of your Initialization code here.
/// </summary>
public ServiceInstaller1()
{
var serviceProcessInstaller = new ServiceProcessInstaller();
var serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
//serviceProcessInstaller.Username = null;
//serviceProcessInstaller.Password = null;
//# Service Information
serviceInstaller.DisplayName = ServiceName;
serviceInstaller.StartType = ServiceStartMode.Manual;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = ServiceName;
Installers.Add(serviceProcessInstaller);
Installers.Add(serviceInstaller);
}
private static string GetConfigurationValue(string key)
{
Assembly service = Assembly.GetAssembly(typeof(Service));
Configuration config = ConfigurationManager.OpenExeConfiguration(service.Location);
if (config.AppSettings.Settings[key] != null)
return ServiceNameDefault + " " + config.AppSettings.Settings[key].Value;
else
return ServiceNameDefault;
}
}

Assuming you mean Windows Service, the answer is no. The service has to be installed in the registry, and the name is one of the registry keys.

I'm afraid that what you are trying to do its not possible. It actually seems to go against the nature of a Windows Service purpose and current behavior.
After a windows service is installed the name can't be changed without re-installing it again. What actually names the service is an element called service installer. Which by now, I assume you know what it is and where its located.
However there are ways of manipulating an installed service by using Windows Management Instrumentation (WMI). Maybe this combined with Izabela's recommendation become the right path to your solution.
I would recommend you to read the following tutorial, you might find an alternate way of achieving what you're trying to do.
http://www.serverwatch.com/tutorials/article.php/1576131/Windows-Services-Management-With-WMI-Part-1.htm

Related

.NET Core - registering services, how to register separate version of a service

I have an interface IService and two implementations ServiceA and ServiceB.
For most of the time I want to use implementation A, but I also have another service that wants implementation B. Is there a way of doing just that? It should look something like this:
services.AddScoped<IService, ServiceA>();
services.AddScoped<ISomethingElse, SomethingElse>();
services.WhenResolving<ISomethingElse>.AddScoped<IService, ServiceB>();
I am going to mention two versions of doing this.
First, Let say that you have configuration parameter and according to your configuration parameter you decide which service will be resolved by your Interface
then
services.AddScoped<ISomethingElseService, SomethingService>();
if (Configuration["MyServiceParam"] == "X")
services.AddScoped<ISomethingService, SomethingElseService>();
the other option is
services.AddScoped<ISomethingService>(s => {
var MyServiceA = s.GetService<MyServiceA>();
if (MyServiceA is null)
return new SomethingElseService();
else
return new SomethingService(MyServiceA);
});

Sporadic "an interface and cannot be constructed. Are you missing a type mapping"

Initial deployment of the site works fine. After about 2-3 hours, the controllers suddenly cannot be instantiated due to a dependency cannot be resolved (or at least that's what the error message tells me).
I have tried various things, but none of which seem to resolve it. Does anyone have any ideas what I can check?
Recently we had a similar situation with one of our Interceptors. All of a sudden it would no longer work. We intercept all calls to interfaces defined in assembly X.Y.Z.dll. But the OS decided to call the file X.Y.Z.DLL after a while. No new deployment happened in the meantime. But all of a sudden the name matching failed. Do you load some assemblies in your configuration by name? Maybe you should check for IgnoreCase in string comparisons.
Another idea: Do you use some kind of cache for your objects? Or a cache based LifetimeManager? If cache items get invalidated after some time you would loose those objects.
i still have no idea what was happening, but i managed to fix it. i was using a third-party bootstrapping library to register my components and mappings. but after rolling my own with MEF, and controlling the registrations myself, the issue went away. i'm guessing it was doing something funky by disposing things when it shouldn't have. thanks for the help.
In case someone encounters this problem using http://bootstrapper.codeplex.com/ with the following declaration:
Bootstrap.Bootstrapper
.With.Unity()
.And.AutoMapper()
.And.ServiceLocator()
.Start();
I replaced that with:
IUnityContainer container = new UnityContainer();
MEFContainer mefContainer = new MEFContainer();
mefContainer.UnityRegistry.ForEach(x => x.Register(container));
container.RegisterInstance<IMappingEngine>(Mapper.Engine);
mefContainer.AutoMapperRegistry.ForEach(x => x.CreateMap(Mapper.Configuration));
where
private class MEFContainer
{
[ImportMany(typeof(IUnityRegistration))]
public List<IUnityRegistration> UnityRegistry { get; set; }
[ImportMany(typeof(IMapCreator))]
public List<IMapCreator> AutoMapperRegistry { get; set; }
public MEFContainer()
{
var catalog = new DirectoryCatalog("bin");
var compositionContainer = new CompositionContainer(catalog);
compositionContainer.ComposeParts(this);
}
}
Note that IUnityRegistration.Register() and IMapCreator.CreateMap() are defined in the third-party code. MEF references System.ComponentModel.Composition
and System.ComponentModel.Composition.Hosting. Will eventually refactor.

Is there a relatively easy way for a hybrid .Net exe (console app/Windows service) to install and start itself as a service?

Suppose an executable named ConsoleOrService.exe is written in C#. It currently is a hybrid. I can just start it on the command line, or I can install it using the .Net's installutil ConsoleOrService.exe and then start the service. I would like a third option: running it on the command line like so: ConsoleOrService.exe --install and have it do all of the work.
Is this possible?
Is this hard?
How can I get started?
Thank you, and let me know if there are questions please.
It's actually quite simple. I've used it in many of my own services (in fact, ALL of my services are capable of doing their own install/uninstall. I control it with a command-line switch, such as /install or /uninstall.
The installation is performed like this:
private static void InstallService()
{
var ti = new System.Configuration.Install.TransactedInstaller();
var si = new MyServiceInstaller();
var cl = new string[] { string.Format(CultureInfo.InvariantCulture, "/assemblypath={0}", System.Reflection.Assembly.GetExecutingAssembly().Location) };
var ctx = new System.Configuration.Install.InstallContext(null, cl);
ti.Installers.Add(si);
ti.Context = ctx;
ti.Install(new Hashtable());
}
The uninstallation is the same, except that you call ti.Uninstall(null); instead of ti.Install(...);.
My MyServiceInstaller is a class that inherits from the System.Configuration.Install.Installer class (as you would normally have in a service).

Why getting a 202 in two equal setup structuremap code paths

In the C# language, using StructureMap 2.5.4, targeting .NET Framework 3.5 libraries.
I've taken the step to support multiple Profiles in a structure map DI setup, using ServiceLocator model with Bootstrapper activation. First setup was loading default registry, using the scanner.
Now I like to determine runtime what Registry configuration I like to use. Scanning and loading multiple assemblies with registries.
Seems it's not working for the actual implementation (Getting the 202, default instance not found), but a stripped test version does work. The following setup.
Two assemblies containing Registries and implementations
Scanning them in running AppDomain, providing the shared Interface, and requesting Creation Of Instance, using the interfaces in constructor (which get dealt with thanx to the profile on Invokation)
Working code sample below (same structure for other setup, but with more complex stuff, that get's a 202):
What type of couses are possible for a 202, specifically naming the System.Uri type, not being handles by a default type?? (uri makes no sense)
// let structure map create instance of class tester, that provides the registered
// interfaces in the registries to the constructor of tester.
public class Tester<TPOCO>
{
private ITestMe<TPOCO> _tester;
public Tester(ITestMe<TPOCO> some)
{
_tester = some;
}
public string Exec()
{
return _tester.Execute();
}
}
public static class Main {
public void ExecuteDIFunction() {
ObjectFactory.GetInstance<Tester<string>>().Exec();
}
}
public class ImplementedTestMe<TSome> : ITestMe<TSome>
{
public string Execute()
{
return "Special Execution";
}
}
public class RegistryForSpecial : Registry
{
public RegistryForSpecial()
{
CreateProfile("Special",
gc =>
{
gc.For(typeof(ITestMe<>)).UseConcreteType(typeof(ImplementedTestMe<>));
});
}
}
Background articles on Profiles I used.
How to setup named instances using StructureMap profiles?
http://devlicio.us/blogs/derik_whittaker/archive/2009/01/07/setting-up-profiles-in-structuremap-2-5.aspx
http://structuremap.sourceforge.net/RegistryDSL.htm
EDIT:
It seemed the missing interface was actually the one being determined runtime. So here is the next challange (and solved):
I provided a default object whenever StructureMap needs to create the object. Like:
x.ForRequestedType<IConnectionContext>()
.TheDefault.Is.Object(new WebServiceConnection());
This way I got rid of the 202 error, because now a real instance could be used whever structure map needed the type.
Next was the override on runtime. That did not work out at first using the ObjectFactory.Configure method. Instead I used the ObjectFactory.Inject method to overide the default instance. Works like a charm.
ObjectFactory.Inject(typeof(IConnectionContext), context);
Loving the community effort.
Error code 202 means a default instance could not be built for the requested type. Your test code is apparently not equal to your real code that fails. If you are getting an error about Uri, you likely have a dependency that requires a Uri in its constructor. It may not be the class you are asking for - it may be one of that classes dependendencies - or one of the dependencies dependencies... somewhere down the line someone is asking StructureMap to resolve a Uri, which it cannot do, without some help from you.

StructureMap 202 - Why?

OK, I'm trying to set a property on a type I'm registering with SM.
Here's the code from the registry in one of my components. This
registry is being added during the configuration from a console app.
When I try to access the EndorsementSpecs property of the instance
AutoMandatoryEndorsementAggregator object, I get the 202. What's
interesting is that I can call
GetAllInstances>() from my
console app and it resolves just fine. Is there something about
accessing this code from within OnCreation that is causing the 202? I
can see everything I expect in WhatDoIHave(). I've also tried a TypeInterceptor with the same results.
//register all open generics
cfg.ConnectImplementationsToTypesClosing(typeof
(MandatoryEndorsementSpecBase<>));
ForSingletonOf<IMandatoryEndorsementAggregator<AutoPolicy>>()
.Use<AutoMandatoryEndorsementAggregator>()
.OnCreation((context, x) =>
{
var specs =
context.GetAllInstances<MandatoryEndorsementSpecBase<AutoPolicy>>();
x.EndorsementSpecs = specs;
})
;
Sorry to deflect your real questions, but are you just trying to inject all instances of MandatoryEndorsementSpecBase into AutoMandatoryEndorsementAggregatory?
If so, you can probably get away with just making it a constructor parameter so that they are all automatically injected.
public AutoMandatoryEndorsementAggregatory(MandatoryEndorsementSpecBase<AutoPolicy>[] endorsementSpecs){
EndorsementSpecs = endorsementSpecs;
}

Resources