How to compare between two executable files? - c#

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?

Related

Adding Files/Folders to Program Files x86 Folder with C#

I am trying to create a file directory (folder) in the 32 bit Program Files folder to store data that a user will be creating in the program. However, it keeps saying that access is denied when I try to do so. Is there anyway to give the program permission to access the 32 bit program files folder and add subsequent folder and files to it? Here is my code below which is producing a run-time error due to not having permission.
string mainDirectory=Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86)+"\\UKC Trial Reporter Files";
if (!Directory.Exists(mainDirectory))
{
Directory.CreateDirectory(mainDirectory);
}
Store your data in Environment.SpecialFolder.ApplicationData, Environment.SpecialFolder.LocalApplicationData or Environment.SpecialFolder.CommonApplicationData (if data have to be accessible by any user).
Never store it in %ProgramFiles%.
%ProgramFiles% is intended for... program files: executables, dlls, app.config files.
In addition of security reasons, there's yet another reason to do this never: when uninstalling, your application's installer must sweep all of files and folders it had created. And this is impossible, when list of files in installdir was changed during application lifetime.
Fortunately, we have UAC since Windows Vista has released.
Don't do that.
Program FIles is exactly that; it should contain EXEs and static resources.
Instead, you need to write to the user's SpecialFolder.ApplicationData folder.

Where to save project related text files?

For testing and debugging purposes, I just hard-coded the file paths for the text files that would be used by my application, e.g.
const string CONFIG_FILE_PATH = #"C:\myconfigfile.txt";
But I don't think it's a good idea to leave it as it is in the Beta/Release version.
So I am wondering, what would be the best location for saving these configuration files that will be used / read by the application? Any suggestions?
Many Thanks.
Why not save the strings in the Settings section of your project? GRight click on your project in Solution Explorer, select Properties, go to the Settings section and add a new string with your file path. Then, in your code, you can access it like this:
using ProjectName.Properties;
var path = Settings.Default.MySetting;
To change the setting:
Settings.Default.MySetting = newPath;
Settings.Default.Save();
In the same folder as the executable.
But you should consider using a Settings class (you can read more here). Visual Studio can automatically create a strongly typed wrapper around a section in the app.config file.
The settings are stored in the same file as the executable, but can be overridden (and saved from the application) in a matching file in the user profile for each user.
Another option: If the test config file is intended to sit along side your executable, you can "Add" "Existing Item..." to your project and then change its properties to "Copy always" or "Copy if newer". During debugging, the executable should be able to find the copy of the config in its current working directory.
This isn't such a useful solution when there's a lot of testing to do.
For settings I would certainly use the app.config file. This is proposed by Microsoft and apart from that it is pretty much the easiest way to handle application settings anyway.
For other files I'd recommend either the applications local or roaming settings path, depending on weather you only need the data local or not. For compact, local databases I tend to use this approach. The application directory, as suggested by Albin, is a bad idea. You cannot be sure that the user is actually allowed to write to that directory and/or files in that directory (i.e. the app was pre-installed by an admin with elevated rights).
To get the location of the local paths use
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal)
and for the roaming path
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoaming)
More information on Windows User Profiles (the actual paths in different versions of Windows for example, you can find here: http://msdn.microsoft.com/en-us/library/aa372123.aspx

Windows Shell: How to associate different xml-files with different apps?

I have many kinds of xml-files (all with extension .xml) with different root element name and namespace. I want to associate each type with a different application and also make it possible to have different file-icons for each type. Can this be done using C# .NET?
The only way to handle this is in a similar way to that which Visual Studio uses to handle .sln files which is the Visual Studio Version Selector. This application is the one that gets associated with .sln files and handles providing an icon and an eventual process to handle the specific .sln file. Assuming you have Visual Studio installed, take a look in the registry at HKEY_CLASSES_ROOT\VisualStudio.Launcher.sln to see how it's done.
So basically you need to:
Write an executable that can decide what to do with .xml files
Register the process as the one responsible for handling .xml files
Place logic in your executable, or in configuration that your executable consumes, that decides what to do on a per file basis.
For icons, take a look at the subkey ShellEx\IconHandler. You'll see that it points to (on an x64 machine with Visual Studio 2010 installed) HKEY_CLASSES_ROOT\Wow6432Node\CLSID\{9A2B23E4-2A50-48DB-B3C3-F5EA12947CB8} which lists under InprocServer32 a DLL that is responsible for providing icons for files, in this instance C:\Program Files (x86)\Common Files\Microsoft Shared\MSEnv\VSFileHandler.dll. You'll need to implement a similar DLL that shares the configuration/logic of your launcher process to determine what icon to show on a per file basis.
The usual caveat: Writing shell extensions in managed code has always been a big "no no" because shell extensions get loaded into any process that shows the common file dialogs. This can cause merry chaos as, up until .net 4.0, only one version of the CLR can be loaded into a process, so you have to be very sure before doing this. Given that .net 4.0 supports in-process side by side, this may not be an issue for you.
No. To Windows, an XML file is an XML file. The OS doesn't look inside to see what namespace is associated with it; it's just an XML file.
Windows associates file types with their extension, so again, all XML files are XML files. You can see this for yourself: rename a normal .txt file that contains absolutely no XML, and then refresh the view of it's folder in Explorer. You'll see the icon change from a text file image to an XML file image.
There isn't a way that you can do this without having custom extensions or an intermediary program.
Maybe one option would be to have a custom applicaiton which is assigned to handle XML files. When this is program is spawned it works out what the "type" of the file is using one of the XML tags and spawns the correct process accordingly. It's unlikely, however that you can give different "types" different icons.

How to detect the install directory of a project?

I have a Visual studio C# project and I have an installer that installs the files into whatever directory the user specifies. I also have another installer with localized language resources and I want that to be installed in the aforementioned directory.
Can anyone point me in the right direction on this? I think I have to do something with registry keys but I don't know what to do.
Edit: For the record, I found this page: How to: Use a Registry Launch Condition to Specify a Target Directory. And I followed the instructions and it did what I wanted it to do.
Typically, you would create a registry subkey and value of HKEY_LOCAL_MACHINE\SOFTWARE\ and then just read that key back in your second installer to decide where to put that.
Something like HKLM\SOFTWARE\MyApplication,
Then you make a string value called InstallPath and write the path from your first installer there.
Depending on what you're doing, you may want to have a look at merge modules for installing several components with one MSI.
You are on the right track. Your first installer would write it's install path to a well known registry key. The second installer would read the path from that well known key and put it's dlls in the appropriate sub folders.
Here is one way to go at it:
Assembly a = Assembly.GetExecutingAssembly();
string folder = System.IO.Path.GetDirectoryName(a.CodeBase);

setting UAC settings of a file in 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.

Categories

Resources