长篇大论道歉。我的问题是允许我的用户为我的应用分配文件关联的最佳方法是什么。我已经把我到目前为止的地方包括在内,但我完全不确定我是以正确的方式看待它。
我的应用使用特定扩展名(.ad2)。它由使用XP,Vista和Win7的用户运行。我需要全力支持他们。在Vista和Win 7中,当然需要管理员权限。我的可执行文件的位置可能因用户安装位置而异。我认为一种好的方法是在安装时分配关联。这里的问题是我的一些用户不喜欢自动安装程序,而且已经有一个庞大的安装基础。所以我现在已经消除了这一点。
我想让我的用户控制他们是否关联,以便他们可以看到该过程
接下来我想到的是在通过菜单访问的应用程序中嵌入一些代码。这很好用,因为应用程序知道它的安装位置。但是它需要运行为管理员(我知道提升的权限适用于整个过程)。但是,用户需要在运行之前提升权限才能绕过UAC。
我上次认为它从Main App菜单项中弹出一个新进程,提升该进程的权限并允许它进行文件关联。带壳的可执行文件将与我的主应用程序位于同一文件夹中,因此它可以知道主要可执行文件和图标等内容。
我倾向于采用新流程 - 我是对的吗?
由于
答案 0 :(得分:1)
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>
注意:这不是一个完整的清单,我删除了requestedExecutionLevel
设置以外的所有内容。
这样做意味着应用程序在运行时会显示UAC提升对话框。
最后,这些都不能帮助非管理员用户。出于这个原因,我会选择per-user file associations。
答案 1 :(得分:0)
我用我的发现回答这个问题,因为它可能对其他人有用。我声称没有原创性,因为所有代码都来自其他人。我选择创建一个单独的可执行文件来运行文件关联设置。我从菜单项调用该程序:
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或更高版本且应用程序未以管理员权限启动,则不会启动。我这样做是因为用户可以直接运行外部应用程序。我使用的代码是:
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检查当前的Priviledges:
public static bool IsElevated {
get {
return new WindowsPrincipal
(WindowsIdentity.GetCurrent()).IsInRole
(WindowsBuiltInRole.Administrator);
}
}
同样,这不是我的代码,而是来自另一个答案。
虽然我相信有人会有更好的方法来做到这一点。我的外部应用程序是WinForm,虽然它可能是一个命令行。
EDIT 根据大卫的意见和建议,我知道这不是一个好办法。但是我希望整体问答(尤其是大卫的评论)对其他人来说是有益的