Microsoft Word Interop自动化FilePrintSetup错误

我收到“有打印机错误。” 当在Windows 7上使用Word 2010使用自动化时,使用自动化将打印作业发送到打印机时。相同的代码在使用Word 2007的Windows XP盒上工作正常。我不确定Windows 7或Word 2010是否导致错误。

任何帮助赞赏

using Microsoft.Office.Interop.Word; ..... object oWordbasic = wordDoc.Application.WordBasic; object[] argValues = new object[] { value, 1 }; //first arg is a printer name String[] argNames = new String[] { "Printer", "DoNotSetAsSysDefault", }; //Error Here oWordbasic.GetType().InvokeMember("FilePrintSetup", System.Reflection.BindingFlags.InvokeMethod, null, oWordbasic, argValues, null, null, argNames); 

我得到下面的错误

 System.Reflection.TargetInvocationException was caught Message=Exception has been thrown by the target of an invocation. Source=mscorlib StackTrace: at System.RuntimeType.InvokeDispMethod(String name, BindingFlags invokeAttr, Object target, Object[] args, Boolean[] byrefModifiers, Int32 culture, String[] namedParameters) at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams) at PBP.ABC.Framework.Wrappers.Microsoft.Word.WordDocument.set_ActivePrinterName(String value) in InnerException: System.Runtime.InteropServices.COMException HelpLink=wdmain11.chm#24696 Message=There is a printer error. Source=Microsoft Word ErrorCode=-2146827168 InnerException: 

如果我省略了打印机参数,则调用工作但不能打印到指定的打印机。 它将打印到默认打印机。

谢谢。

可能会为你工作 – 这是我必须在Word中进行打印而不更改活动打印机,我收到一个错误,发现有时Word只喜欢打印机名称,其他时候也想拥有端口。

…获取打印机名称和端口使用InstalledPrinter,如下所示

 private InstalledPrinter PreferredPrinter { get; set; } private InstalledPrinter DefaultPrinter { get; set; } private void SetDefaultAndPreferredPrinters() { if (UserSettings[SETTING_PREFERRED_PRINTER] == null) { UserSettings[SETTING_PREFERRED_PRINTER] = string.Empty; } _preferredPrinterName = ((string)UserSettings[SETTING_PREFERRED_PRINTER]).Trim(); List installedPrinters = InstalledPrinter.GetList(); DefaultPrinter = null; PreferredPrinter = null; foreach (InstalledPrinter installedPrinter in installedPrinters) { if (installedPrinter.IsDefault) { DefaultPrinter = installedPrinter; } if (installedPrinter.Name.Equals(_preferredPrinterName, StringComparison.InvariantCultureIgnoreCase)) { PreferredPrinter = installedPrinter; } } } public enum PrinterStatus{ Other = 1, Unknown, Idle, Printing, Warmup, Stopped, Offline, Degraded } public class InstalledPrinter{ private static readonly ILog _s_logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); public string DriverName { get; set; } public string Location { get; set; } public string Name { get; set; } public bool Network { get; set; } public string PortName { get; set; } public string ServerName { get; set; } public bool Shared { get; set; } public PrinterStatus Status { get; set; } public bool WorkOffline { get; set; } public bool IsDefault { get; set; } public static List GetList() { PrinterSettings ps = new PrinterSettings(); string sDefault = ps.PrinterName; string query = "Select * From Win32_Printer"; ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); ManagementObjectCollection results = searcher.Get(); List list = new List(results.Count); foreach (ManagementObject printManagementObject in results) { InstalledPrinter entry = new InstalledPrinter(); foreach (PropertyInfo propertyInfo in typeof(InstalledPrinter).GetProperties()) { object[] oparams = {1}; if (propertyInfo.Name != "IsDefault") {//The IsDefault property is worked out logically, the rest of the properties map identically to the columns of the WMI query results. try { oparams[0] = ConvertValue( printManagementObject[propertyInfo.Name], propertyInfo.PropertyType); propertyInfo.GetSetMethod().Invoke( entry, oparams); }catch(Exception e) { _s_logger.Error(string.Format("Failed to enumerate printer property Name:{0}, Type:{1}", propertyInfo.Name, propertyInfo.PropertyType)); } } } _s_logger.Info(string.Format("Finished enumerating properties of printer: {0}", entry.Name == null ? "" : entry.Name)); if (sDefault.Equals(entry.Name, StringComparison.CurrentCultureIgnoreCase)) { entry.IsDefault = true; } list.Add(entry); } return list; } private static object ConvertValue(object value, Type type) { if (value != null) { object printerStatusRetval = null; if (type == typeof(DateTime)) { string time = value.ToString(); time = time.Substring(0, time.IndexOf(".")); return DateTime.ParseExact(time, "yyyyMMddHHmmss", null); } else if (type == typeof(long)) return Convert.ToInt64(value); else if (type == typeof(int)) return Convert.ToInt32(value); else if (type == typeof(short)) return Convert.ToInt16(value); else if (type == typeof(string)) return value.ToString(); else if (type == typeof(PrinterStatus)) try { printerStatusRetval = Enum.Parse(typeof (PrinterStatus), value.ToString()); } catch (Exception e) { _s_logger.Error(string.Format("Failed to convert PrinterStatus with value {0}", value)); printerStatusRetval = value.ToString(); } return printerStatusRetval; } return null; } 

}

…然后在实例化Word后我有类似的东西来设置打印机:

  object[] oWordDialogParams = {PreferredPrinter.Name, true}; object[] oWordDialogParamsWithPort = {string.Format("{0} on {1}", PreferredPrinter.Name, PreferredPrinter.PortName), true}; string[] argNames = {"Printer", "DoNotSetAsSysDefault"}; //oWord is my own class that provides a fairly simple wrapper around MS Word oWord.Application.ActivePrinter = UserSettings[SETTING_PREFERRED_PRINTER] as string; Dialog printDialog = oWord.Application.Dialogs[WdWordDialog.wdDialogFilePrintSetup]; object wordBasic = oWord.Application.WordBasic; try { wordBasic.GetType().InvokeMember("FilePrintSetup" , BindingFlags.InvokeMethod , null , wordBasic , oWordDialogParams , null , null , argNames); }catch(Exception e) { _s_logger.Info("Failed to print using printer name, trying printer name and port", e); try { wordBasic.GetType().InvokeMember("FilePrintSetup" , BindingFlags.InvokeMethod , null , wordBasic , oWordDialogParamsWithPort , null , null , argNames); }catch(Exception e2) { _s_logger.Info("Failed to print using printer name and port", e2); throw; } } 

没有找到解决问题的方法。 放入if条件以不同方式处理Word 2010并使用非托管代码进行打印。 链接概述了如何执行此操作