C# 应用程序文件关联

C# 应用程序文件关联,c#,C#,很抱歉发了这么长的帖子。我的问题是,允许我的用户向我的应用程序分配文件关联的最佳方法是什么。我已经包括了我到目前为止所取得的成就,但我根本不确定我是否以正确的方式看待它 我的应用程序使用特定的扩展名(.ad2)。它由使用XP、Vista和Win7的用户运行。我需要支持他们所有人。在Vista和Win 7中,这当然需要管理员权限。我的可执行文件的位置可能会因用户安装位置的不同而有所不同。我认为一个好方法是在安装时分配关联。这里的问题是,我的一些用户不喜欢自动安装程序,而且已经有很大的安装基数。所以

很抱歉发了这么长的帖子。我的问题是,允许我的用户向我的应用程序分配文件关联的最佳方法是什么。我已经包括了我到目前为止所取得的成就,但我根本不确定我是否以正确的方式看待它

我的应用程序使用特定的扩展名(.ad2)。它由使用XP、Vista和Win7的用户运行。我需要支持他们所有人。在Vista和Win 7中,这当然需要管理员权限。我的可执行文件的位置可能会因用户安装位置的不同而有所不同。我认为一个好方法是在安装时分配关联。这里的问题是,我的一些用户不喜欢自动安装程序,而且已经有很大的安装基数。所以我现在已经把它省略了

我想让我的用户控制他们是否关联,因此流程必须对他们可见

接下来我想到的是在通过菜单访问的应用程序中嵌入一些代码。这很好,因为应用程序知道它安装在哪里。但是,它需要以管理员身份运行(我知道提升的权限适用于整个流程)。但是,用户需要在运行前提升权限才能绕过UAC

我最后一个想法是,从主应用程序菜单项向外推出一个新进程,提升该进程的权限,并允许它进行文件关联。带外壳的可执行文件将与我的主应用程序位于同一文件夹中,因此它将知道主可执行文件和图标等内容的位置

我更倾向于采用新的流程,对吗


谢谢

我用我的发现来回答这个问题,因为它可能对其他人有用。我声称这没有独创性,因为所有代码都来自其他代码。我选择创建一个单独的可执行文件来运行文件关联设置。我从菜单项调用该程序,因此:

var proc = new ProcessStartInfo {
                UseShellExecute = true,
                WorkingDirectory = Environment.CurrentDirectory,
                FileName = Path.Combine(Application.StartupPath, "ADEFileAssociator.exe"),
                Verb = "runas"
            };

try {
      Process.Start(proc);
    }
catch {
       MessageBox.Show("Failed to start File Associator","Process Error",MessageBoxButtons.OK,MessageBoxIcon.Error);
       return;
       }
这里对另一个问题的回答中描述了这种方法,效果很好。如果操作系统为Vista或更高版本,且应用程序未以管理员权限启动,则文件关联程序ApplicApplication会仔细检查用户使用的操作系统,并且不会启动该应用程序。我这样做是因为用户可以直接运行外部应用程序。我使用的代码是:

 var safeToRun = true;
 var os = Environment.OSVersion;
 if (os.Version.Major > 5) {//Got Vista or Win7
     if (!IsElevated) {
         var message = new StringBuilder();
         message.AppendLine("You are running Vista or Win7 and this program ");
         message.AppendLine("needs to run with Admin Privileges. When the ");
         message.AppendLine("program closes please right click on the executable");
         message.AppendLine("or icon and select 'Run As Administrator'.");
         message.AppendLine("");
         message.AppendLine("The Program will now close.");
         MessageBox.Show(message.ToString(), "Insufficient Privileges", MessageBoxButtons.OK, MessageBoxIcon.Error);
         safeToRun = false;
     }
 }

 if (safeToRun) {
     Application.EnableVisualStyles();
     Application.SetCompatibleTextRenderingDefault(false);
     Application.Run(new MainForm());
 }
IsElevated检查当前权限:

public static bool IsElevated {
   get {
         return new WindowsPrincipal
            (WindowsIdentity.GetCurrent()).IsInRole
            (WindowsBuiltInRole.Administrator);
       }
}
同样,这不是我的代码,而是来自另一个答案

虽然我相信有人会有更好的方法去做。我的外部应用程序是WinForm,尽管它可能是命令行

编辑
根据大卫的意见和建议,我知道这不是一个好的做事方式。然而,我希望总体问题和答案(特别是David的评论)将对其他人具有指导意义

ScruffyDuck提出的解决方案使用了一种自主开发的UAC方法,这种方法是非标准的,功能不如内置于Windows中的标准设施和开发者预期使用的标准设施

需要管理员权限的应用程序应使用清单进行标记:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"> 
  <trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
    <security>
      <requestedPrivileges>
        <requestedExecutionLevel
          level="requireAdministrator"
          uiAccess="false"/>
        </requestedPrivileges>
       </security>
  </trustInfo>
</assembly>


.

您知道不需要提升权限才能设置的每用户关联吗?请在web上查找。这似乎比提升外部安装时间要好得多好-谢谢,我会看看你的UAC方法有多混乱。您只需在应用程序的清单中标记该应用程序需要提升(
requireAdministrator
),如果可以提供凭据,系统将提升或终止。这是一个非常糟糕的举动,你自己做。谢谢大卫。我非常感谢你的评论和建议。我已停止尝试以上述方式工作,我正在使用每个用户的文件关联