10

I need to send documents to a network printer (\myserver\myprinter). I'm using the System.Printing classes to print, and it works fine when it's from a Windows Service, but from an ASP.NET app, it's only able to print to local printers, not network printers. The error I'm getting is "Printer Name is not valid" This is what I'm using to get the printer name:

public string PrinterName
{
   using (LocalPrintServer server = new LocalPrintServer())
   return server.GetPrintQueue(@"\\myserver\myprinter");
}

What are my options here? Is this a permissions problem?

4

3 回答 3

5

默认情况下,ASP.NET 应用程序在具有有限权限的特殊帐户上运行。只够服务网页,仅此而已。因此,您必须配置 ASPNET 用户。

相比之下,Windows 服务通常在本地系统帐户下运行(具有高权限)

于 2010-09-16T17:36:23.870 回答
5

您可以通过模拟或提升运行 Web 应用程序的用户的权限来解决凭据问题。

但是,我们通过将网络打印机添加为服务器上的打印机(在服务器上添加打印机对话)并将作业发送到该打印机来做到这一点。

我们像这样使用了 Printing.PrintDocument(VB 中的代码)......

Public Class SpecialReportPrintJob
  Inherits Printing.PrintDocument

Protected Overrides Sub OnBeginPrint(ByVal ev as Printing.PrintEventArgs)
  MyBase.OnBeginPrint(ev)

  Me.PrinterSettings.PrinterName = "PrinterNameUsedOnServer"

  'setup rest of stuff....
End Sub  
End Class
'And we then call it like so
Dim printSpecialReport as new SpecialReportPrintJob()
printSpecialReport.Print()
于 2010-09-16T17:43:38.923 回答
1

可以使用 ASP.Net/C# 进行网络打印:

如果为域用户配置了网络并将打印机添加到打印服务器:

  • PrinterName 要定义为 = "\\PrintServerIP_OR_Name\\PRINTERNAME" 示例:PrinterSettings.PrinterName = "\\15.1.1.1\\prn001"
  • 检查打印机访问权限集
  • 哪个是域用户或所有人
  • 如果是域用户,则可以将 C# 代码包含在可用于调用打印代码的模拟中,如下所示:
/// <summary>
    /// Does the actual impersonation.
    /// </summary>
    /// <param name="userName">The name of the user to act as.</param>
    /// <param name="domainName">The domain name of the user to act as.</param>
    /// <param name="password">The password of the user to act as.</param>
    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 );
                        impersonationContext = 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 ( impersonationContext!=null )
        {
            impersonationContext.Undo();
        }   
    }

    private WindowsImpersonationContext impersonationContext = null;

首先调用模拟用户,然后调用如下所示的打印函数:

if(ImpersonateValidUser("username", "domain", "password"))
{
  PrintDetails();
  UndoImpersonation();
}

于 2016-05-14T12:21:39.420 回答