我试图在Impersonation下使用Process.Start(),我有谷歌几天,我遇到的大多数答案是在ASP.net下,但我正在为Window Application开发,所以我很难找到根本原因.
这是我的冒充代码
private void impersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
if ( LogonUser( userName, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
mImpersonationContext = tempWindowsIdentity.Impersonate();
}
}
}
Run Code Online (Sandbox Code Playgroud)
我试图通过我的程序打开文档(没有.exe,如.txt,.doc)
using (new Impersonator(DomainUserID, Domain, Password))
Process.Start(filePath);
Run Code Online (Sandbox Code Playgroud)
到目前为止,我能够使用模拟用户检测目录/文件,这对我当前的登录用户来说是不可见的,因为我没有授予它访问权限.但每当我尝试打开文档时,我都会收到错误
System.ComponentModel.Win32Exception (0x80004005): Access is denied
Run Code Online (Sandbox Code Playgroud)
如果我错了请纠正我,所以在这种情况下,我不认为将UseShellExecute设置为false(还有用户名和密码输入的processStartInfo?)因为它是可执行文件(?),我确实遇到过使用CreateProcessAsUser函数,这个函数似乎也不适用于我的情况,从我为.exe文件读取它的例子.
如果有人能够启发我,我将不胜感激.
更新:模拟类
public class Impersonator : IDisposable
{
#region P/Invoke
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int LogonUser( string lpszUserName,
string lpszDomain,
string lpszPassword,
int dwLogonType,
int dwLogonProvider,
ref IntPtr phToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern int DuplicateToken( IntPtr hToken,
int impersonationLevel,
ref IntPtr hNewToken);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern bool RevertToSelf();
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern bool CloseHandle(IntPtr handle);
#endregion
#region Constants
private const int LOGON32_LOGON_INTERACTIVE = 2;
private const int LOGON32_PROVIDER_DEFAULT = 0;
#endregion
#region Attributes
private WindowsImpersonationContext mImpersonationContext = null;
#endregion
#region Public methods.
public Impersonator( string userName, string domainName, string password)
{
impersonateValidUser(userName, domainName, password);
}
#endregion
#region IDisposable member.
public void Dispose()
{
undoImpersonation();
}
#endregion
#region Private member.
private void impersonateValidUser(string userName, string domain, string password)
{
WindowsIdentity tempWindowsIdentity = null;
IntPtr token = IntPtr.Zero;
IntPtr tokenDuplicate = IntPtr.Zero;
try
{
if ( RevertToSelf() )
{
if ( LogonUser( userName, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token) != 0)
{
if ( DuplicateToken( token, 2, ref tokenDuplicate ) != 0 )
{
tempWindowsIdentity = new WindowsIdentity( tokenDuplicate );
mImpersonationContext = tempWindowsIdentity.Impersonate();
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
else
{
throw new Win32Exception( Marshal.GetLastWin32Error() );
}
}
finally
{
if ( token != IntPtr.Zero )
{
CloseHandle( token );
}
if ( tokenDuplicate != IntPtr.Zero )
{
CloseHandle( tokenDuplicate );
}
}
}
/// <summary>
/// Reverts the impersonation.
/// </summary>
private void undoImpersonation()
{
if ( mImpersonationContext != null )
{
mImpersonationContext.Undo();
}
}
#endregion
}
Run Code Online (Sandbox Code Playgroud)
UseShellExecute = true模仿时不能使用。这与 Windows 中 shell 执行的方式有关。基本上所有内容都会传递到外壳程序,外壳程序查找如何处理动词(在您的情况下为“打开”),然后在拥有外壳程序的用户下启动应用程序,该用户不是模拟用户 - 模拟用户实际上没有如果没有会话,则为 shell!
尽管您使用不同的机制来模拟用户,但文档仍然UseShellExecute适用于您的情况:
UseShellExecuteUserName如果属性不为 null 或空字符串,则必须为 false ,否则调用InvalidOperationException该方法时将抛出异常。Process.Start(ProcessStartInfo)
要解决此问题,最简单的方法可能是自行查找注册的应用程序,如本答案中所述:查找用于在 Windows 上打开特定文件类型的默认应用程序。通过关联应用程序的路径,您可以以其他用户身份启动可执行文件。
| 归档时间: |
|
| 查看次数: |
2702 次 |
| 最近记录: |