C# 在windows server 2012 R2中使用模拟通过IIS打印失败

C# 在windows server 2012 R2中使用模拟通过IIS打印失败,c#,.net,iis,printing,impersonation,C#,.net,Iis,Printing,Impersonation,我试图通过使用下面的代码进行模拟来访问网络打印机,以便从IIS(WCF应用程序)打印pdf文档。由于我的wcf应用程序在“LocalSystem”应用程序池标识下运行,因此我需要进行模拟 [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] public class Impersonation : IDisposable { private readonly SafeTokenH

我试图通过使用下面的代码进行模拟来访问网络打印机,以便从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; }
}
但是打印不适用于这种模拟,尽管我可以列出网络打印机,但当我将文档发送到打印机时,它不会打印。它在打印队列中显示为空。有什么想法吗

以下是我在模拟下调用的Microsoft打印代码:

代码示例:

using (new Impersonation(domain, username, password)) 
{ 
  //printing code goes here.
}

能否在iis express下运行该应用程序并验证其是否正常工作?我只想确定是不是IIS安全沙箱导致了这种情况。因为IIS有一个安全沙盒和系统。绘图可能无法完全工作,因为服务器没有IIS express。但是,如果我在本地设备(windows 7和IIS 7.5)上运行应用程序,它会成功运行。一切正常。但当我在Windows Server 2012 R2(IIS 8.5)中部署相同的应用程序时,它不会打印(也不会给出任何异常或错误),而是将文档转到打印队列,但大小没有说明任何内容。