首先,此代码在VS2005中有效。
每当我尝试单步执行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;
}
StackTrace =
在System.Runtime.InteropServices.Marshal.ThrowExceptionForHRInternal(Int32 errorCode,IntPtr errorInfo)
在System.Management.ManagementObjectCollection.ManagementObjectEnumerator.MoveNext()
在AcpClasses.PrinterSpool.GetPrintersCollection()...
当我尝试在“本地”窗口中查看数据时,这些字段立即显示为怀疑:
1.计数 - 值:“功能评估超时。”
2. IsSynchronized - 值:由于先前的功能评估超时,因此功能评估被禁用
3. SyncRoot - 值:由于先前的功能评估超时,因此功能评估被禁用。
我如何尝试进一步调试以了解发生了什么?
答案 0 :(得分:1)
要进一步调试,您需要在进入foreach循环之前检查Printers
。
searchPrinters.Get()
行。另一件应该有用的事情就是将err.Message
更改为err.ToString()
。
为了它的价值,我调试了这个,没有运行VS 2005和&amp; 2008年在XP上。
编辑:发布代码供您试用。
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;
}
编辑:我唯一能想到的是手动浏览打印机和传真以查看是否有任何问题导致您。
答案 1 :(得分: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)
{....}`
Timeout的默认值必须是TimeSpan.MaxValue,但是......
在我的案例中,这是一个解决方案。