如何在后台运行模拟返回 (ENTER) 命中的程序



我编写了一个 C# 程序,将 1997 - 2003 .DOC Word 文档转换为文本文件。 我正在从命令行运行该程序。 我必须转换超过 300,000 个文档。 每个文档的处理时间从 0.7 秒到 1.5 秒不等。 该程序工作正常。 我正在使用库:

  • Microsoft.Office.Interop.Word

这里的问题是很少有Word文档损坏,有些启用了宏,有些被锁定以进行编辑等。 我能够处理大多数错误,除了一个。

我可以在此链接上找到我遇到的类似问题(除了我正在转换为 TXT 的事实(: Microsoft 互操作保存为命令失败

这是我的问题;我每 25 - 35 分钟收到一次错误。 该库中的某些内容会捕获错误并生成一个弹出窗口,说"文件遇到错误。命令失败",弹出窗口只有一个"确定"按钮。

当弹出警告消息窗口时,程序将暂停,直到有人手动点击"RETURN",或单击"确定"按钮。

如何编写在后台运行并模拟某人按下 RETURN 按钮的程序? 这样,在命令行中生成的弹出窗口将消失,我的程序将恢复。

class Program
{
    public static object refTrue = true;
    public static object refFalse = false;
    public static object refMissing = Type.Missing;
    static void Main(string[] args)
    {
        Word._Application word = null;
        Word.Documents documents;
        string dirpath = "C:\Blobs\directory\";
        String msserver = "SERVER";
        String msdatabase = "DB";
        String msconnstring = String.Format("Data Source={0};Trusted_Connection=yes;Database={1};MultipleActiveResultSets=true", msserver, msdatabase);
        using (System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(msconnstring))
        {
            //open connection
            con.Open();
            System.Data.SqlClient.SqlCommand cmdtest = con.CreateCommand();
            cmdtest.CommandText = "select f.filenamedoc from dbo.tb_worddtl_txt_ f left join  dbo.tb_worddtl_txt p on f.filenamedoc = p.filenamedoc where p.filenamedoc is null ";
            cmdtest.CommandType = CommandType.Text;
            cmdtest.CommandTimeout = 60;
            List<string> Filestoprocesstest = new List<string>();
            SqlDataReader missingFiles = cmdtest.ExecuteReader();
            while (missingFiles.Read())
            {
                Filestoprocesstest.Add(missingFiles[0].ToString().Trim());
            }
            //Will process missing files:
            foreach (string value in Filestoprocesstest)
            {
                Console.WriteLine(value);
                word = new Word.Application();
                documents = word.Documents;
                String file2p = dirpath.Trim() + value.Trim();
                Object filename = file2p;
                object newRefTargetFile = file2p.Replace(".doc", ".txt");
                if (File.Exists(file2p))
                {
                /** converts .DOC into .TXT **/
                    try
                    {
                        Word.Document document = documents.OpenNoRepairDialog(
                               ref filename,
                               ref refTrue,
                               ref refFalse,
                               ref refFalse,
                               ref refMissing,
                               ref refMissing,
                               ref refMissing,
                               ref refMissing,
                               ref refMissing,
                               ref refMissing,
                               ref refMissing,
                               ref refTrue,
                               ref refFalse,
                               ref refMissing,
                               ref refMissing,
                               ref refMissing);
                        if (document == null)
                            throw new Exception("Could not read " + filename);
                        word.Visible = false;
                        word.DisplayAlerts = Word.WdAlertLevel.wdAlertsNone;
                        object wdFormatDOSText = Word.WdSaveFormat.wdFormatDOSText;
                        word.Options.SavePropertiesPrompt = false;
                        word.Options.SaveNormalPrompt = false;
                        word.ActiveDocument.SaveAs(ref newRefTargetFile, ref wdFormatDOSText,
                            ref refMissing, ref refMissing, ref refMissing,
                            ref refMissing, ref refMissing, ref refMissing,
                            ref refMissing, ref refMissing, ref refMissing,
                            ref refMissing, ref refMissing, ref refMissing,
                            ref refMissing, ref refMissing);
                        word.Quit();
                        Thread.Sleep(500);
                        word = null;
                    }
                    catch (System.Runtime.InteropServices.COMException exception)
                    {
                        Console.WriteLine("An error was encountered with file: " + exception.Message);
                    }
                    finally
                    {
                        if (word != null)
                        {
                            word.Quit();
                        }
                        word = null;
                    }
                    /** Reads TXT **/
                    String filecontents = "";
                    try
                    {
                        using (StreamReader sr = new StreamReader((String)newRefTargetFile))
                        {
                            filecontents += sr.ReadToEnd();
                        }
                    }
                    catch (Exception e)
                    {
                        Console.WriteLine("The file could not be read:");
                        Console.WriteLine(e.Message);
                    }
                    /** Inserts TXT back into Database **/
                    System.Data.SqlClient.SqlCommand cmd = con.CreateCommand();
                    cmd.CommandText = "Insert into dbo.tb_worddtl_txt values (@filename, @sourcefile, @filetext)";
                    cmd.CommandType = CommandType.Text;
                    cmd.CommandTimeout = 60;
                    System.Data.SqlClient.SqlParameter param = cmd.Parameters.Add("@filename", SqlDbType.Text);
                    param.Value = file2p.Substring(20).Replace("doc", "txt");
                    param.Direction = ParameterDirection.Input;
                    param = cmd.Parameters.Add("@sourcefile", SqlDbType.Text);
                    param.Direction = ParameterDirection.Input;
                    param.Value = value;
                    param = cmd.Parameters.Add("@filetext", SqlDbType.Text);
                    param.Direction = ParameterDirection.Input;
                    param.Value = filecontents;
                    Console.Write("Processed: " + filename + "rn");
                    cmd.ExecuteNonQuery();
                }
            }
            con.Close();
            //OdbcConn.Close();
        }

您可以使用 SendKeys 类

SendKeys.Send("{ENTER}");

您可以查看 MSDN 以获取更多信息

我想出了问题所在。 在尝试退出 Word 实例后,word.Quit(); ,进程WINWORD.EXE仍在后台运行。 一些Word文档带有VB宏,而其他一些则使用MS Word扩展名(.dot(,这导致WINWORD.EXE流程实例无法发布,并且在某些情况下它生成了弹出窗口(例如上面描述的那个,以及其他一些诸如"是否要修改.dot扩展名"(。 此外,当我实际打开 Word 时,我有"从上次会话保存"的文档。 基本上,退出MS Word后使用该行Marshal.ReleaseComObject(documents);时,我所有的问题都消失了。 这一行发布了该迭代的 WINWORD.EXE 实例进程,我的程序运行非常流畅。

finally
{
    if (word != null)
    {
        word.Quit();
    }
    word = null;
}
Marshal.ReleaseComObject(documents);

最新更新