【问题标题】:Microsoft Word Interop automation FilePrintSetup ErrorMicrosoft Word 互操作自动化 FilePrintSetup 错误
【发布时间】:2012-02-02 23:55:53
【问题描述】:

我收到“出现打印机错误”。在使用 Word 2010 在 Windows 7 上使用自动化将打印作业发送到打印机时。相同的代码在带有 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: 

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

谢谢。

【问题讨论】:

    标签: c# windows-7 office-interop office-2010 word-automation


    【解决方案1】:

    可能对您有用 - 这是我在 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<InstalledPrinter> 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<InstalledPrinter> 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<InstalledPrinter> list = new List<InstalledPrinter>(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 ? "<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;
                    }
                }
    

    【讨论】:

      【解决方案2】:

      没有找到解决问题的方法。放入 if 条件以不同方式处理 Word 2010 并使用非托管代码进行打印。 Link 概述了如何做到这一点

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-20
        • 1970-01-01
        • 1970-01-01
        • 2020-11-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多