Through WiX installer I installed my Windows application and folder is being created under c:\ProgramFiles with .exe and required dll's.
While running the .exe I am getting the System.UnauthorizedAccessException.
Please let me know if there any helpful suggestions.
Please find the below event log for reference.
Application: xxxxxxx.exe
Framework Version: v1.0.0
Description: The process was terminated due to an unhandled exception.
Exception Info: System.UnauthorizedAccessException
at System.IO.__Error.WinIOError(Int32, System.String)
at System.IO.FileStream.Init(System.String, System.IO.FileMode, System.IO.FileAccess, Int32, Boolean, System.IO.FileShare, Int32, System.IO.FileOptions, SECURITY_ATTRIBUTES, System.String, Boolean, Boolean, Boolean)
at System.IO.FileStream..ctor(System.String, System.IO.FileMode, System.IO.FileAccess, System.IO.FileShare, Int32, System.IO.FileOptions, System.String, Boolean, Boolean, Boolean)
at System.IO.StreamWriter.CreateFile(System.String, Boolean, Boolean)
at System.IO.StreamWriter..ctor(System.String, Boolean, System.Text.Encoding, Int32, Boolean)
at System.IO.StreamWriter..ctor(System.String, Boolean)
at System.IO.File.AppendText(System.String)
Don't try to write where applications should not write. Use other folders like for example:
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
If there is no possible alternative, which I seriously doubt, run the executable with administrative privileges.
https://msdn.microsoft.com/en-us/library/bb756929.aspx
Cross-Reference: A related issue is how to store settings for applications overall. Where to put the files or settings:
Create folder and file on Current user profile, from Admin Profile
Cause
This looks like a simple access violation - you try to obtain write access to a file which you do not have permissions for - in the context you are running (files under %ProgramFiles% are not writeable for regular users, or non-elevated admins - barring file virtualization, see section 9 below).
Here is a generic launch error check-list - probably not useful since you basically have a simple access violation (so it seems). Not sure why the linked answer has been downvoted though. I might have messed up a couple of points - it is just a messy list meant to spark some ideas. Including here for easy retrieval.
Suggested Possible Fixes
Here is a list of a few possible approaches you can use to either work around the problem, fix the cause of the problem, or redesign things
so the problem is effectively avoided. And there are a few approaches
that are merely possible and rarely used. I would frankly consider
approach 10 - HKCU registry keys for settings - combined with a cloud approach for retrieval or copy from a read-only settings file.
The below list is not in order of preference. In fact, approach number 1 is very undesirable in my view. Approach 6 can be effective, but not that great (certainly better than 1 though). I can live with the other approaches (except 9), and 2 is probably the most common to use.
1. Elevate Application (Admin Rights): As others have suggested you can run your application with admin rights (very bad practice these days - admin rights are pervasive, the keys to the city, and make your application a hacker target and also makes the application more dangerous if it contains bugs of caliber). Here is a short how-to: How do I force my .NET application to run as administrator?.
Admin Users Only: Crucially, elevation will not work for normal users! (they will be prompted for an admin password). Only admins can elevate!
Blank Admin Password: If there is a blank admin password on the box (common on home PCs), any user can elevate any binary set to elevate to admin rights at will (using the blank password account) - whilst logged into their own restricted account (they can obviously also already log in as admin with the blank password account and launch absolutely anything - so the security hole is already there with the blank password regardless of elevation issues - but why allow elevation with blank password accounts?).
UAC: What happens when UAC is disabled? Standard users are probably just not prompted for a password, and the launch fails? I haven't had the chance to try yet.
Security: In certain scenarios elevated processes appear to be able to launch other elevated processes that can outlast the original process (depends on launching user's NT privileges). Madness.
2. User Profile (Move File): You can determine what file is causing the access violation (some sort of settings file?) and move it
to a location where users have regular access rights in all cases.
Generally somewhere in the user profile (recommended).
3. Read-Only Access: Very often you can get away with read-only access for settings files. Perhaps you can enforce this approach
instead? It all depends on your application's design. Perhaps you can
handle the access denied exception and then run read-only?
4. Internal Defaults: As a flavor of the read-only approach, you can lose the whole settings file and rely on internal defaults. Rarely
an option I think, but possible. Might be good if you actively want to
hide the settings? You just compile a new binary for users?
5. Online / Clouded Settings?: Some people like to eliminate settings files altogether (or make them read-only) and then retrieve
the "real settings" from a database on launch. This approach can have
dramatic advantages - especially for corporate applications - settings
managemenent and versioning, elimination of user profile roaming
issues, etc... (and challenges of course - network issues,
firewall, proxy, etc...).
6. ACL Permissioning: You can apply ACL permissions to the file in question on installation, allowing regular users to write to it. Not great design at all, but it will work. And certainly better than running with admin rights (elevated) - because you pin-point the access needed, and don't just elevate the whole process. Don't just sett full access to the whole folder - only open write access for single files.
WiX Permission Sample: There is a segment with information on ACL permissioning here: How to deny folder permission to Users with wix installer.
WiX Permission Elements: And here is another segment - mid page - (different ways to apply permissioning in WiX): Is WiX changing the permissions on my Notes.ini file?
WiX Permission Documentation: And the actual WiX documentation is here: http://wixtoolset.org/documentation/manual/v3/ (search for "permission" - recommend link in previous bullet point to understand the differences between the different elements).
7. Windows Service: In certain cases one can run the parts of an application that require elevated rights as a Windows service. Not an approach that I have seen very often, but possible. You then install the service to run as LocalSystem or an equivalent, elevated account (or using service accounts - see "other approaches" section - or this alternative answer). Maybe I can mention scheduled task as well - I have never tried to use a scheduled task for such a scenario.
8. Impersonate: I suppose you could impersonate an account with access rights to write to the location in question. I don't use this approach so I am unsure of the technical details, aspects and challenges. Just chalking it up as an option.
9. Virtualization Approaches: Just mentioning this. Various forms of virtualization - for example policies you can enable to allow file and registry write failures to be redirected to a writeable location (more along the lines of data redirection - with all the confusion that ensues - this is no solution - in fact Microsoft intends to remove the feature in future Windows version. Not sure of the state in Windows 10. MSDN on Registry Virtualization). Generally no problems solved, but several problems not recognized. Overall certain to cause confusion as people don't see where the data is written to, and the data is not shared among users - but user-specific. And there are full-on virtualization / data streaming like App-V and containers that allow full access. Not my speciality, and not my preference.
Please do not use this virtualization or data redirection nonsense (it is for legacy applications to not crash, not for new applications to use). I will still add a link to some technical details for how the feature actually works (there are a number of prerequisites that must be satisfied before this redirection works): log4net log file not visible in Windows explorer in application installation sub folder (recommended to show why this feature should never be used).
10. Registry HKCU: Last but not least one should mention that the traditional approach for settings management would be registry
keys stored per user if you want each user to be able to tweak them.
Linked below is an answer from way back on the topic of per-user file deployment and how it can be done in a package, along with some alternative network / database / cloud approaches.
It might be an involved read, but here it is - it essentially provides a few more permutations of the above possibilities:
Create folder and file on Current user profile, from Admin Profile
Some Links:
C++ MSI Package Administative Privileges (same issue, basically)
can give administration privileges to Application folder when creating windows installer
WiX Toolset: install file with specific permissions
Open project properties for the project that wix is triying to install.
go to security
and set the security settings as
You can also leverage .NET impersonation concept, if there is no other alternative location which doesn't require administrative privileges.
Here is the link to get the overview of the .Net impersonation.
How do you do Impersonation in .NET?
Related
I'm creating a firmware update application (in C#, WPF, MVVM, .Net version still up in the air, but I hope to run it on Windows and Mac) that will allow the user to check for updates to both the application itself and for the latest firmware. I plan to use the common method of putting a file on a server that contains the latest version number and a URL to the files. The application will download the file, compare the versions in the file with the local versions, and download the latest files and/or update the application. Universally lacking in the 'how to's' of this method is the topic of security.
My initial thought was to put the "current version file" in a password protected secret folder, but then that seems overkill for a simple XML file. And since the user will be able to download the app from the website anyway, hiding/password protecting the URL to the application seems pointless. Even the firmware, being a binary file running on custom hardware, at first thought seems rather benign from a security perspective. But then again, I don't spend my days thinking of how to hack into systems.
So, in regards to just the process described above, what kinds of security measures should be taken to protect the server, data and user from attacks? And potentially as a bonus question, what security measures can be taken to protect the application update itself? With this, I can at least see the potential to trick the updater into installing malicious code, so a checksum to verify the updated file's integrity would be a minimum there.
Is it possible to delete-protect a file/folder using Registry or using a custom written Windows Service in C#? Using Folder Permissions it is possible, but I am looking for a solution that even restricts the admin from deleting specific folders.
The requirement is that the administrator must not be easily track the nature of protection and/or may not be able to avert it easily. Obviously all administrators will be able to revert the procedure if the technique is clearly understood.
Like folder Permissions/OwnerShip Settings can easily be reset by an administrator. SO that is not an option.
Folder protection software can easily be uninstalled and show clear indication that a particular folder is protected by some special kind of software. So that too is not an option.
Most antivirus programs protect folders and files in Program Dir. Windows itself doesnt allow certain files such as registry files in c:\windows\system32\config to not even copied. Such a protection is desired for folders which allowse to read and write to files but not allow deletion. Similar functionality is desired. The protection has to seemless and invisible.
I do not want to use any protection features like FolderLock and Invisible secrets/PC Security and Desktop password etc. Moreover, the solution has to be something other than folder encryption.
The solution has to be OS-native so
** that it may implemented **
pro grammatically using C#/VB.Net.
Please help.
Obviously all administrators will be
able to revert the procedure if the
technique is clearly understood.
Please don't tell me your solution is going to rely on security by obscurity...
Anyway, if you don't trust people with administrative rights on the server not to do the right thing, then I suspect you are trying to solve the wrong problem. The problem you should be trying to solve is restricting access rights, and training those who have elevated privileges.
Well, i don't know what you are actually trying to achieve, one option to prevent the deletion is to keep the file open in write mode from your program. nobody will be able to delete it as long as it is open. This is why you are not able to delete windows registry files.
But this does mean that nobody else will be able to write to the file.
When should the Windows Registry be used for per-user state, and when should we use the filesystem, particularly the user's AppData folder? (eg, C:\Users\USERNAME\AppData). Where does Isolated Storage come in?
Is there a pretty firm rule, or is it just a fuzzy thing, like "use the registry until it becomes too much data to store in the registry". or "use whatever you feel like using."
Are there Windows logo requirements that affect the decision?
If I use the AppData directory, how do I choose between Local, Roaming and LocalLow ?
edit: I just noticed these similar questions:
When and why should you store data in the Registry?
Registry vs Ini file for storing user-configurable app settings.
I will summarize replies.
If you have a small number of key/value pairs and the values aren't big the registry is great - and you don't care about xcopy deployment - then use the registry (I know this isn't exact, but it's usually obvious when working with the registry becomes a pain).
If you want xcopy deployment the data must be in the same folder as the program obviously - but the program can be somewhere under the AppData folder, it doesn't have to be under "program files".
Use isolated storage only when you need it or have to use it - for example ClickOnce.
Otherwise use AppData\Roaming, use Local or LocalLow only if you have a good reason.
EDIT: Here is the difference between Roaming, Local and LocalLow:
Windows has a little known feature called "roaming profiles", the general idea is that in a corporate environment with this feature enabled any user can use any computer.
When a user logs in his private settings are downloaded from the server and when he logs out his settings are uploaded back to the server (the actual process is more complicated, obviously).
Files in the User's "Roaming" folder in Vista or "Application Data" in XP move around with the user - so any settings and data should be stored there.
Files under "Local" and "LocalLow" in vista and "Local Settings" in XP do not, so it's a good place for temp files, things that are tied to the specific computer or data that can be recalculated.
In Vista, as part of the new security features we all know and love, you can have programs running in "low integrity mode" (for example IE in protected mode), those programs are running with reduced privileges and can't access files in the user's profile - except for files under the "LocalLow" folder.
So, in conclusion, files stored in "LocalLow" are inherently insecure and files in "Local"/"Local Settings" are likely to be unavailable in some large companies - so unless you have good reason and know exactly what you are doing go with "Roaming"/"Application Data".
Don't clutter up my Registry thank you.
Use isolated storage, thats what it's for.
See Was The Windows Registry a Good Idea? On Jeffs Blog...
You might want to consider Isolated Storage.
I don't know whether there is a firm rule, but but one thing to consider is that the registry is transacted -- it is safer for concurrent read/write operations. So, if your user data might be written by multiple threads at run time (or if you have multiple exe's in your product package), consider using the registry.
History:
One reason (as I heard it) that MS went from .ini files to the registry was precisely to try to handle the concurrent access problem.
.Net (sort of) went back to .ini files in the form of xml .config files, however those config files are not supposed to be written to at runtime (or at least not if there is a chance of concurrent writers/readers).
More info: http://blogs.msdn.com/oldnewthing/archive/2007/11/26/6523907.aspx
When a user installs my application how do I keep User Account Control from producing this dialog? And no I don't want to tell them to disable UAC.
(source: netron.com)
You'd need to design your installation such that it doesn't require administrative access to install, which essentially means that you'll need to install inside the user's home directory instead of ProgramFilesDir and write registry entries only to HKEY_CURRENT_USER. For more details on how do this with a .MSI package, see this article. Inno Setup also has some details on limited user installs.
I don't think Visual Studio's setup project builder is capable of producing packages that don't require administrator rights to install. In any case, Vista seems to assume that anything that looks like a Setup.exe needs elevation (and results in the prompt).
Code signing will not remove the prompt, it will only make it say "Program XYZ from Developer Name wants access to your computer" instead of "An unknown program wants access to your computer".
You need a code signing digital certificate from a certificate authority like Comodo or VeriSign. It's debatable how useful it is, though, because it only replaces this scary-looking warning with a slightly less scary warning (yellow alert vs red alert) that says "Publisher: " instead of "Unidentified Publisher" and still tells the user only to run it if they trust you.
I'm somewhat doubtful that the average user really notices the difference between the two warnings.
Your application would need to be certified by microsoft.
User Account Control, as it says at the bottom of the dialog, but you don't want to do. No other way. Either that or get it signed/certified? :)
I need to store log files and configuration files for my application. Where is the best place to store them?
Right now, I'm just using the current directory, which ends up putting them in the Program Files directory where my program lives.
The log files will probably be accessed by the user somewhat regularly, so %APPDATA% seems a little hard to get to.
Is a directory under %USERPROFILE%\My Documents the best? It needs to work for all versions of Windows, from 2000 forward.
If you're not using ConfigurationManager to manage your application and user settings, you should be. The configuration toolkit in the .NET Framework is remarkably well thought out, and the Visual Studio tools that interoperate with it are too.
The default behavior of ConfigurationManager puts both invariant (application) and modifiable (user) settings in the right places: the application settings go in the application folder, and the user settings go in System.Environment.SpecialFolder.LocalApplicationData. It works properly under all versions of Windows that support .NET.
As for log files, System.Environment.SpecialFolder.LocalApplicationData is generally the place that you want to put them, because it's guaranteed to be user-writeable.
There are certainly cases where you wouldn't - for instance, if you want to write files to a network share so that you easily can access them remotely. There's a pretty wide range of ways to implement that, but most of them start with creating an application setting that contains the path to the shared folder. All of them involve administration.
I have a couple of complaints about ConfigurationManager and the VS tools: there needs to be better high-level documentation than there is, and better documentation of the VS-generated Settings class. The mechanism by which the app.config file turns into the application configuration file in the target build directory is opaque (and the source of one of the most frequently asked questions of all: "what happened to my connection string?"). And if there's a way of creating settings that don't have default values, I haven't found it.
Note: You can get the path to the LocalApplicationData folder in .NET by using the following function:
string strPath=System.Environment.GetFolderPath(System.Environment.SpecialFolder.LocalApplicationData);
For application settings - use System.Environment.SpecialFolder.ApplicationData - this is where a roaming profile data is stored, so it allows your user to log and work from different machines in the domain.
For log files - System.Environment.SpecialFolder.LocalApplicationData
The accepted answer notes that for log files the following is a good spot.
System.Environment.SpecialFolder.LocalApplicationData This equates to a path of C:\Users\[User]\AppData\Roaming which you can see is user specific. Like the accepted answer mentions this is a guaranteed user-writeable location and can be useful for certain situations
However in a web application environment you may be running your application under a network account and you or a coworker may need to try and track down where exactly those logs are going per application. I personally like to use the non user specific location enumeration of
System.Environment.SpecialFolder.CommonApplicationData which equates to C:\ProgramData. Yes, you will need to specify access rights for any folders you create, but it's usually a one time deal and then all of your application logs can live in one happy location.
Additionally, while looking around the Internet, there is a project out there to programatically set write access to folders you create within CommonApplicationData, Allow write/modify access to CommonApplicationData.
To be honest %appdata% is still the best place to place your config files and log files, as it serves the purpose of a placeholder to store your application data. It should not be that hard to access, just write %appdata% in explorer and you will be directed straight to your %appdata% directory.
Do not store config files in the application folder, Microsoft has stated this is NOT the ideal location. Windows has been moving towards blocking writing to C:\Program Files\ and you'll find in Vista any application that tries to write here, will fire up a UAC warning.
Windows 7 will allow users to customize what UAC popups they use (expect some power users to block most of them) and your app will fail/freeze if the user never approves this write attempt.
If you use the proper userprofile and appdata variables, then Win 2000, XP, Vista, and Win7 will map the data to the proper write friendly folder, with no UAC popups.
You can use SHGetSpecialFolderPath:
int MAX_PATH = 255;
CString m_strMyPath;
SHGetSpecialFolderPath(NULL, m_strMyPath.GetBuffer(MAX_PATH), CSIDL_COMMON_APPDATA, TRUE);
This will specify the 'special folder path' which you can safely write logs to for windows:
For XP: C:\Documents and Settings\All Users\Application Data
For Vista: C:\ProgramData
Check the MSDN page here: http://msdn.microsoft.com/en-us/library/bb762204(VS.85).aspx
The best answer depends on the nature of the logs and configurations. If they are program-wide, and don't need to survive uninstallation of the application, then I think they're fine where they are. If the logs and configurations are user specific, or need to survive uninstallation, then they belong somewhere under %USERPROFILE% - %APPDATA% being the 'proper' base directory for this type of thing.
I use the Isolation Storage for configuration. You can also use the Temp folder to store temporary information like log.