Печать с ASP.NET на сетевой принтер
Мне нужно отправить документы на сетевой принтер (\ myserver\myprinter). Я использую классы System.Printing для печати, и он отлично работает, когда он работает с Windows Service, но из приложения ASP.NET, он способен печатать только на локальные принтеры, а не на сетевые принтеры. Ошибка, которую я получаю, это "Имя принтера недействительно". Это то, что я использую, чтобы получить имя принтера:
public string PrinterName
{
using (LocalPrintServer server = new LocalPrintServer())
return server.GetPrintQueue(@"\\myserver\myprinter");
}
Каковы мои варианты здесь? Это проблема с разрешениями?
Ответы
Ответ 1
Есть проблемы с учетными данными, которые вы можете решить путем олицетворения или повышения прав пользователя, в котором работает веб-приложение.
Однако мы сделали это, добавив сетевой принтер в качестве принтера на сервере (добавьте диалог принтера на сервер) и выполнив задание, отправленное на этот принтер.
Мы использовали Print.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()
Ответ 2
По умолчанию приложение ASP.NET работает на специальной учетной записи с ограниченными правами. Достаточно просто, чтобы обслуживать веб-страницы, не более того. Поэтому вам нужно будет настроить пользователя ASPNET.
В отличие от этого службы Windows обычно запускаются под учетной записью локальной системы (с высокими привилегиями)
Ответ 3
Сетевая печать из ASP.Net/C# может быть выполнена с помощью:
Если сеть настроена для пользователей домена и принтер добавлен на сервер печати:
- Имя принтера, которое должно быть определено как = "\\ PrintServerIP_OR_Name\\PRINTERNAME"
Пример: PrinterSettings.PrinterName = "\\ 15.1.1.1\\prn001"
- Проверьте настройки разрешений на доступ к принтеру
- Которые либо являются пользователями домена, либо всем
- Если пользователи домена, то код С# может быть заключен в олицетворение, которое может использоваться для вызова кода печати, который выглядит следующим образом:
/// <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();
}