|
Richard MacCutchan wrote: relevant to VS either
From the post
"when I then pull my internal nuget into a project,"
I figured that mean using a project via VS.
One can manage them outside of VS but I doubt many people do. Certainly I would presume that most do it in VS so that is how I read it.
|
|
|
|
|
It seems that the .NET 8 infrastructure code that interacts with the service control manager provides a layer of abstraction over the Start and Stop commands.
Therefore I don't see how to directly issue a service stop command. The service is passed a CancellationToken object, but I've been informed that you can't cancel such a token without access to the CancellationTokenSource.
When the service runs, all I have is the token, not the source.
So how do I shutdown and exit the service from code running inside the service?
SOLUTION:
Below is the template code produced by Visual Studio when you create a .NET 8 Windows service:
I simply created a property on the service class itself that can be set from inside the service and indicates to the outside world whether the service wants to shut down.
I called it StopFlag .
public sealed class WindowsBackgroundService(
MyWindowsService myWindowsService,
ILogger<WindowsBackgroundService> logger) : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
try
{
myWindowsService.OnStart(new string[0]);
while (!stoppingToken.IsCancellationRequested && !myWindowsService.StopFlag)
{
await Task.Delay(TimeSpan.FromSeconds(1), stoppingToken);
}
}
catch (OperationCanceledException)
{
}
catch (Exception ex)
{
logger.LogError(ex, "{Message}", ex.Message);
Environment.Exit(1);
}
}
}
The difficult we do right away...
...the impossible takes slightly longer.
modified 11-Feb-24 15:36pm.
|
|
|
|
|
|
Griff, thanks for the reply.
The method and object you mention are only in the .NET Framework.
I recently upgraded the service to .NET 8, which uses a different paradigm.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Store a "semaphore" (or "command code") somewhere and have the service look at it every so often. Use pull instead of push, and let it shut itself down.
"Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I
|
|
|
|
|
Richard Andrew x64 wrote: logger.LogError(ex, "{Message}", ex.Message);
Just noting that from the support position I have found it useful to log both when it started and when it stopped, regardless of why it stopped.
|
|
|
|
|
I have some simple code that worked when it was running on the .NET Framework 4.8, but after converting the project to .NET 8.0, the code is unable to open a subkey under HKLM because of an "UnauthorizedAccess Exception".
try
{
using (RegistryKey BaseKey =
RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64))
{
using (RegistryKey SubKey =
BaseKey.CreateSubKey("Software\\CompanyName\\ProductName"))
{
DatabasePath = SubKey.GetValue("DBPath") as string;
SubKey.Close();
BaseKey.Close();
return Result.Success();
}
}
}
FACTS:
The registry key already exists when this code runs.
The code is running under the LocalSystem account as a Windows Service.
The initial open of the base key, HKLM apparently succeeds, but the BaseKey.Handle member is null immediately after the call to OpenBaseKey and before CreateSubKey.
Please ask for more details.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Got any anti-virus running? I've seen Trend get in the way like this before, though that was quite a bit ago.
|
|
|
|
|
To be honest, you shouldn't really be using the Registry at all - access to it is going to get more restrictive rather than less as OS's advance.
There are other ways to store info, particularly paths to DB that don't require the registry - here is the one I use: Instance Storage - A Simple Way to Share Configuration Data among Applications[^]
I created it because I have multiple apps which need access to the same DB server and when I changed PC name I had to update loads of different apps. Now, they all use the same data on each machine and it's a single change on each PC to get the connection string. It may be a little overkill for you situation, but It's made my life a load easier!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
When the keys are little sandboxes only pertaining to your application, why wouldn't you want that centralized there and why wouldn't they make it work more like that?
I don't really disagree and could see it going as you say... ditch the registry. I just don't get why IF the context is little sandboxed subsections of the registry instead of "you can edit anything or you can edit nothing".
|
|
|
|
|
That was the original idea: a single centralized depository for all config info. So it grew and grew, and bloated massively, slowed down everything and became a source of problems because there was no defined (or enforceable) separation of App A info from App B, much less system related info. It also added a route by which trojans could inject themselves into other apps very simply by modifying the config info.
So it became depreciated as a centralized store for new apps because of the problems it caused, and security features evolved as UAC was introduced which deliberately made it harder to use. Those continue to become more restrictive as the OS evolves - at some point it will probably become off limits to all non-admin apps (it's only not at present for backward compatibility with legacy applications).
If it had been designed as a sandbox environment in the first place, it could have been a really useful secure store - but it never was and that lack of foresight shows in the zombie version we currently have!
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
modified 14-Feb-24 3:02am.
|
|
|
|
|
Richard Andrew x64 wrote: The registry key already exists when this code runs.
In that case, why are you using CreateSubKey rather than OpenSubKey ?
CreateSubKey will attempt to create or open the key for write access. Since you're not writing to it, you should open it for read access instead.
Also note that the RegistryView is only required if your app is compiled as 32-bit and needs to access the 64-bit registry, or vice-versa.
Beyond that, you need to check the ACL on the specific registry key you're trying to open. It's possible that the system account has been denied (or has not been granted) access.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Richard Andrew x64 wrote: The registry key already exists when this code runs. The exception doesn't complain about it not existing.
Richard Andrew x64 wrote: The code is running under the LocalSystem account as a Windows Service. Which is, as documented, a limited account.
Richard Andrew x64 wrote: The initial open of the base key, HKLM apparently succeeds, but the BaseKey.Handle member is null immediately after the call to OpenBaseKey and before CreateSubKey. That might be a hint
Bastard Programmer from Hell
"If you just follow the bacon Eddy, wherever it leads you, then you won't have to think about politics." -- Some Bell.
|
|
|
|
|
This comes from a comment in a prior post.
Global Usings – A Look at New Language Features in C# 10 | The .NET Tools Blog[^]
"With C# 10 you can use global using directives that the compiler will consider for the whole project"
To me this is just going to lead to similar problems as in C++ where one puts all of their includes in one include file and then uses that single include file everywhere.
It is indeed convenient.
But that doesn't mean that it should be used. Nor should it even exist.
When looking at a single source file one shouldn't need to be concerned about the impact that other files might have.
|
|
|
|
|
jschell wrote: When looking at a single source file one shouldn't need to be concerned about the impact that other files might have.
That's probably an unrealistic ideal.
For example, the project file controls the C# language level, which can fundamentally change the meaning of the code in your C# files.
The project file determines which assemblies/packages you're referencing, which can also change the meaning and/or behaviour of the code.
Even going back to VB6, IIRC there was a project level "option base" setting which would change the default lower bound for array declarations which didn't explicitly specify one.
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Yeah I'm not a fan. I'm not even all that wild about the namespace MyNameSpace; vs namespace MyNameSpace { } but mostly just because it breaks the code if someone happens to not be on more recent tooling.
|
|
|
|
|
Hi All,
I am trying to set up a 'framework' (not the right term) as I need to make use of using code sample below:
using System;
using Phidget22;
using Phidget22.Events;
I have got the example code set up and working example to compile but this is too complex for the function I am trying to do, I think as the correct steps have been followed to access the files. I think something has changed with the way to set up projects so they can see an external using file (or more likely I didn't do it properly!)
Glenn
|
|
|
|
|
Hi Glenn, it's not clear what your problem/question is.
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
To be perfectly honest neither am I, what I am trying to is be able from a Console app in C# 2022 to access the files used in the using statements above. I think I have it installed correctly as the example compiles and runs.
So is there a guide for doing this? I have had a Google and get not the right results. Last time I had to do something like this it was place the dll in the directory that doesn't seem to work...
|
|
|
|
|
Did you add a reference to the DLL in your C# project?
The difficult we do right away...
...the impossible takes slightly longer.
|
|
|
|
|
Hmm, it's a case of 'browse' to the DLL click OK and get a message it can't see it (but you can browse to it!)
|
|
|
|
|
|
|
Hi, I just upgraded a .NET Framework project to .NET 8.0 using the .NET Upgrade Assistant extension for Visual Studio from Microsoft.
I added a reference in the Dependencies folder to System.ServiceProcess.ServiceController.dll in the "C:\Program Files\dotnet\sdk\8.0.101" disk folder.
For some reason, it's unable to resolve types within that DLL (such as ServiceBase ) and the reference in the Dependencies folder has a yellow triangle with an exclamation mark.
Is the project fubared because it was in-place upgraded, or is there something else wrong?
Why can't it resolve the types within that DLL, and why does the reference node have that yellow triangle icon? When I mouse over the icon, it doesn't display any tooltip to tell me what's wrong.
SOLUTION:
I added the file from the wrong folder. When I changed the reference to point to the same assembly in the "C:\Program Files\dotnet\sdk\8.0.101\runtimes\win\lib\net8.0\" folder, it resolved all the issues.
Thanks for reading my post.
The difficult we do right away...
...the impossible takes slightly longer.
modified 3-Feb-24 8:45am.
|
|
|
|
|