【问题标题】:C# Remove Readonly From Main Application FolderC# 从主应用程序文件夹中删除只读
【发布时间】:2013-04-15 22:06:13
【问题描述】:

我正在尝试使用自动/自我更新程序构建应用程序。该文件将检查更新,然后立即下载文件并替换必要的文件。我一直在尝试将其放入安装程序包中,但遇到了应用程序文件夹只读的问题。我尝试使用多个 SO this one 中的代码删除 readonly 参数,但是在安装程序后,该文件夹仍然是只读的。

[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand)]
public override void Install(IDictionary stateSaver)
{
    base.Install(stateSaver);
    try
    {
        string path = this.Context.Parameters["targetdir"];
        path = path.Substring(0, path.Length - 1);

        DirectoryInfo di = new DirectoryInfo(path);
        di.Attributes &= ~FileAttributes.ReadOnly;
        di.Refresh();
    }
    catch (Exception e)
    {
    }
}

我也尝试将其放入 Commit 方法中。路径肯定被拉了(MessageBox.Show 显示了正确的路径)。

我需要做一些不同的事情来更改应用程序的主文件夹吗?


我不明白为什么更新程序进程在这个问题的上下文中很重要,但它是如何工作的:

  • 用户启动更新程序应用程序作为主应用程序的一种“门户”。
  • 更新程序会检查服务器是否有特定于该设备的更新。
  • 下载新文件并替换当前未锁定的所有文件。
  • 然后该 exe 调用一个辅助 exe 并自行关闭。帮助程序 exe 更新剩余文件(即更新程序本身)
  • 助手然后启动主应用程序。

【问题讨论】:

  • 您无法在 EXE 运行时覆盖它。
  • 我不会覆盖那个文件。我有一个单独的 exe 用于更新。
  • @Tom 即使有了启动器,您仍然不是在寻找只读标志,而是在寻找提升的权限
  • 你先退出原来的进程吗?
  • Windows 中没有“只读文件夹”的概念。但是,如果没有 UAC 提升,您的程序通常没有对安装位置的写入权限。您必须使用a manifest 向用户征求许可。

标签: c# visual-studio-2010 windows-installer


【解决方案1】:

您不是要删除只读标志,而是要提高在该文件夹中写入的权限 - 它一开始就不是只读的。

为此,您可以使用“RunAs”运行安装程序:

// launcher code
  if (CheckIfUpdateAvailable()){
    ProcessStartInfo startInfo = new ProcessStartInfo ("MyUpdater.exe");  
    startInfo.Verb = "runas";
    System.Diagnostics.Process.Start (startInfo); 
    Application.Quit();
  }

启动器生成的进程将有权写入您的应用文件夹

并且您的更新程序必须是与您的应用程序一起部署的可执行文件 - 您会发现很难覆盖正在运行的可执行文件的文件

或者您可以切换到 ClickOnce,这是免费的。当然 - 对于使用 ClickOnce 安装程序可以执行的操作有一些小的限制。

【讨论】:

  • 我们的应用程序正在对我无法控制的服务器使用一些自定义身份验证方法。安装程序应用程序也是启动器应用程序。类似于您可能看到的暴雪游戏更新。
  • @Tom 我听说过很多关于使用 MSI 的借口,这是一个典型的借口。您可以专注于答案的第一部分,它告诉您如何处理当前的情况
  • 我想说“原因”在这里更合适,但你的答案的两个部分都没有告诉我如何处理问题中的情况。
  • @Tom 对,“原因”...看看更新后的答案是否能让你更清楚你需要做什么,如果不是 - 告诉我什么不清楚
  • 由于启动器是更新程序而不是主应用程序,因此您的解决方案没有意义。
【解决方案2】:

http://support.microsoft.com/kb/981778

我最终为更新程序进行了自我提升(重新启动运行方式)。这只会在有可用更新时请求许可。

// During update process:
if (!IsAdministrator()) 
{
    // Launch itself as administrator
    ProcessStartInfo proc = new ProcessStartInfo();
    proc.UseShellExecute = true;
    proc.WorkingDirectory = Environment.CurrentDirectory;
    proc.FileName = Application.ExecutablePath;
    proc.Verb = "runas";

    try
    {
        Process.Start(proc);
    }
    catch
    {
        // The user refused to allow privileges elevation.
        // Do nothing and return directly ...
        return false;
    }
    Application.Exit();
}



public static bool IsAdministrator()
{
    var identity = WindowsIdentity.GetCurrent();
    var principal = new WindowsPrincipal(identity);
    return principal.IsInRole(WindowsBuiltInRole.Administrator);
}

另一个可行的解决方案,虽然不完全是我想要的,是检查每个项目的属性 -> 安全 -> 启用 ClickOnce 安全设置,然后构建安装程序。这很烦人,因为每次文件在 UAC 帐户上运行时都会请求许可。但是,它可以正常工作,并且不需要启动一些循环 exe。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-08
    • 1970-01-01
    • 2014-12-22
    • 2012-03-01
    • 2015-04-01
    • 2011-07-29
    相关资源
    最近更新 更多