如果我尝试在与我位于同一域中的计算机中打开注册表(并且我的登录用户在目标计算机上具有管理员权限),则此 .NET API可以正常工作。
如果它是具有不同本地管理用户(我确实有密码)的域外计算机,则会变得棘手。
在调用 OpenRemoteBaseKey() 之前,我尝试使用WNetUseConnection()(在过去我想要读取远程磁盘文件的情况下,这对我很有帮助),但没有骰子——我得到一个拒绝访问异常。
显然,我必须以其他方式传递凭据,但如何?
如果我尝试在与我位于同一域中的计算机中打开注册表(并且我的登录用户在目标计算机上具有管理员权限),则此 .NET API可以正常工作。
如果它是具有不同本地管理用户(我确实有密码)的域外计算机,则会变得棘手。
在调用 OpenRemoteBaseKey() 之前,我尝试使用WNetUseConnection()(在过去我想要读取远程磁盘文件的情况下,这对我很有帮助),但没有骰子——我得到一个拒绝访问异常。
显然,我必须以其他方式传递凭据,但如何?
我成功用来访问计算机上的文件的是以下代码:
#region imports
[DllImport("advapi32.dll", SetLastError = true)]
private static extern bool LogonUser(string
lpszUsername, string lpszDomain, string lpszPassword,
int dwLogonType, int dwLogonProvider, ref
IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
private static extern bool CloseHandle(IntPtr handle
);
[DllImport("advapi32.dll", CharSet = CharSet.Auto,
SetLastError = true)]
public extern static bool DuplicateToken(IntPtr
existingTokenHandle,
int SECURITY_IMPERSONATION_LEVEL, ref IntPtr
duplicateTokenHandle);
#endregion
#region logon consts
// logon types
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
// logon providers
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT50 = 3;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT35 = 1;
#endregion
然后部分签名,只需使用:
IntPtr token = IntPtr.Zero;
bool isSuccess = LogonUser("username", "domain", "password",
LOGON32_LOGON_NEW_CREDENTIALS,
LOGON32_PROVIDER_DEFAULT, ref token);
using (WindowsImpersonationContext person = new WindowsIdentity(token).Impersonate())
{
//do your thing
person.Undo();
}
如您所见,“Undo()”将使您不再以该用户身份登录。所以在你完成之前不要使用它。但不要忘记使用它!