Adding Context Menu To Desktop Background - c#

I have a program that I want to run in the system tray. While my program is running I want to provide the user with a context menu whenever they click on the desktop.
For example, let's say the user clicks on the desktop (not on any folder, icon, etc., only on the desktop). I would provide them with a context menu such as:
I know how to add these using a registry file (.REG):
[HKEY_CLASSES_ROOT\DesktopBackground\Shell\Wallpaper]
"MUIVerb"="Wallpaper Settings"
"SubCommands"="Next;Previous;Reset"
"Position"="bottom"
; Next
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Next]
#="Next"
; Previous
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Previous]
#="Previous"
; Reset
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Reset]
#="Reset"
I tried, in my program, to just add these entries to the registry but I kept running into permission problems because the program isn't running as administrator. I also don't want to force the end user of my program to run it as administrator.
How can I write a program that adds a context menu to the desktop background but doesn't have to run as administrator? Or can I?
Does my program have to run as a service?
Thank you.

Apply the .REG file during installation.
or
Provided, you make your installer yourself:
var path = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\CommandStore\shell\Next";
Microsoft.Win32.Registry.LocalMachine.CreateSubKey(path, true); // True makes it writeable
Microsoft.Win32.Registry.LocalMachine.OpenSubKey(path).SetValue("#", "Reset", Microsoft.Win32.RegistryValueKind.String);
.
Thankfully, no way of doing this w/o administrative privs.

Related

Check if a program is started via "Run as Administrator" or not

I wanted to detect if my program is started via "Run as Administrator" or not. On two machines it works by doing:
new System.Security.Principal.WindowsPrincipal(System.Security.Principal.WindowsIdentity.GetCurrent()).IsInRole(System.Security.Principal.WindowsBuiltInRole.Administrator)
Because when I run programs, by default they don't run as Administrator, so I can check it like that.
However on yet another machine (this one has Win7 and UAC disabled) and when I start any program there it automatically starts with admin rights, without ever having to "Right click -> Run as Administrator". Can I somehow filter this instance out?
Background is simply, that on the very first start it should prevent the user from starting it elevated, but if the user starts it elevated every time anyways it shouldn't care.
Hope it makes sense,
Matty
I found out that the "EnableLUA" setting in the Registry in "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System" was actually set to 0 so UAC is completely disabled and starts everything as an Admin so I will just add a check for this value to be 1 additionally :)

Start process as normal user from ClickOnce application

We have a ClickOnce application that starts an external process with
p = new Process();
p.StartInfo.WorkingDirectory = Path.GetDirectoryName(exe);
p.StartInfo.FileName = Path.GetFileName(exe);
p.StartInfo.Arguments = arguments;
p.Start();
Usually, people ask whether it is possible to start the process as administration. But in my case it is the opposite:
I would like to make sure that this application is started as the user that is logged on. By default, that happens - for example when I test it.
But some users (Windows 8.1) report that the exe is started as administrator. For some weird reason, Windows automatically wants to start it as admin, even if it would not be necessary at all. If they right click on the exe and check the Properties, the box Run this program as an administrator is not checked!
When checking the exe file in the folder, it shows a UAC icon (example below):
Now I am wondering if it is programmatically possible to prevent that behavior and start the process in non-elevated state, maybe with a StartInfo property?
If application requires UAC, there are two reasons:
There is a manifest (embedded into executable, or external one) which requires that.
Windows decided, based on certain conditions, that application needs evelated permissions.
Since as you say in your question, the same executable does not require UAC on certain machines while does require on others - most likely there is no embedded manifest and that is Windows who decides this application needs evelation.
Here you can find somewhat dated, but I hope still relevant architecture of UAC. Under "Installer detection technology" you will see that even simple things like "The file name includes keywords such as "install," "setup," or "update." might cause windows to force UAC on that executable. First check if this somehow helps you to solve your problem (like maybe on some machines executable matches some of those criterias).
If that does not help, and because embedded manifest is unlikely - you can try to create external manifest for that exe (you can do this automatically before starting process) in which you request requestedExecutionLevel asInvoker. Put that manifest (it should be named .exe.manifest) near problem exe (not your clickonce application) and see if that helps. Hope you know how to create manifest file, if not - you can easily find that on Google or ask here. Note that if executable has embedded manifest already - it will have a priority (but that is unlikely).
Maybe this will help you?
launch C# exe without prompting UAC on Windows 7
Add this to your manifest:
requestedExecutionLevel level="asInvoker" uiAccess="false"
"It could be that your third party DLL has to run in elevated mode, so your best option is to run as administrator. Bypassing the UAC prompt without running as administrator is a long complicated process"
You're doing it right by not specifying any account information when creating a new Process instance: that'll rely on the default behavior of using the same user account running current process.
As for some users getting the "Run As Administrator" prompt:
it may be that the security rules on the machine somehow identified the executable as not safe. Try to ask your customer to check whether in the properties page of the app they see an "Unblock" button. If so, let them click the "Unblock". That will eliminate that UAC prompt in the future.

How to debug a C# .NET application in Visual Studio 2010 that is started from another process

I have a .NET GUI application written in C# and a PDF printer. The PDF printer has a field where you can set a command to start an external application.
In this case, I can print a document with this printer and the printer starts my EXE file with the filepath to the generated PDF file as argument. How can I debug my application when it is started from the printer?
In Visual Studio 2010, I can set debug information for command line arguments, and this works fine. But if the application is started from the printer the application doesn't work fine. Therefore I want to debug my application when it is started from printer. How can I do this? Is there a parameter to start an EXE file in debug mode or something like this?
Try to attach to the process:
http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx
To attach to a running process
1.On the Debug menu, select Attach to Process. If no project is open, select
Attach to Process on the Tools menu.
2.In the Attach to Process dialog box, find the program that you want to
attach to from the Available Processes
list.
a.If the program that you want to
debug is running on another computer,
you must first select the remote
computer. For more information, see
How to: Select a Remote Machine.
b.If the process is running under a
different user account, select the
Show processes from all users check
box.
c.If you are connected through Remote
Desktop Connection, select the Show
processes in all sessions check box.
3.In the Attach to box, make sure that the type of code you will debug is
listed. The default Automatic setting
tries to determine what type of code
you want to debug. If the automatic
setting is not appropriate:
a.Click Select.
b.In the Select Code Type dialog box,
click Debug these code types and
select the types to debug.
c.Click OK.
4.Click Attach.
The Available Processes list is
displayed automatically when you open
the Processes dialog box. Processes
can start and stop in the background
while the dialog box is open. However,
the contents are not always current.
You can refresh the list at any time
to see the current list of processes
by clicking Refresh.
You can be attached to multiple
programs when you are debugging, but
only one program is active in the
debugger at any time. You can set the
active program in the Debug Location
toolbar or the Processes window. For
more information, see How to: Set the
Current Program.
All Debug menu execution commands
affect the active program. You can
break any debugged program from the
Processes dialog box or break all
attached programs from the Debug menu.
For more information, see How to:
Break Execution.
You can attach to a process when it starts using a small registry tweak.
Go to
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options
Create a new key with the name of the executable as it will appear in Task Manager, for example, myapp.exe. Under this, create a new string value called debugger and set it to vsjitdebugger.exe.
Now, when the EXE file is triggered, a window will appear asking which debugger to attach to.
Consider adding a call into your code that explicitly requests that the debugger be attached at the current location. This has been around since Win32 days, and surfaces in .NET as System.Diagnostics.Debugger.Break (and System.Diagnostics.Debugger.Launch).
You can also add logic to decide when to trigger this if you don't want to do it the first time through:
#if DEBUG
if (++staticCounter > 3) System.Diagnostics.Debugger.Break();
#endif
And, of course, you'll want to disable it for production.

How to allow users only interactive with my program?

I'm writing a software for a call-center. It's somewhat like a ATM program: user can only interactive with it, not with underlying Windows. It takes controls when user logs in to Windows, and when user exits, it logs off Windows.
How can I do that in .NET? A demo will be much appreciated.
Thank you.
Replace the Windows Shell.
By that I mean Explorer.exe, by means of editing the Windows Registry. What this does for you is instead of logging on and the system running Explorer.exe which consists of the Start Menu, Taskbar and other similar features you are familiar with, it only runs your program. There is no desktop, no context menu, no taskbar, or start menu. Thus, making your application "The Shell" or the new "Explorer.exe".
However, by doing this the user still has access to Control+Alt+Delete, so they would still be able to access the Windows Task Manager, which mind you can also be disabled via a simple Registry Key Entry.
This is the most pain free, easiest solution because you don't even have to worry about things such as disabling the WindowsKey or other annoyances.
The registry key to this is as follows:
SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
The name of the value to modify is:
Shell
And you can simply enter the value to be the fully qualified path to your program's executable file. You will only want to do this under HKEY_CURRENT_USER and only for the account that is to run your shell program. So you will need two separate accounts.
Administrator account
This account will just be a normal password protected account that will be used to manage the system
Kiosk account
This account will be the account that is logged on at all times, which runs your custom shell (your application)
Additional Notes
To disable the Task Manager the registry path is as follows:
Software\Microsoft\Windows\CurrentVersion\Policies\System
The name of the value is:
DisableTaskMgr
This is a DWORD value which to enforce the policy must be set to '1'.
What I did was to use DirectX and just use full-screen and exclusive modes, which you can see a small example of here: http://www.directxtutorial.com/tutorial9/b-direct3dbasics/dx9B2.aspx.
This is more work, but it will allow you to do what you want.
Depending on what control you have, there are steps you can do with group policy to limit what people can do on the computer. You can look at how people set up a kiosk application on Windows for some ideas.
What you want to do is run the OS in "kiosk mode".
This entails using the Group Policy Management Console to apply the kiosk mode template - as part of this you register your application as the shell.
As such there is no taskbar, or explorer view to fall back on to. The only way to run the usual shell would be to connect a keyboard to the system - press ctl-alt-delete and run explorer from the taskmanager that pops up.
And you can disable even the standard task manager if users are going to have keyboard access to the console. You will want to implement some kind of launch explorer.exe interface otherwise the system might become a bit difficult to manage :P
You can set your applications window to be always on top and to cover the entire screen. If you exclude buttons that close the window the user must know that ALT+F4 closes the window in order to exit. This has been good enough for me those times I've needed it.

Disable everything in windows except program c#

I've got the following question:
Is it possible te disable everything in windows except the program it's running?
I need to program an application on a touchscreen (fullscreen), where people can fill in a survey.
The only thing they should use is this program. (for protection of the survey anwsers and other secret stuff :p )
And the program should be closed when entering the right password.
So how can I disable everything else but the program I'm running?
Thanks
You should investigate Kiosk Mode. It might not be the right solution for your particular case, but it is an accepted way of restricting users to one application.
Kiosk Mode in IE
Basically you make the application full screen and disable things like the task bar etc.:
Disable the start menu and other stuff through the Group Policy Management
for the local computer (run gpedit.msc -> User Configuration ->
Administrative templates -> Start menu and Taskbar).
Source
This KB entry describes how to do that the best way by replacing the shell.

Categories