Programmatically change the Windows Shell - c#

I'm working on a project that will be "embedded" into a Windows 7 system, this is going to be achieved by disabling task manager and changing the windows shell to the application, as well as other things.
What I'm looking to do here is programmatically change the Windows shell between the application and explorer.exe, I would like to know if there's any way to do this in C#.
Currently I have a few lines of code that attempt to change the registry entry for the Windows Shell, but nothing appears to happen after refreshing the Registry Editor, the code looks like this:
regKey = Registry.LocalMachine.OpenSubKey("SOFTWARE", true).OpenSubKey("Microsoft", true).OpenSubKey("Windows NT", true).OpenSubKey("CurrentVersion", true).OpenSubKey("Winlogon", true);
regKey.DeleteValue("Shell");
regKey.SetValue("Shell", shell);
regKey.Close();
I've tried restarting windows to see if that allows the shell change to complete, but to no avail.
I'd greatly appreciate it if someone can tell me if it's even possible to do it programmatically, and where I'm going wrong with it.
Also, I'd be grateful to know if there's a way to code the program so that it's always running with admin privileges so that registry editing will work.
Many Thanks,
Richard

After much searching of other locations on the net, I have finally got the Shell to change to the executable file of the application that is being built.
The "Embedding" process is a three step process, in the case of the software I'm working on, we start by disabling Task Manager, We then set the shell executable in the Local Machine registry and then repeat the process in the Current User registry.
Below is the code that achieves this:
public void embedSoftware()
{
try
{
// Disable Task Manager
regKey = Registry.CurrentUser.OpenSubKey(subKey, true).CreateSubKey("System");
regKey.SetValue("DisableTaskMgr", 1);
regKey.Close();
// Change the Local Machine shell executable
regKey = Registry.LocalMachine.OpenSubKey(#"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
regKey.SetValue("Shell", shell, RegistryValueKind.String);
regKey.Close();
// Create the Shell executable Registry entry for Current User
regKey = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows NT\CurrentVersion\Winlogon", true);
regKey.SetValue("Shell", shell);
regKey.Close();
MessageBox.Show("Embedding Complete");
}
catch (Exception e)
{
MessageBox.Show(e.Message);
}
}
In this example the variable "shell" is a string containing the path of the executable to use as the new Windows Shell.
Further to this there's a method to "un-embed" the software, this method simply deletes the "DisableTaskMgr" and "Shell" values from the Current User registries, it also resets the "Shell" value in the Local Machine registry to "explorer.exe".
I hope this helps others out there who're having trouble changing Windows Shells programmatically.
Regards,
Richard

Related

Setting a C# WPF program to start on boot [duplicate]

I have a small application with a CheckBox option that the user can set if they want the app to start with Windows.
My question is how do I actually set the app to run at startup.
ps: I'm using C# with .NET 2.0.
Thanks to everyone for responding so fast.
Joel, I used your option 2 and added a registry key to the "Run" folder of the current user.
Here's the code I used for anyone else who's interested.
using Microsoft.Win32;
private void SetStartup()
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
if (chkStartUp.Checked)
rk.SetValue(AppName, Application.ExecutablePath);
else
rk.DeleteValue(AppName,false);
}
Several options, in order of preference:
Add it to the current user's Startup folder. This requires the least permissions for your app to run, and gives the user the most control and feedback of what's going on. The down-side is it's a little more difficult determining whether to show the checkbox already checked next time they view that screen in your program.
Add it to the HKey_Current_User\Software\Microsoft\Windows\CurrentVersion\Run registry key. The only problem here is it requires write access to the registry, which isn't always available.
Create a Scheduled Task that triggers on User Login
Add it to the HKey_Local_Machine\Software\Microsoft\Windows\CurrentVersion\Run registry key. The only problem here is it requires write access to the registry, which isn't always available.
Set it up as a windows service. Only do this if you really mean it, and you know for sure you want to run this program for all users on the computer.
This answer is older now. Since I wrote this, Windows 10 was released, which changes how the Start Menu folders work... including the Startup folder. It's not yet clear to me how easy it is to just add or remove a file in that folder without also referencing the internal database Windows uses for these locations.
Here is all way to add your program to startup for Windows Vista, 7, 8, 10
File path
C:\Users\Bureau Briffault\AppData\Roaming\Microsoft\Windows\Start
Menu\Programs\Startup (Visible from task manager, Running on current
user login success, No admin privileges required)
C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start
Menu\Programs\Startup (Visible from task manager, Running on all user
login success, Admin privileges required)
Registry path
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Run
(Visible from task manager, Running on current user login success, No
admin privileges required)
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\RunOnce
(Not visible from task manager, Running on current user login success,
Running for one login time, No admin privileges required)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run
(Visible from task manager, Running on all user login success, Admin
privileges required)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce
(Not visible from task manager, Running on all user login success,
Running for one login time, Admin privileges required)
Task scheduler
Microsoft.Win32.Taskscheduler.dll (Not visible from task manager,
Running on windows boot, Running as admin, Admin privileges required)
It`s a so easy solution:
To Add
Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
key.SetValue("Your Application Name", Application.ExecutablePath);
To Remove
Microsoft.Win32.RegistryKey key = Microsoft.Win32.Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
key.DeleteValue("Your Application Name", false);
In addition to Xepher Dotcom's answer, folder path to Windows Startup should be coded that way:
var Startup = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
/// <summary>
/// Add application to Startup of windows
/// </summary>
/// <param name="appName"></param>
/// <param name="path"></param>
public static void AddStartup(string appName, string path)
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
key.SetValue(appName, "\"" + path + "\"");
}
}
/// <summary>
/// Remove application from Startup of windows
/// </summary>
/// <param name="appName"></param>
public static void RemoveStartup(string appName)
{
using (RegistryKey key = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
key.DeleteValue(appName, false);
}
}
You can create a registry entry in "HKCU\Software\Microsoft\Windows\CurrentVersion\Run", just be aware that it may work differently on Vista. Your setting might get "virtualized" because of UAC.
If an application is designed to start when Windows starts (as opposed to when a user logs in), your only option is to involve a Windows Service. Either write the application as a service, or write a simple service that exists only to launch the application.
Writing services can be tricky, and can impose restrictions that may be unacceptable for your particular case. One common design pattern is a front-end/back-end pair, with a service that does the work and an application front-end that communicates with the service to display information to the user.
On the other hand, if you just want your application to start on user login, you can use methods 1 or 2 that Joel Coehoorn listed.
if you using wpf, the "ExecutablePath" don't work. So i made a code that work on wpf too.
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
key.SetValue(
"AutoStart.exe",
"\"" + System.Reflection.Assembly.GetExecutingAssembly().Location + "\""
);
}
I found adding a shortcut to the startup folder to be the easiest way for me. I had to add a reference to "Windows Script Host Object Model" and "Microsoft.CSharp" and then used this code:
IWshRuntimeLibrary.WshShell shell = new IWshRuntimeLibrary.WshShell();
string shortcutAddress = Environment.GetFolderPath(Environment.SpecialFolder.Startup) + #"\MyAppName.lnk";
System.Reflection.Assembly curAssembly = System.Reflection.Assembly.GetExecutingAssembly();
IWshRuntimeLibrary.IWshShortcut shortcut = (IWshRuntimeLibrary.IWshShortcut)shell.CreateShortcut(shortcutAddress);
shortcut.Description = "My App Name";
shortcut.WorkingDirectory = AppDomain.CurrentDomain.BaseDirectory;
shortcut.TargetPath = curAssembly.Location;
shortcut.IconLocation = AppDomain.CurrentDomain.BaseDirectory + #"MyIconName.ico";
shortcut.Save();
You can do this with the win32 class in the Microsoft namespace
using Microsoft.Win32;
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
key.SetValue("aldwin", "\"" + Application.ExecutablePath + "\"");
}
Important addition to other's answers using Application.ExecutablePath: if one of the folders containing your exe contains some strange chars (like mine had C# name) then Application.ExecutablePath will return path with different slashes which will result in it not working.
Application.ExecutablePath.Replace('/', '\\') is more appropriate
Add an app to run automatically at startup in Windows 10
Step 1: Select the Windows Start button and scroll to find the app you want to run at startup.
Step 2: Right-click the app, select More, and then select Open file location. This opens the location where the shortcut to the app is saved. If there isn't an option for Open file location, it means the app can't run at startup.
Step 3: With the file location open, press the Windows logo key + R, type shell:startup, then select OK. This opens the Startup folder.
Step 4: Copy and paste or Create the shortcut to the app from the file location to the Startup folder.

How to launch an application on Login(Not Startup) in Windows Server

Ok i am working on an application which is basically an activity monitor.
This application will automatically log out a user if there is no activity for some time. I have successfully done the logout part.
But i am trying to automatically start the application when another or same user logged in again.
I tried startup code but it only works when windows starts up.
private void SetStartup()
{
RegistryKey rk = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
rk.SetValue("My_App", Application.ExecutablePath);
}
So is there any way to know when someone login in the system.
I am using winform and c#.
Let me know if someone needs more information
Thanks.
You can place a shortcut to your application in the "Startup" folder for all users. The location of this depends on your operating system.
Windows 10: press windows key+R, then type "shell:common startup". Put a shortcut to your application in here.
On Windows 7 it was at "C:\Documents and Settings\All Users\Start Menu\Programs\Startup".
If it's neither of those, add a comment...
Each time someone logs on, the application will be run.

Launch Windows Form Program on Startup

I am using below code for launch my program on startup:
RegistryKey rk = Registry.CurrentUser.OpenSubKey
("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
rk.SetValue(AppName, Application.ExecutablePath);
but when run my project this error occourrs:
System.UnauthorizedAccessException: 'Attempted to perform an unauthorized operation.'
There was this issue a long time ago.
first you need to set registry in HKCU\Software\Microsoft\Windows\CurrentVersion\Run make sure you have enough permissions!:
using (RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true))
{
key.SetValue(AppName, Application.ExecutablePath);
}
Then follow the steps from this post:
Add it to the current user's Startup folder. This requires the least permissions for your app to run, and gives the user the most
control and feedback of what's going on. The down-side is that it's a
little more difficult determining whether to show the checkbox already
checked next time they view that screen in your program.
Add it to the HKey_Current_User\Software\Microsoft\Windows\CurrentVersion\Run
registry key. The only problem here is that it requires write access
to the registry, which isn't always available.
Create a Scheduled Task that triggers on User Login
Add it to the HKey_Local_Machine\Software\Microsoft\Windows\CurrentVersion\Run
registry key. The only problem here is that it requires write access
to the registry, which isn't always available.
Set it up as a windows service. Only do this if you really mean it, and you know for sure you want to run this program for all
users on the computer.

Writing Run (on startup) registry key

My goal is to have my application run on startup.
My problem is my application is not writing to 'Run' in regedit.
I have this code
RegistryKey rWrite = Registry.CurrentUser.OpenSubKey(#"HKey_Current_User\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
and I believe what this is suppose to do is write my application to
HKey_Current_User\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\run
However, this is not writing anything to regedit.
Things to note:
My application forces the user to run in administrator. It essentially checks if they have ran in administrator and if they haven't it displays a messagebox then closes the program with
Environment.Exit(0);
You got the Key with write access (Probably does not exist because you got CurrentUser inside CurrentUser), but you are not setting any values inside. If you want your program to start, you need to set your application path inside. Here's how you would do it:
var rWrite = Registry.CurrentUser.OpenSubKey(#"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
rWrite.SetValue("YourOwnKeyForYourApp",
AppDomain.CurrentDomain.BaseDirectory + AppDomain.CurrentDomain.FriendlyName);

How to start the windows application when we starts the computer

How to start the windows application when we starts the computer. In my application I want to update the current date & time in registry.
The easiest way is to add it to the "startup" folder which you can find the Windows button -> All programs.
It might be named differently if you have a localized Windows version.
Use the "Run" key in the registry.
See http://support.microsoft.com/kb/314866
You can use the Startup folder, thats easy to handle by your users if they do not want it anymore.
Then there ist the Run key in the registry, see Andrew' answer.
Also you might set up a windows service which does things not interactivly and also when no user is logged in. This service can do a single thing, start up automatic und terminate after finishing its work (it does not need to loop like most services).
You can use two easy ways to do this.
Add to Start up folder
Environment.GetFolderPath(Environment.SpecialFolder.Startup)
Add registry entry
RegistryKey myKey= Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
myKey.SetValue("Your Application Name", "\"" + Application.ExecutablePath.ToString() + "\);

Categories

Resources