I am currently writing an app to start the screensaver on Windows 10 and show the screen instead of a black background. So that Bubbles and relatives can act like in older OS version.
Here is my full code:
using Microsoft.Win32;
using System;
using System.Diagnostics;
using System.IO;
using System.Windows.Forms;
public class DrawOverMyScreen {
public static void Main(string[] CommandLine) {
switch (CommandLine[0]) {
case "/c":
DialogResult Answer = MessageBox.Show("What do you want to do?\n\n - Press \"Yes\" to configure the screensaver\n - Press \"No\" to change the screensaver\n - Press \"Cancel\" to do nothing", "DrawOverMyScreen Configuration", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button3);
switch (Answer) {
case DialogResult.Yes:
Screensaver("/c");
break;
case DialogResult.No:
throw new NotImplementedException();
break;
default:
break;
}
break;
default:
Screensaver("/s");
break;
}
}
public static void Screensaver(string CommandLine) {
RegistryKey Settings = Registry.CurrentUser.OpenSubKey(@"SOFTWARE\DrawOverMyScreen");
if (Settings != null) {
string ScreensaverLocation = Settings.GetValue("Screensaver", string.Empty).ToString();
if (!string.IsNullOrEmpty(ScreensaverLocation) && File.Exists(ScreensaverLocation)) {
Process Screensaver = Process.Start(new ProcessStartInfo(ScreensaverLocation, CommandLine));
Screensaver.WaitForExit();
}
}
}
}
Notice the Screensaver
method. It uses Process.Start(new ProcessStartInfo(ScreensaverLocation, CommandLine));
to start the screensaver. But whenever I do Screensaver("/c");
to run the screensaver's config utility, I only get the normal screensaver view (The one you get when idle after a certain time). Using the run prompt like this: C:\Windows\SysWOW64\SCREEN~1.SCR /c
also gives the same result, but command line prompt actually opens the config utility.
Why won't it work, and how can I make it so it works?
Just from what you have provided, I can't tell you why it won't work. I do not have a screensaver to test that with (that I know of). But I'm able to do all four of these with Notepad opening a text file:
Separate ProcessStartInfo
ProcessStartInfo procInfo = new ProcessStartInfo("notepad.exe", "c:\\test.txt");
Process proc = Process.Start(procInfo);
proc.WaitForExit();
Separate ProcessStartInfo with Properties
ProcessStartInfo procInfo = new ProcessStartInfo();
procInfo.Arguments = "c:\\test.txt";
procInfo.FileName = "notepad.exe";
Process proc = Process.Start(procInfo);
proc.WaitForExit();
Inline ProcessStartInfo
Process proc = Process.Start(new ProcessStartInfo("notepad.exe", "c:\\test.txt"));
proc.WaitForExit();
No PSI, Just Process
Process proc = Process.Start("notepad.exe", "c:\\test.txt");
proc.WaitForExit();
You may want to go with the first one so that you can breakpoint on the "Process proc..." line and examine the properties of procInfo
. The Arguments
property should show the 2nd value (in my case, c:\\test.txt
), and the FileName
property should be the path to what you are executing (mine is notepad.exe
).
EDIT: I added the separate one with properties so you can really see explicit setting.
I have worked out an example using the 3D Text screensaver:
string scrPath = @"C:\Windows\System32\ssText3d.scr";
ProcessStartInfo procInfo = new ProcessStartInfo();
procInfo.FileName = scrPath;
procInfo.Verb = "config";
procInfo.UseShellExecute = false;
Process proc = Process.Start(procInfo);
proc.WaitForExit();
I didn't use the Arguments
. Instead, I used the Verb
. This requires UseShellExecute
to be set to false
. I got the expected configuration dialog instead of the screensaver running.
More About Verbs
This is where the verbs are for screen savers.
You can also define custom verbs: Register an Application to Handle Arbitrary File Types