我的应用程序带有需要以管理员身份运行的清单,但应用程序的一部分是使用WNetAddConnection2映射驱动器,我相信由于凭据等原因需要在正常的用户环境中运行。有没有办法在普通用户上下文中执行这段代码而不创建单独的进程。
修改
从评论中我得到了这么多,但它不起作用。我预计它不会因为我真的不明白我应该如何使用它。也许最好是我打开一个新问题?
class Program
{
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
[DllImport("advapi32.DLL")]
public static extern bool RevertToSelf();
static void Main(string[] args)
{
IntPtr phToken = IntPtr.Zero;
ImpersonateLoggedOnUser(phToken);
MapDrives();
RevertToSelf();
}
}
修改
如果当前用户具有管理员权限,那么主进程将使用清单提升,在提升的代码中我想在用户非提升空间中运行命令,因为它似乎具有不同的环境变量等。相信一旦线程启动它就无法改变自己,它需要运行一个新线程。
答案 0 :(得分:4)
查看A small C# Class for impersonating a User代码项目文章。它实现了一个IDisposable类(在使用后释放身份验证令牌)。我已经看到.NET代码泄漏是因为没有发布模拟令牌。
您只能为一个代码块模拟用户,该代码块将访问您需要以其他用户身份访问的网络资源。您的代码看起来像
using ( new Impersonator( "myUsername", "myDomainname", "myPassword" ) )
{
/* code that executes under the new context */
...
}
我希望它有所帮助。
答案 1 :(得分:1)
首先,您需要获取要启动应用的用户令牌,您可以使用WTSQueryUserToken执行此操作。如果用户尚未登录,您可以使用LogonUser Win32 API在新会话中获取新的。要获取计算机上的所有会话,您可以使用WTSEnumerateSessions。
然后,一旦获得令牌,您就可以使用CreateProcessAsUser或其他ImpersonateLoggedOnUser Win32 API。
请确保在您获得的手柄上调用CloseHandle
,这类工作特别容易泄漏。
答案 2 :(得分:0)
我不确定这是一种在不创建新进程的情况下执行此操作的方法,ImpersonateLoggedOnUser只能在服务中运行,而且我不想提供凭据。
如果我错了,请纠正我