1

I have written a program which runs automatically. It affects how the computer is used and so if there is an issue with the program settings the computer could be unusable.

I would like the program to detect when the computer boots in safe mode in order to open the program's recovery menu. I found this solution, but it looks to be for C++ only.

I am writing a WPF app in .NET Framework and want to check the safe mode status for a Windows 10 computer.

Edit: I intend for the program to be run manually in safe mode, it detects that it is in safe mode, so opens the recovery menu instead of the normal program.

230Daniel
  • 432
  • 3
  • 16
  • 6
    How do you manage to run your program _automatically_ when the computer boots in Safe Mode? – Steve Apr 11 '19 at 09:45
  • 4
    Isn't the whole point of `Safe Mode` that it won't start programs that are set to run automatically, and only start those that are essential to run Windows? – Rand Random Apr 11 '19 at 09:46
  • 1
    You could use the C++ solution by importing the User32.dll – royalTS Apr 11 '19 at 09:46
  • You can call user32.lib functions from C# - so it shouldn't be too much of a problem converting the C++ code : https://stackoverflow.com/questions/17912352/cant-import-user32-dll-into-visual-studio – PaulF Apr 11 '19 at 09:46
  • 1
    @Steve Thanks for pointing this out, I have edited my answer to clarify this. I intend for the program to be run manually when safe mode is entered, then it opens the recovery menu. – 230Daniel Apr 11 '19 at 10:19
  • 1
    You can call Windows API from C# code then. There is a site ([PInvoke](http://pinvoke.net/)) that could help you to define the syntax required to call GetSystemMetrics – Steve Apr 11 '19 at 10:26
  • There is also a project on GitHub to a library for these calls https://github.com/inspiredtechnologies/SystemMetrics/ – Steve Apr 11 '19 at 10:31

1 Answers1

1

This is fundamentally a Windows API question, so the solution is the same in all languages: call the GetSystemMetrics API function, requesting the SM_CLEANBOOT metric. This will return an integer value indicating how the system was booted. In particular:

  • 0 means a normal boot,
  • 1 means a fail-safe ("safe mode") boot,
  • 2 means a fail-safe boot with networking support.

The only challenge, then, is how to call this function from managed code. The .NET Framework and C# language allow you to P/Invoke native functions. To do so, you need to provide a declaration of the native function you want to call, and you'll also want to define some types (enumerations, etc.). Sample code:

internal const int SM_CLEANBOOT = 67;

[DllImport("user32.dll")]
internal static extern int GetSystemMetrics(int smIndex);

A more complete code sample, including a full enumerated type for all of the system metrics is available on pinvoke.net.

Note that what Steve and Rand Random mentioned in comments is correct. In safe mode, your application will not be launching automatically—and you shouldn't want it to. This detection is something you'll need to do manually at application startup, and only if you are actually going to behave differently.

Don't assume that the user booting up in safe mode implies that they want to enter recovery mode in your program. System problems and application problems are completely independent. You should simply provide a way to enter recovery mode as part of your application—perhaps a command-line switch. Don't use a global solution for a local problem.

Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574