我正在尝试通过使用以下代码进行模拟来从IIS(WCF应用程序)打印pdf文档来访问网络打印机。由于我的wcf应用程序在“LocalSystem”应用程序池标识下运行,我需要进行模拟。
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public class Impersonation : IDisposable
{
private readonly SafeTokenHandle _handle;
private readonly WindowsImpersonationContext _context;
bool disposed = false;
// constants from winbase.h
const int LOGON32_LOGON_INTERACTIVE = 2;
const int LOGON32_LOGON_NETWORK = 3;
const int LOGON32_LOGON_BATCH = 4;
const int LOGON32_LOGON_SERVICE = 5;
const int LOGON32_LOGON_UNLOCK = 7;
const int LOGON32_LOGON_NETWORK_CLEARTEXT = 8;
const int LOGON32_LOGON_NEW_CREDENTIALS = 9;
const int LOGON32_PROVIDER_DEFAULT = 0;
const int LOGON32_PROVIDER_WINNT35 = 1;
const int LOGON32_PROVIDER_WINNT40 = 2;
const int LOGON32_PROVIDER_WINNT50 = 3;
public Impersonation(ImpersonateUserDetails user) : this(user.Domain, user.UserName, user.Password)
{ }
public Impersonation(string domain, string username, string password)
{
// if domain name was blank, assume local machine
if (string.IsNullOrEmpty(domain))
domain = System.Environment.MachineName;
var ok = LogonUser(username, domain, password,
LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, out this._handle);
if (!ok)
{
var errorCode = Marshal.GetLastWin32Error();
throw new ApplicationException(string.Format("Could not impersonate the elevated user. LogonUser returned error code {0}.", errorCode));
}
this._context = WindowsIdentity.Impersonate(this._handle.DangerousGetHandle());
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
this._context.Dispose();
this._handle.Dispose();
}
disposed = true;
}
~Impersonation()
{
Dispose(false);
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);
sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
{
private SafeTokenHandle()
: base(true) { }
[DllImport("kernel32.dll")]
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
[SuppressUnmanagedCodeSecurity]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool CloseHandle(IntPtr handle);
protected override bool ReleaseHandle()
{
return CloseHandle(handle);
}
}
}
public class ImpersonateUserDetails
{
public string UserName { get; set; }
public string Password { get; set; }
public string Domain { get; set; }
}
但是虽然我可以列出网络打印机,但打印不适用于此模拟,但是当我将文档发送到打印机时它不会打印。它在打印队列中显示大小为空。请问任何想法???
以下是微软的打印代码,我在模仿时调用: https://msdn.microsoft.com/en-us/library/system.drawing.printing.printdocument.print(v=vs.110).aspx
代码示例:
using (new Impersonation(domain, username, password))
{
//printing code goes here.
}