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.
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
).
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
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?