2009-10-05 34 views
0

首先,此代码在VS2005中工作。Win32_Printer ManagementObjectSearcher错误(VS2008 C#)

无论何时尝试跨越foreach循环并分配ManagementObject时,VS2008中的代码都会崩溃并伴随UnauthorizedAccessException。

public static List<string> GetPrintersCollection() { 
    if (printers == null) { 
    printers = new List<string>(); 
    string searchQuery = "SELECT * FROM Win32_Printer"; 
    try { 
     using (ManagementObjectSearcher searchPrinters = new ManagementObjectSearcher(searchQuery)) { 
     ManagementObjectCollection Printers = searchPrinters.Get(); // <= Printers data below 
     foreach (ManagementObject printer in Printers) { // <= Error Here 
      printers.Add(printer.Properties["Name"].Value.ToString()); 
     } 
     } 
    } catch (UnauthorizedAccessException err) { 
     Console.WriteLine(err.Message); // the message is an empty string 
     throw new Exception("PrinterSpool - GetPrintersCollection: You do not have authorization to access this printer."); 
    } catch (Exception err) { 
     throw new Exception(string.Format("PrinterSpool - GetPrintersCollection: {0}", err.Message)); 
    } 
    } 
    return printers; 
} 

堆栈跟踪=
在System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(的Int32的errorCode,IntPtr的errorInfo中)
在System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
在AcpClasses.PrinterSpool.GetPrintersCollection ()...

当我尝试查看本地窗口中的数据时,这些字段看起来立即可疑:
1.计数 - 值:“功能评估超时。
2. IsSynchronized - 值:功能评估由于先前的功能评估超时而被禁用。
3. SyncRoot - 值:功能评估被禁用,因为之前的功能评估超时。

我该如何尝试进一步调试以找出发生了什么?

+0

评论: 其他地方定义为列表 printers = null; 此代码也不再适用于Visual Studio 2005(我刚刚查询了仅查询Win32_Printer的控制台应用程序)。 – jp2code 2009-10-05 15:20:13

+0

我在回答中添加了一些代码,可以帮助诊断您的问题。 – 2009-10-05 19:54:15

回答

1

要进一步调试,您需要在进入foreach循环之前检查Printers

  1. searchPrinters.Get()行上设置断点。
  2. 新闻F10
  3. 现在检查您的项目。

另一件应该帮助的事情是将err.Message更改为err.ToString()

对于它的价值,我在XP上运行VS 2005 & 2008时没有任何问题进行调试。

编辑:发布代码供您试用。

public static List<string> GetPrintersCollection() 
{ 
    if (printers == null) 
    { 
     printers = new List<string>(); 
     string searchQuery = "SELECT * FROM Win32_Printer"; 
     try 
     { 
      using (ManagementObjectSearcher searchPrinters = new ManagementObjectSearcher(searchQuery)) 
      { 
       ManagementObjectCollection Printers = searchPrinters.Get(); // <= Printers data below 
       foreach (ManagementObject printer in Printers) 
       { 
        printers.Add(printer.Properties["Name"].Value.ToString()); 
       } 
      } 
     } 
     catch (UnauthorizedAccessException err) 
     { 
      //Log & re-throw 
      Console.WriteLine("Caught UnauthorizedAccessException: " + err.ToString()); 
      throw; //re-throw existing exception, not a new one 
     } 
     //there's no reason to catch the plain-old Exception 
    } 

    return printers; 
} 

编辑:我能想到的唯一的另一件事是手动完成的打印机和传真,看看是否有导致问题的为您服务。

+0

- \t \t \t打印机{System.Management.ManagementObjectCollection} \t System.Management.ManagementObjectCollection '+' 计数\t 'Printers.Count' 扔类型 'System.UnauthorizedAccessException的' – jp2code 2009-10-05 17:46:07

+0

同时,err.ToString的异常() “PrinterSpool - GetPrintersCollection:您没有权限访问此打印机。\ System \ n在System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()\ r \ n在win32_printer.Program.GetPrintersCollection() – jp2code 2009-10-05 17:46:42

+0

上面的信息有帮助吗?我不知道如何处理它。显然,我是我自己机器上的管理员,但我也希望此应用程序能够在其他机器上为其他人(即非管理员)工作。 ***(注意:很抱歉在多条评论中发布此回复,但是SO似乎对评论长度施加了限制,并且我不知道如何以其他方式回复邮件。)*** – jp2code 2009-10-05 17:49:06

1

尝试超时这个

 `string strQuery = "SELECT * FROM Win32_Printer"; 

     ObjectQuery objectQuery = new ObjectQuery(strQuery); 

     ManagementObjectSearcher query = new ManagementObjectSearcher(objectQuery); 
     query.Options.Timeout=new TimeSpan(0,0,5); 
     ManagementObjectCollection queryCollection = query.Get(); 

      foreach (ManagementObject managementObject in queryCollection) 
      {....}` 

默认值必须是TimeSpan.MaxValue,但是......

这是在我的情况的解决方案。