在程序文件下运行 .exe 时出现 System.UnauthorizedAccessException

Posted

技术标签:

【中文标题】在程序文件下运行 .exe 时出现 System.UnauthorizedAccessException【英文标题】:System.UnauthorizedAccessException while running .exe under program files 【发布时间】:2018-11-08 07:14:40 【问题描述】:

通过 WiX 安装程序,我安装了我的 Windows 应用程序,并在 c:\ProgramFiles 下使用 .exe 和所需的 dll 创建文件夹。

在运行 .exe 时,我得到了 System.UnauthorizedAccessException

如果有任何有用的建议,请告诉我。

请查找以下事件日志以供参考。

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)

【问题讨论】:

如果您以管理员身份运行程序,它会失败吗?如果不需要,您需要更新程序清单以指示它需要提升。与程序的安装程序无关。 我可能也会处理异常而不是崩溃:) @BrianSutherland 添加了一个包含如何创建清单的答案,但我认为 exe 不应该在 Program Files 文件夹中写入应用程序数据... 【参考方案1】:

不要试图写应用程序不应该写的地方。使用其他文件夹,例如:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

如果没有可能的替代方案,我非常怀疑,请以管理权限运行可执行文件。

https://msdn.microsoft.com/en-us/library/bb756929.aspx

【讨论】:

【参考方案2】:

交叉引用:一个相关的问题是如何存储应用程序的整体设置。放置文件或设置的位置: Create folder and file on Current user profile, from Admin Profile


原因

这看起来像一个简单的访问冲突 - 您尝试获取对您没有权限的文件的写访问权限 - 在您正在运行的上下文中(文件%ProgramFiles% 下的普通用户或非高级管理员不可写入 - 除非文件虚拟化,请参阅下面的 9 部分。

Here is a generic launch error check-list - 可能没用,因为你基本上有一个简单的访问冲突(看起来如此)。不知道为什么链接的答案被否决了。我可能搞砸了几点——这只是一个旨在激发一些想法的混乱列表。包括在这里以便于检索。


建议的可能修复方法

这里列出了一些可能的方法,您可以使用 work around the problemfix the cause of the problemredesign things 所以有效地避免了这个问题。有几种方法 这只是可能的,很少使用。 我会坦率地考虑 方法 10 - 用于设置的 HKCU 注册表项 - 结合云方法从只读设置文件中检索或复制。

以下列表不按优先顺序排列。事实上,在我看来,方法号1 是非常不可取的。方法6 可能是有效的,但不是那么好(当然比1 好)。我可以接受其他方法(9 除外),2 可能是最常用的方法。

1.提升应用程序(管理员权限):正如其他人建议的那样,您可以使用 管理员权限 运行您的应用程序(这些天非常糟糕的做法 - 管理员权限无处不在,关键是城市,并使您的应用程序成为黑客的目标,如果它包含口径的错误,也会使应用程序更加危险)。这是一个简短的操作方法:How do I force my .NET application to run as administrator?。

仅限管理员用户:至关重要的是,提升不适用于普通用户! (他们将被提示输入管理员密码)。 只有管理员可以提升空白管理员密码:如果盒子上有一个空白管理员密码(在家用电脑上很常见),任何用户都可以随意提升任何二进制集以提升到管理员权限(使用空白密码帐户)-登录到他们自己的受限帐户时(他们显然也可以使用空白密码帐户以管理员身份登录并启动任何东西-因此,无论提升问题如何,使用空白密码都存在安全漏洞- 但为什么允许使用空白密码帐户进行提升?)。 UAC:当 UAC 被禁用时会发生什么?可能只是没有提示标准用户输入密码,并且启动失败?我还没有机会尝试。 安全性:在某些情况下,提升的进程似乎能够启动其他提升的进程,这些进程可以比原始进程更持久(取决于启动用户的 NT 权限)。疯狂。

2.用户配置文件(移动文件):您可以确定导致访问冲突的文件(某种设置文件?)并移动它 到用户在所有情况下都具有常规访问权限的位置。 通常在用户个人资料中的某处(推荐)。

3.只读访问权限:很多时候,您可以通过只读访问设置文件逃脱。也许你可以强制执行这种方法 反而?这完全取决于您的应用程序的设计。也许你可以 handle the access denied exception 然后以只读方式运行?

4.内部默认值:作为一种只读方法,您可能会丢失整个设置文件并依赖内部默认值。很少 我认为的一个选项,但可能。如果您积极想这样做可能会很好 隐藏设置?你只是为用户编译一个新的二进制文件?

5.在线/云设置?:有些人喜欢完全删除设置文件(或将它们设为只读)然后检索 启动时数据库中的“真实设置”。这种方法可以有 显着优势 - 特别是对于企业应用程序 - 设置 管理和版本控制,消除用户配置文件漫游 问题等......(当然还有挑战 - network issuesfirewallproxyetc...)。

6. ACL 权限:您可以在安装时将 ACL 权限应用于相关文件,允许普通用户对其进行写入。 根本不是很棒的设计,但它会起作用。而且肯定比使用管理员权限(提升)运行更好 - 因为您可以确定所需的访问权限,而不仅仅是提升整个过程。不要只设置对整个文件夹的完全访问权限 - 仅对单个文件开放写访问权限。

WiX Permission Sample:这里有一段关于 ACL 权限的信息:How to deny folder permission to Users with wix installer。 WiX Permission Elements:这是另一个部分 - 中间页面 -(在 WiX 中应用权限的不同方法):Is WiX changing the permissions on my Notes.ini file? WiX Permission Documentation:实际的 WiX 文档在这里:http://wixtoolset.org/documentation/manual/v3/(搜索“permission” - 推荐上一个要点中的链接以了解不同元素之间的差异)。

7. Windows 服务:在某些情况下,可以将需要提升权限的应用程序部分作为 Windows 服务运行。这不是我经常看到的方法,但可能。然后,您安装该服务以作为 LocalSystem 或等效的提升帐户运行(or using service accounts - 请参阅“其他方法”部分 - 或 this alternative answer)。也许我也可以提及scheduled task - 我从未尝试过在这种情况下使用计划任务。

8.模拟:我想您可以模拟一个具有访问权限的帐户来写入相关位置。我不使用这种方法,所以我不确定技术细节、方面和挑战。只是把它作为一种选择。

9.虚拟化方法:仅提及这一点。各种形式的虚拟化 - 例如policies you can enable to allow file and registry write failures to be redirected to a writeable location(更多类似于data redirection - 随之而来的所有混乱 - 这不是解决方案 - 事实上微软打算在未来的 Windows 中删除该功能版本。不确定 Windows 10 中的状态。MSDN on Registry Virtualization)。一般没有问题解决,但有几个问题没有认识到。总体而言肯定会引起混淆,因为人们看不到数据写入的位置,并且数据不是在用户之间共享 - 而是特定于用户。还有全面的虚拟化/数据流,如 App-V 和允许完全访问的容器。不是我的专长,也不是我的偏好。

请不要使用这种虚拟化或数据重定向废话(这是为了旧应用程序不会崩溃,而不是为了新应用程序使用)。我仍然会添加一些技术细节的链接,以了解该功能的实际工作原理(在此重定向工作之前必须满足许多先决条件):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:最后但并非最不重要的一点应该提到,传统的设置管理方法是注册表 如果您希望每个用户都能够调整密钥,则为每个用户存储密钥。


下面的链接是关于每用户文件部署以及如何在包中完成的主题的答案,以及一些替代网络/数据库/云方法

这可能是一个复杂的阅读,但在这里 - 它本质上提供了上述可能性的更多排列

Create folder and file on Current user profile, from Admin Profile

一些链接

C++ MSI Package Administative Privileges(基本上是同一个问题) can give administration privileges to Application folder when creating windows installer WiX Toolset: install file with specific permissions

【讨论】:

【参考方案3】:

如果没有其他不需要管理权限的替代位置,您还可以利用 .NET 模拟概念。

这里是获取 .Net 模拟概述的链接。

How do you do Impersonation in .NET?

【讨论】:

【参考方案4】:

为 wix 尝试安装的项目打开 项目属性

转到安全

并将安全设置设置为

【讨论】:

以上是关于在程序文件下运行 .exe 时出现 System.UnauthorizedAccessException的主要内容,如果未能解决你的问题,请参考以下文章

c# winform程序发布后运行时出现的一个问题

新安装的vs2013运行时出现找不到.dll文件。

python打包时出现 Permission denied,然后dist下没有exe文件

在 Linux 中保存文件时出现 System.IO.DirectoryNotFoundException

程序 .exe 在 cygwin 上运行,但在调试和在 Visual Studio 上运行时出现异常

求助 关机问题;关机时出现:结束程序-12345