setting UAC settings of a file in C# - c#

i want to give a file(already present on the client computer .exe) permissions to always execute with administrative permissions.
please note that the file i wants to give permissions is already on target machine. and i want to change permissions of that file through another program written in c# and it has administrative permissions to do everything.
kindly let me know how to do it
i am using this code
System.Security.AccessControl.FileSecurity fs = File.GetAccessControl(#"c:\inam.exe");
FileSystemAccessRule fsar = new FileSystemAccessRule("Everyone", FileSystemRights.FullControl, AccessControlType.Allow);
fs.AddAccessRule(fsar);
File.SetAccessControl(#"c:\inam.exe", fs);
this code will change the permissions correctly but still when i execute inam.exe after executing this code the UAC not appeared and also the inam.exe cant perform administrative operations.
actually i have already deployed an application on more than 10,000 clients so wants to release a patch to resolve the administrative rights issue.

Execute with administrative privileges is not a file permission.
This is usually configured by adding a manifest file (either to the Win32 resources in the EXE, or as an external manifest). This manifest file can state whether the application needs to run elevated or not.
I'm not entirely sure where Windows stashes the "Run this program as an administrator" compatibility setting.

Using a manifest file is the best approach, but an alternative one would be to programmatically set the "Run this program as an administrator" flag (the option you find in the Compatibility tab of an EXE's properties), by setting a simple registry key. You need to create a string value (REG_SZ) under the one of these keys (if you want the setting to be per user or per machine, respectively):
HKEY_CURRENT_USER\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
or
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers
The name of the value needs to be the full path to your executable (if the path contains spaces, do not surround the path with quotes), and the data of the value must contain the string RUNASADMIN.

Build a manifest file (see http://www.gregcons.com/KateBlog/AddingAManifestToAVistaApplication.aspx among other places) and name it Whatever.exe.manifest and put it in the same folder as the exe. The nanifest should set the requestedExecutionLevel to requireAdministrator. All set.
If you own the other exe, you can embed the manifest when you build it. This is almost trivial in Visual Studio 2008 and up. See the Application tab and drop down the Manifests drop down. There are instructions nearby. Also when you use VS 2008 to add a manifest to your project you don't have to type all the XML, you just copy the appropriate requested execution level from the comments that are generated for you.

Related

Unable to delete files in "Program Files\my app" folder : System.UnauthorizedAccessException :Access to the path '' is denied

I am trying to create an updater which will replace the files in the folder without needing an installer. As part of this process, I need to be able to delete old files and replace them by new files. I tried it and got an UnAuthorizedException. I am runing the updater as administrator. I tried the following
a. Setting the file and folder attribute to Normal
[Access to the path is denied when trying to delete a certain directory
b. Taking ownership of the folder and files contained in it
[Taking ownership of a file or folder
c. Changing the permissions and giving all users full control over the folder and files [Using a custom action in the installer]
[How to give Read/Write permissions to a Folder during installation using .NET
d. Running the updater from a windows service
There is no difference in the results. I keep getting the access denied error. What do I do so that the updater can delete the files?
It's not clear exactly what you mean by "running as administrator", but being logged in as administrator and running a program does not mean that the program is running with elevated privilege, which is what it really needs. But clearly the updater program is not running elevated.
So the issue might be that this updater program of yours needs an elevation manifest so that when you run it, it will ask for elevation with a UAC prompt.
Having said that, simply replacing files that were installed with a Windows installer MSI is not supported. The files must be replaced with a Windows Installer update such as a patch .msp file or an upgraded MSI file. Windows Installer keeps track of every file installed, and it's version and whether it's been updated or not, as well as a filehash. Replacing a file without using Windows Installer can result in unexpected demands for the original MSI file in order that Windows can restore the files to their original installed state. You might find that going to Programs&Features (or right-clicking the MSI file) and choosing repair will also restore them.

How to compare between two executable files?

I have a file which doesn't require UAC Warning. I copied the file to another location using C#.NET
File.Copy("Original.exe", "Copy.exe");
Now i see that Copy.exe require UAC warning to run under windows 7/Vista.
How can i compare between Original.exe and Copy.exe to see exactly what happened to the file and change it manually so that it doesn't require UAC anymore. Which tool can i use to achieve that ?
BOTH EXECUTABLE ARE THE SAME FILE : How to know the difference between these two files ?
Windows Installer Detection Technology is the reason of such behavior. There is a set of conditions which force executable file to be considered as requiring administrator privileges:
32 bit executables
Applications without a requestedExecutionLevel
Interactive processes running as a Standard User with LUA enabled
Before a 32 bit process is created, the following attributes are
checked to determine whether it is an installer:
Filename includes keywords like "install," "setup," "update," etc.
Keywords in the following Versioning Resource fields: Vendor, Company Name, Product Name, File Description, Original Filename,
Internal Name, and Export Name.
Keywords in the side-by-side manifest embedded in the executable.
Keywords in specific StringTable entries linked in the executable.
Key attributes in the RC data linked in the executable.
Targeted sequences of bytes within the executable.
Related MSDN article: http://technet.microsoft.com/en-us/library/cc709628%28WS.10%29.aspx
Possible solutions:
If you are the author of executable, include manifest with specified requestedExecutionLevel
If you don't have access to source code - try to add or modify manifest using appropriate utilities (mt for example or maybe some generic resource editor)
Avoid keywords update, install and setup in executable file name
Afte copying the file try to set the file's acl like that:
var file = new FileInfo("copy.exe")
var fileSecurity = file.GetAccessControl();
fileSecurity.AddAccessRule(new FileSystemAccessRule(new SecurityIdentifier(WellKnownSidType.WorldSid, null),
FileSystemRights.FullControl,
AccessControlType.Allow));
file.SetAccessControl(fileSecurity);
You may find that the problem is to do with the location rather than the file. Win 7 is very fussy, especially if you try and change anything under Program Files.
Have you tried putting the original file in the new location to check if that also required UAC approval?

Visual Studio Deployment Package Change File Permissions

Maybe this isn't possible due to Security implications...
I have a Deployment Package created in Visual Studio for a Win Form. The application references an app.config file locally and allows the user to change the settings in it, through the application.
When I deploy the application and attempt to save the changes I have made, Windows is saying "Permission denied". Is there a command I can run as part of the installation that will give the "Everyone" security permission to my app.config file....and thus allow my Application to edit it?
Thank you.
If you want to be able to write to the app.config file you need to move it to the Shared Application Data directory and modify your application to read the configuration information from there. On Win7 for example:
C:\ProgramData\YourCompany\YourApp\app.config
In C#, to get the common app data directory:
// using System.IO;
string appDataDir = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
You might be able to use a custom action in your installer to run icacls in order give full access to Everyone:
icacls {Path to App.config} /grant Everyone:(F)

Failed to update .mdf database because the database is read-only (Windows application)

I've created a database windows application using in C#. My application is running successfully on Windows XP, but it doesn't properly execute on Vista or Windows 7 systems. My application shows a message similar to
Failed to update .mdf database because the database is read-only
Can anyone give me a solution to this?
The big thing that changed between Windows XP and Windows Vista/7 is the introduction of UAC which means that users, even if created as administrators, don't routinely have read/write access to "important" locations such as the %programfiles% (Usually C:\Program Files or C:\Program Files (x86)) directory. This is why your application works on Windows XP and not on Windows Vista.
You need to store your DATA in the %programdata% directory (which is usually C:\ProgramData) if the data is shared between users on the machine or %appdata% (which is usually C:\Users\USERNAME_GOES_HERE\AppData\Roaming) if it is specific to a given user. You'll now no longer encounter the problem of being unable to write to the file.
The reason for this is that by storing data in your programs installation directory you were doing the wrong thing. Windows didn't stop you from doing this previously, but it was fairly widely documented that %programfiles% was not the appropriate place to store data.
If the MDB file is in your application path, then the default permissions would require elevation of rights to be able to write to the files -- I'd recommend moving the data to the ApplicationData shared folder, where end users will have write permissions by default
I ran into this related to localdb, the file is named:
myfolder/mysolution/myproject/App_Data/something.mdf
The way I fixed it is to right-click on the top level folder (myfolder) and then choose Properties, then choose Edit, then select Users, add to users either the Modify permission or both Modify and full control (this is a development environment) and then click apply.
So in other words, in my experience, it doesn't matter what folder you put the localdb in, you just need to give Users permission to write.
You should add the Modify permissions for IIS_IUSRS user to *.mdf file.
go to the folder Where the program is installed and right click on the database file and Properties -> Security -> Group or Username (Click users one by one and see below for the permissions)
If for the user if not set to full control, then click EDIT -> Select the user and give full control..

File Not Found in %TEMP% on Win7

I have an odd bug where my code returns a file not found exception but the file seems to be exactly where it should be. My project has some code to run a system cmdlet and look for the results of the cmdlet in an XML output file. We tell the cmdlet to put this output XML in a custom subdir of the system TEMP dir, e.g., C:\WINDOWS\TEMP\SomeFolder\output.xml. We then use the .NET XmlDocument class to open and parse the XML file.
On WinXP, this works. On my dev box, this works. On a clean Win7 test machine, it does not.
My first thought was that I'm running into Vista/Win7 File Virtualization, but our application manifest specifies that our app run as Admin -- and from what I've read, that should bypass file virtualization.
The other wrinkle is that our code likes to use UNC file paths, even if the file is local to the machine. (We have a requirement that the code in question may need to run the cmdlet on a remote machine, and therefore the output XML could be on a remote machine too.) So we try to open the XML file via \MATT-WIN7\C$\WINDOWS\TEMP\SomeFolder.xml rather than C:\WINDOWS\TEMP\SomeFolder\output.xml.
But I removed the UNC path code temporarily and a simple call to File.Exists() still says the XML file is not there, when Windows Explorer shows the file sitting exactly where I think it should be.
Is there some nuance of file virtualization that I have not read about yet?
My workaround is to move the output xml file somewhere else, but that will potentially break the "portability" of our code when it needs to run on a remote machine, because using the %TEMP% location is a location that can be resolved for remote computers pretty easily (via remote registry call to find the system environment variable).
I would prefer to leave the file where it is, and fix our code so it actually finds the file!
There is a user-specific override for the %TEMP% environment variable that points to %USERPROFILE%\AppData\Local\Temp, not to %SYSTEMROOT%\Temp. Make sure your code is looking in the temp folder you expect it to look at.
Update: Based on your comments, it seems that the problem is that your app is not actually being elevated on the test machine, but is elevated on your dev machine. I suspect the following:
you either have UAC disabled on your dev machine or you are running VS as administrator. Big no-no on both. :-)
your binary is not code-signed and is not in one of the two trusted locations - %SystemRoot%\system32 or %ProgramFiles%. For security reasons UAC does not even prompt the user for elevation for apps that have elevation manifest, but are not code-signed or in a trusted location.
You can create a self-signed certificate to code-sign your binary and add that certificate to the test machines, to get the UAC prompt. Once you've confirmed that your app is properly being elevated, your code to access the system %TEMP% folder should work correctly.

Categories

Resources