![](/img/trans.png)
[英]Access Denied when calling PrintQueue.Pause() method in C#.net
[英]Access Denied trying to purge printqueue in C#
我正在尝试在C#中创建一个清空打印队列中所有项目的方法。 以下是我的代码:
LocalPrintServer localPrintServer = new LocalPrintServer(PrintSystemDesiredAccess.AdministratePrinter);
PrintQueue printQueue = localPrintServer.GetPrintQueue(printerName);
if (printQueue.NumberOfJobs > 0)
{
printQueue.Purge();
}
当此代码运行时,在localPrintServer构造函数上,应用程序抛出此错误:“创建PrintServer对象时发生异常.Win32错误:访问被拒绝。”
该构造函数有一些重载(包括不发送参数)。 尝试其中任何一个,我越过那一行,但是当我进入printQueue.Purge()调用时,我得到了与上面列出的相同的访问被拒绝消息。
寻找有关如何/我可以做些什么的建议来解决这个问题。 我可以从我的电脑手动删除打印作业。 我不确定应用程序是否以相同的访问权限运行,也不确定如何检查。
此问题是由GetPrintQueue
方法稍微有点引起的,因为它不允许您传入所需的访问级别。 使用您的代码,您将使用AdministratePrinter
权限(没有意义)连接到打印服务器 ,并使用默认用户权限连接到打印队列 。 因此,即使Everyone对打印队列具有管理员权限,操作也会失败。
要解决此问题,请使用PrintQueue
的构造函数来指定正确的访问级别:
using (PrintServer ps = new PrintServer()) {
using (PrintQueue pq = new PrintQueue(ps, printerName,
PrintSystemDesiredAccess.AdministratePrinter)) {
pq.Purge();
}
}
如果您没有在Administrators组成员的上下文中运行(或者没有使用提升的权限运行),这可能仍会导致权限错误,因此使用try / catch块进行此操作对于生产代码来说是一个好主意。
您是否以4.0运行网站? 当我们将网站从3.5升级到4.0 Framework时,我遇到了问题。 Print Purging功能在4.0 Framework中停止运行。 最终,我最终创建了一个使用3.5框架的Web服务,并让4.0网站将要清除的打印机与3.5 Web服务进行通信。
(抱歉要复活这个帖子,这是我在寻找答案时偶然发现的一个主题。想想我会发布这个,如果它可以帮助那些遇到相同情况的人)
最近,我将.net框架从4.0升级到4.6.1后遇到了同样的问题。 奇怪的是,我的.net应用程序在.net 3.5上运行,但不知怎的,它受到了这种变化的影响。
无论如何,我运行应用程序的方式是通过任务调度程序,修复是右键单击任务,一般情况下,选中名为“以最高权限运行”的框。
我想如果你在控制台上运行它,你需要在打开cmd窗口时“以管理员身份运行”。
我尝试使用@mdb解决方案,但它不起作用(使用Framework .NET 4.6.1拒绝访问)。 所以我最终使用了以下解决方案:
void CleanPrinterQueue(string printerName)
{
using (var ps = new PrintServer())
{
using (var pq = new PrintQueue(ps, printerName, PrintSystemDesiredAccess.UsePrinter))
{
foreach (var job in pq.GetPrintJobInfoCollection())
job.Cancel();
}
}
}
//以此为例让您入门......
/// <summary>
/// Cancel the print job. This functions accepts the job number.
/// An exception will be thrown if access denied.
/// </summary>
/// <param name="printJobID">int: Job number to cancel printing for.</param>
/// <returns>bool: true if cancel successfull, else false.</returns>
public bool CancelPrintJob(int printJobID)
{
// Variable declarations.
bool isActionPerformed = false;
string searchQuery;
String jobName;
char[] splitArr;
int prntJobID;
ManagementObjectSearcher searchPrintJobs;
ManagementObjectCollection prntJobCollection;
try
{
// Query to get all the queued printer jobs.
searchQuery = "SELECT * FROM Win32_PrintJob";
// Create an object using the above query.
searchPrintJobs = new ManagementObjectSearcher(searchQuery);
// Fire the query to get the collection of the printer jobs.
prntJobCollection = searchPrintJobs.Get();
// Look for the job you want to delete/cancel.
foreach (ManagementObject prntJob in prntJobCollection)
{
jobName = prntJob.Properties["Name"].Value.ToString();
// Job name would be of the format [Printer name], [Job ID]
splitArr = new char[1];
splitArr[0] = Convert.ToChar(",");
// Get the job ID.
prntJobID = Convert.ToInt32(jobName.Split(splitArr)[1]);
// If the Job Id equals the input job Id, then cancel the job.
if (prntJobID == printJobID)
{
// Performs a action similar to the cancel
// operation of windows print console
prntJob.Delete();
isActionPerformed = true;
break;
}
}
return isActionPerformed;
}
catch (Exception sysException)
{
// Log the exception.
return false;
}
}
如果您不介意清除本地计算机上的所有队列,则可以使用以下代码段。 它需要管理员权限,但不会抛出异常:
System.ServiceProcess.ServiceController controller = new System.ServiceProcess.ServiceController("Spooler");
controller.Stop();
System.IO.DirectoryInfo info = new System.IO.DirectoryInfo(@"C:\Windows\System32\spool\PRINTERS");
var files = info.GetFiles();
foreach (var file in files)
{
file.Delete();
}
controller.Start();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.