【发布时间】:2010-09-09 20:55:57
【问题描述】:
我正在尝试找出是否有任何方法可以提升应用程序中的特定功能。例如,我有一个应用程序,其系统和用户设置存储在注册表中,我只需要在需要更改系统设置时进行提升。
不幸的是,我遇到的所有信息都在谈论仅以提升的权限启动新进程。
【问题讨论】:
我正在尝试找出是否有任何方法可以提升应用程序中的特定功能。例如,我有一个应用程序,其系统和用户设置存储在注册表中,我只需要在需要更改系统设置时进行提升。
不幸的是,我遇到的所有信息都在谈论仅以提升的权限启动新进程。
【问题讨论】:
不可能只提升一个功能或单个进程的任何其他部分,因为提升级别是每个进程的属性。就像怀孕一样,您的过程可以升高也可以不升高。如果您需要提升运行代码的某些部分,则必须启动一个单独的进程。
但是,如果您可以将函数实现为 COM 对象,则可以通过创建提升的 COM 对象来间接提升它,如下所示:
HRESULT
CreateElevatedComObject (HWND hwnd, REFGUID guid, REFIID iid, void **ppv)
{
WCHAR monikerName[1024];
WCHAR clsid[1024];
BIND_OPTS3 bo;
StringFromGUID2 (guid, clsid, sizeof (clsid) / 2);
swprintf_s (monikerName, sizeof (monikerName) / 2, L"Elevation:Administrator!new:%s", clsid);
memset (&bo, 0, sizeof (bo));
bo.cbStruct = sizeof (bo);
bo.hwnd = hwnd;
bo.dwClassContext = CLSCTX_LOCAL_SERVER;
// Prevent the GUI from being half-rendered when the UAC prompt "freezes" it
MSG paintMsg;
int MsgCounter = 5000; // Avoid endless processing of paint messages
while (PeekMessage (&paintMsg, hwnd, 0, 0, PM_REMOVE | PM_QS_PAINT) != 0 && --MsgCounter > 0)
{
DispatchMessage (&paintMsg);
}
return CoGetObject (monikerName, &bo, iid, ppv);
}
【讨论】:
我看过的最好的文章是这篇:
http://www.codeproject.com/KB/vista-security/UAC__The_Definitive_Guide.aspx
它解释了当现有 Microsoft 应用程序启动 UAC 提示时幕后发生的事情的本质,以及一些如何自己做的事情,或者至少你会知道你要做什么它工作......
(注意他展示的示例是托管 c++)
【讨论】:
找到nice article that covers this here:
大多数应用程序在运行时不需要管理员权限。如果您的应用程序在执行时不保持跨会话状态并且不执行修改本地安全策略之类的操作,那么使用标准用户令牌运行应该就可以了。有时您的应用程序的某些部分需要管理员权限,您应该将这些部分分离到一个单独的进程中。我稍后再谈。
看起来文章在谈论使用 C++,所以我找到了 another article,其中介绍了如何使用 P/Invoke 调用此代码。所以应该可以从 .NET 中实现。
【讨论】:
Windows SDK“交叉技术示例”有一个“UACDemo”应用程序,它显示了一个 C# Windows 窗体应用程序的示例,该应用程序启动一个管理员进程来执行需要提升的任务(即写入 %programfiles%)。
这是编写您自己的功能的一个很好的起点。我已将此示例扩展为使用 .Net Remoting 和 IPC 在我的普通用户进程和提升的进程之间进行调用,这使我能够保持提升可执行通用性并在应用程序中实现特定于应用程序的代码。
【讨论】:
您真正需要做的是将您的设置存储在 Application Data 文件夹中。
【讨论】:
我认为 Aydsman 在这里是正确的。在 .NET 3.5 中添加了命名管道支持后,您就拥有了一个不错的 IPC 机制来与提升的子进程进行通信。
【讨论】: