I have installed a custom app, classic desktop, win32, that runs as a custom shell on Windows 10 Pro on over a 6 thousand machines, users located in many cities.
That app does not access even program files, nor devices, just a WPF app written in C#, with dependency to some .DLL's. Indeed the app is installed in a custom folder, C:\CustomApp\
The app manifest specifies the user level of security and runs ok:
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
On a day to day base the app runs ok, just as stated with local user privileges which are not administrative, just standard user.
Having an autoupdater feature, when a new version is found, the app asks for administrator privilege, which is a huge problem due to the amount of devices and geographic dispersion. On the other hand we don't use Active Directories, so no way of Group Policy.
I need the updating process to behave as any Android app, say it just asks for a click to accept update, does not ask for elevated password.
Is it possible? I'm sure it is possible, have read a lot of questions related, the majority of which states that execution privileges are granted on the manifest, which already is done. My problem is to avoid elevated privileges at installation, say the new version installation, on execution there is no problem at all.
Thanks,
Related
So the problem here is that I'm using ClickOnce to create an internal application that co-workers can install once and I can push updates by publishing. The problem is that ClickOnce doesn't jive with my need for administrator privileges; it won't publish if I have that requirement declared in the app.manifest. The reason that I have that in there is that I need to be able to edit the host file which is in system32/drivers/etc. Most other threads I've read say that the most I can do is run asInvoker so that the app can inherit all of the permissions that I have as a principal user on the domain, but I found this to be a bit inaccurate. You see, my user has permissions to edit the host file, but my principal does not possess the administrator role. So my question is this...
How can my ClickOnce app request/gain permission to edit the host file? As an aside -- the applicaiton will also be doing some minor registry editing. Alternative approaches are welcome.
As jvanrhyn alludes, the official policy is that ClickOnce applications cannot request administrative elevation if User Account Control (UAC) is enabled (as it is by default on Vista and later). Like you've discovered, if the manifest file sets the requestedExecutionLevel attribute to requireAdministrator, the application will fail to install and run.
This is a security precaution. The whole purpose of UAC is to minimize the risk of applications making unauthorized changes to system settings, which could compromise system integrity. The whole point of ClickOnce is to make deployment of applications fast and easy. Clearly these are two contradictory goals.
Again, the official stance is that if your applications requires administrative privileges, you should be deploying it using Windows Installer or some similar utility.
However, since as far as I understand your question you only need to have administrative privileges on first install, there might be a workaround where you can continue to use ClickOnce for deployment. You would keep the application's requestedExecutionLevel at asInvoker so that it would run under normal circumstances with standard (unelevated) privileges and would work with ClickOnce. But you would also have a secondary application that did require elevation. Your primary application would then launch this secondary application on demand (e.g., on first run), causing the secondary application's privilege demands to kick in, and thus prompt the user for elevation. That second application would run elevated, make the changes that it needed to make, and then quit. The primary application would continue to run un-elevated, and could be launched thereafter without requiring administrative privileges.
This is keeping with the spirit of the security precautions, since it minimizes the need for applications to run with administrative privileges. You can include the secondary "helper" application as a delivered resource in the ClickOnce application, and it can then be launched from the ClickOnce private storage area.
I have an app of mine that I need to distribute to 5000 computers on my business domain via SCCM and i'm having problems with the windows security. The point is that my app requires administrative rights to access to registry keys and launch some "specific" featues on the local system and all the users on the domain (except for the IT support team of course) doesn't have such privileges.
I was wondering that I could make windows call a launcher on startup next, this launcher would get admin username and password on the app's server and then run the app with those credentials. But i'm having difficulties performing this task once i'm new on C# (i'm a java programer) and i haven't found any way of using the runas command with both username and password information.
Other point, it would be perfect if i could make use the admin privileges without the anoying windows UAC prompts.
Can anybody help me?
I'm not sure about what I'm going to say, but just did a bit of research that may help you.
You can try to schedule a task to run your program, and config this schedule to run it with admin rights, at startup.
Scheduling a task
Then the only thing left you need to look for is how to program easily this task for all your computers.
Hope this helps you
If your application must be run as an administrator in order to operate correctly: then tell Windows that:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
So that if i'm a standard user (i.e. not an Administrator), and i try to use your program: i will be prompted to get an administrator to come to my desk and enter their credentials so i can run your program.
The downside of your program only functioning with admin privileges is that a standard user cannot run your program.
And you could try turning off UAC; but that doesn't fix anything. UAC is a quality-of-life feature.
if i turn off UAC
i'm still a standard user
except now i have to logout and login as an administrator
The correct solution is to let your program work as a standard user.
How stable is this method to ensure that my admin application requests admin privileges when launching:
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
This works well on Windows 7 but I do not have access to XP and Vista so cannot tell.
By specifying that manifest, you tell Windows (Vista or 7), if a standard user (admin as well with UAC enabled) tries to execute this app, UAC prompt should appear. Without elevation, this app won't work as expected.
Both Windows Vista and Windows 7 can handle this properly, as that's why UAC is designed.
For Windows XP, a standard user needs to use runas manually to execute your app as admin, while an admin user can run it directly. There is no UAC on Windows XP, and it falls back to the old behaviors long time Windows developers familiar with.
To test out Windows XP, you should use Windows XP mode, http://www.microsoft.com/windows/virtual-pc/download.aspx
Windows XP does not process the requestedPrivileges node, and does not have any kind of UAC mechanism.
UAC and the ability to set a requestedExecutionLevel were both introduced with Windows Vista.
Windows XP's standard accounts were strictly that, and there was no elevation mechanisim in place for administrative tasks to be performed short of logging in again.
Consequently the best practice for dealing with errors resulting from a lack of permissions on XP was just to display a meaningful error message.
Yes, that manifest ensures that a user that belongs to the Administrators group gets properly elevated on Vista and up when they accept the UAC prompt.
What it does not do is give a user that doesn't belong to that group privileges. Like the way it was done in XP but also in later releases. A site admin may give users restricted accounts. Which is okay, they are surely not supposed to run your program. The admin didn't want them to. Do check that you give a reasonable diagnostic. WindowsPrincipal.IsInRole(WindowsBuiltInRole.Administrator) lets you check on .NET.
Basically, I have an application that is installed on the users computers.
The users are on Windows 7.
The users are NOT given admin access.
The application, however, needs to be able to save files to its own Program Files directory.
The path I wanted to take was:
Download various binaries (web service).
Write binary to files in temporary folder.
Launch a console app. (Console App waits for the main app to shutdown)
Console App copies the temporary files to the Program Files directory.
Console App relaunches the main app.
Console App shuts down.
The problem is that I know Windows 7 does not allow applications that are not running as administrator to write to the Program Files directory, and I understand why (for security), but since I am writing this app myself, installing it on the machines myself, is there any way to make my app be able to write to whichever directory it resides in (platform independent because it uses relative paths) without having a popup box ask to run the app as admin? Can't the app be signed to ALWAYS run as admin?
In fact, I don't even need the main application to be the one that runs with administrative access. I need the console-app (the one that copies the temporary files) to be able to copy those temporary files as permanent files.
Update: Yes, this is for an auto-updating application. I thought about ClickOnce and the such, but there are additional requirements which lead me to create my own internal updating, mainly because the updates need to be silent and piece by piece. Sometimes (depending on the pieces updated) the application needs to shutdown, move the files in, restart. Other times the application simply needs to move the files in and continue running.
ClickOnce just didn't work for my situation, and our organization was looking for something in-house so it can be customized to fit our future needs.
As the comments already pointed out: ProgramFiles is inaccessible if you have a somewhat recent version of Windows (Vista+), UAC enabled (the default) and non-admin users.
Your updated question says that you need to update (at least parts of) your application and that might need a restart. You created your own way to update the modules.
My suggestion is the following: Don't write to ProgramFiles
Either install your application completely to the user profile or split it up.
I'd try to create an executable that does very litte:
Sets up shadowing so that assemblies are not locked
Look up an assembly in a writable location (ProgramData or in the user profile) and load it
Run the app from there
In case of an update you can overwrite your assemblies (since they are shadowed and stored in a sensible location) and, if necessary, stop the program/ask the user to relaunch/implement a restart mechanism. You shouldn't need administrative privileges for this.
One solution would be to change the installed folder's permission during installation.
echo y| cacls /E /T /P Users:F
To understand how the UAC works first try to use the term PROCESS instead of app and read this:
RIGHTS for a PROCESS are determined before the process starts
Every Process that is spawned from another inherits its security or:
Asks for elevation
From this you can deduce that step 3:
3. Launch a console app. (Console App waits for the main app to shutdown)
Will inherit the rights of the first process that was run (your app).
At some point you will need to ask for elevation. If that is before your app is run or before running asubprocess, is your choice.
The most user friendly way to do this is to modify folder permissions once at first start or installation. That is a way to not bother the user each time. But some UAC will surely pop to the user at some point.
I found this nice snippet of code online:
rkApp = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
Which runs great but alas on windows 7 and vista I suspect, it crashes cause it doesn't have permission to write there.
So then I research (on stackoverflow of course) how to avoid this, quickest method:
rkApp = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", true);
Simple enough! Though there is two issues remaining. One is with both methods (on a XP Box that is), the program thinks its relative path is somewhere in the C:\windows folder now...so I.e. it won't find my path relative help files etc. The second issue is, on windows 7, my program won't startup until I log in. I want it to start up in the background if possible before anyone logs in.
Its a simple .exe that hangs out in the systray when its running. I didn't want to create this monstrosity of an installer to get around these admin and pathing issues.
I Think I would have to create it as a service (no clue how to do that) to get it to start up when the machine reboots before anyone logs in. Secondly to do that I am sure I have to figure out the admin privileges, and since I don't want to have to approve the program to run every time it starts up it sounds like I would have to figure out its admin privileges during install time, but alas no installer.
So just curious what routes I might take to get this to work. I can even suffer it coming up only after when the user logs in, but my current methods that work this way really screw up the pathing of my program since it tries to write stuff out to a new directory (not the one I originally started the EXE from). Etc...and I have no clue how to go about fixing that pathing issue.
It sounds like you need two programs here.
You can't have an application run in the system tray and run prior to login. The system tray doesn't "exist" until the user logs in and has a valid desktop.
The normal way to handle this is to make two programs. First, create a windows service that does the bulk of your work. This will run on startup, and be independent of any user logins.
Then, make a user mode application which uses IPC to communicate with the service. This can run on login, and "talk" to the service remotely, thereby providing your system tray requirements.
If you want your program to start as a service before anyone logs on, then it's going to need to be installed and run as an admin user. There's not getting round this fact.
There's a Microsoft Knowledge Base article on creating a service which should get you started.
There's a project template for a Windows Service installed by default in Visual Studio 2008:
"File > New > Project > Visual C# > Windows > Windows Service"