写入Program Files文件夹

时间:2009-11-11 13:38:45

标签: c# uac cas

我的应用程序包含一个用于更新应用程序的自更新程序可执行文件。

更新程序执行的第一个步骤是检查它是否具有对应用程序文件夹的写入权限

IPermission perm = new FileIOPermission(FileIOPermissionAccess.AllAccess, _localApplicationCodebase);

        if (!SecurityManager.IsGranted(perm))
        {
            OnProgressChanged("Security Permission Not Granted \n The updater does not have read/write access to the application's files (" +
                              _localApplicationCodebase + ")",MessageTypes.Error);
            return false;
        }

        OnProgressChanged("Updater have read/write access to local application files at " + _localApplicationCodebase);
        return true;

if (!SecurityManager.IsGranted(perm)) { OnProgressChanged("Security Permission Not Granted \n The updater does not have read/write access to the application's files (" + _localApplicationCodebase + ")",MessageTypes.Error); return false; } OnProgressChanged("Updater have read/write access to local application files at " + _localApplicationCodebase); return true;

在Win7 / Vista下执行时,此代码传递(意味着根据CAS,代码确实具有写访问权限),但是当我尝试编写文件时,我得到了拒绝访问(并且我确认文件不是在使用中)

据我所知,Vista / Win7 UAC阻止用户在程序文件文件夹中写入文件。但是,我不明白的是,如果实际上它不是

,则授予许可

此致

Eric Girard

PS:如果我使用“以管理员身份运行”运行相同的代码,它可以正常运行

3 个答案:

答案 0 :(得分:6)

了解UAC的重要一点是,默认情况下,没有代码以管理员权限运行,因此无法写入Program Files目录。即使您以管理员身份登录,也会使用标准用户权限启动应用程序。

有两种解决方法。您可以让用户使用“以管理员身份运行”菜单项启动应用程序。但这依赖于用户记住一些东西。更好的是embed a manifest进入请求管理员权限的可执行文件。在清单中,将requestedExecutionLevel设置为requireAdministrator。这将导致UAC在应用启动后立即提示用户输入管理员凭据。

正如Daniel所说,最好的解决方案是将更新功能放在一个单独的应用程序中。您的主应用程序将有一个清单,将requestedExecutionLevel设置为“asInvoker”,并将updater应用程序设置为“requireAdministrator”。您的主应用程序可以使用标准权限运行。但是当需要更新时,请使用Process.Start启动需要用户输入管理员凭据的更新程序应用程序。

答案 1 :(得分:4)

编写自动更新程序的最佳方法是使用辅助应用程序。第一个程序使用提升的权限调用第二个程序,提示UAC。然后第二个应用程序可以安装补丁。

答案 2 :(得分:1)

我不确定这是不是你想要做的,但我发现这篇文章很有帮助。如果您的应用程序在Vista上运行,如果启用了UAC并且用户是否已提升,则可以使用所包含的代码检测。

http://www.itwriting.com/blog/198-c-code-to-detect-uac-elevation-on-vista.html

然后使用runas重启您的应用以让用户提升权限

ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.Verb = "runas";
processInfo.FileName = Application.ExecutablePath;
Process.Start(processInfo);