系统未经授权访问异常:拒绝访问路径“...”。

11

我已经完成了使用ClickOnce安装的.NET C# WPF安装。 一切正常。 然后,我有以下代码,它是安装程序的一部分:

String destinationPath = System.Windows.Forms.Application.StartupPath + "\\" + fileName;
File.Copy(path, destinationPath, true);
this.DialogResult = true;
this.Close();

但我得到了这个错误:

System.UnauthorizedAccessException:拒绝访问路径C:\ user \ pc \ appdata \ local \ apps \ 2.0.......。

在System.IO.File.InternalCopy(String sourceFileName,String destFileName,Boolean overwrite,Boolean checkHost)处 at System.IO.File.Copy(String sourceFileName,String destFileName,Boolean overwrite)

这是权限错误还是我需要调整一些代码?

令我困惑的是为什么用户能够使用一键单击将程序安装到该目录而没有任何问题,但上传文件却无法工作?


你的目标环境是什么,对其有多少控制权?是为企业组织还是个人使用? - Justin Loveless
我的目标更多是个人使用,但也可以用于企业。 - user5313398
1
不要试图将文件复制到您的应用程序文件夹中,如果用户修复或重新安装您的应用程序,则该文件夹可以被替换。请改用“ApplicationData”。 - Dour High Arch
我无法使用应用程序数据进行安装。所以,我必须更改一些设置才能将其安装在应用程序数据中吗? - user5313398
5个回答

10

安装应用程序时,安装程序通常会要求管理员权限。如果用户选择“是”,该程序将运行并具有读写访问更多路径的权限,而普通用户则没有这种权限。如果情况是安装程序没有要求管理员权限,那可能是ClickOnce自动以某种提升的权限运行。

我建议您写入本地appdata文件夹,但如果您真的想写入与应用程序相同的目录,则必须先使用管理员权限运行您的应用程序。

要始终要求您的应用程序具有管理员权限,可以修改应用程序的清单文件,将requestedExecutionLevel标记的level属性设置为requireAdministrator

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

您可以在如何强制我的.NET应用程序以管理员身份运行?中了解更多信息。


@user5313398: 我选择ClickOnce的原因是因为它不需要额外的权限设置,对吧? - 我对ClickOnce不是很熟悉,但你的应用程序很可能不会在与ClickOnce安装程序相同的特权下运行。如果Microsoft这样做就太愚蠢了,因为谁知道你的应用程序需要什么特权呢? - Visual Vincent
那么你现在最好的建议是先卸载它是什么? - user5313398
1
默认情况下,ClickOnce不包括管理员权限,并且在部署特定类型的应用程序时会使用一组特殊的权限,以及它被部署的位置(这就是为什么该应用程序可以安装到一个目录中,但当您运行该应用程序时,您不能写入该安装目录)。 - Justin Loveless
此外,要求应用程序具有管理员权限是不好的实践。如果你发现自己处于需要这样做的位置上,你可能需要首先重新考虑你正在做的事情,并查看是否可以以避免此类需求的方式重新设计你的解决方案。正如@user5313398所说,你使用ClickOnce是因为你不需要特殊的权限集。在企业环境中要求管理员权限是一场等待发生的噩梦。 - Justin Loveless
@JustinLoveless:我很清楚这一点,但如果他需要它在启动目录中,那么要么就是这样做,要么使用普通安装程序(这将需要管理员权限)。-- 不过,他也可以跳过安装程序,将所有内容打包成一个 .zip 文件。 - Visual Vincent
显示剩余23条评论

3

我正在运行一个生成文件的程序。目标文件夹是只读的。由于这个原因,它将会崩溃并显示错误。通过使用文件夹属性来移除只读属性可以解决这个问题。


1

首先,如果需要编写任何数据,应使用Environment.SpecialFolder枚举。

其次,不要写入应用程序部署的任何文件夹,因为通常对于应用程序而言是只读的。您可能想要写入ApplicationDataLocalApplicationData枚举。


@jb 我需要将许可文件加载到应用程序安装的位置吗?那么我最好的做法是什么? - user5313398
@user5313398,除非用户能够获得提升的权限,否则不可能实现。 - Justin Loveless
可能有多个问题。也许其他计算机上已禁用了UAC,或者存在不同的组策略设置等。也许其他用户能够以管理员身份运行该应用程序,并一直这样做。 - Justin Loveless
@那么,最好的建议是什么? - user5313398
1
@user5313398 不要写入那个文件夹。 - Justin Loveless
问题在于许可证必须与.exe文件在同一位置。 - user5313398

1

我认为在Windows 8(或7)及以后的版本中,默认情况下访问%appdata%是受限制的。

当通过ClickOnce安装应用程序时,您可能会被提示允许它更改此计算机 - 是这样吗?

您可以尝试以管理员权限运行该应用程序作为测试(按住Shift键,右键单击.exe文件,选择“以管理员身份运行”),这可能会解决问题,但这不是理想的方法。

相反,请尝试其他文件夹,例如:

Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)

或者

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments )

这应该会给你更好的运气。

顺便说一下 - 如果你正在编写代码中的路径,而不是使用

path + "\\" + path + "\\" + filename 

代码中如果路径可能已经以\结尾,这很容易导致错误。通常最好使用Path.Combine(..)方法。

String destinationPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), fileName);

我需要将许可文件加载到应用程序安装的位置,那么最好的方法是什么? - user5313398

0
在我的情况下,当我尝试下载(SFTP)文件并将其写入我们的本地/网络文件夹时,远程服务器会返回“。”和“..”。我不得不显式地丢弃“。”和“..”文件名。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接