【问题标题】:Quit() causes Access to become visible for a momentQuit() 使 Access 暂时可见
【发布时间】:2019-09-30 22:58:58
【问题描述】:

我正在尝试连接到访问数据库并检索信息。

一切顺利,项目几乎完成,但我需要弄清楚如何退出互操作。

我首先创建我的访问应用程序,然后确保可见设置为 false。 (我没有看到 Access)但是一旦我的代码到达 app.Quit() 行(虽然使用 step 进行了验证),Access 就会在屏幕上闪烁,只是为了再次消失。

附加信息:如果我通过访问窗口执行一个步骤不会消失并且我无法手动关闭它(红色 x 右上角)。该应用程序只是重新打开空白。我必须强制关闭它。

正如您在我注释掉的代码中看到的那样,我使用 Process Kill 来确保屏幕上没有任何闪烁,但这会导致我的应用程序变得不稳定(由于崩溃而创建了如此多的访问数据库备份)。

如果您体验正常(空白凝视)。如果您有直觉,请至少让我知道从哪里开始挖掘。

static public DataTable ExecuteSQLToDataTable(string sql)
        {
            DataTable dt = new DataTable();

            lock (Locks.AccessDB)
            {
                Microsoft.Office.Interop.Access.Application accApp = new Microsoft.Office.Interop.Access.Application();
                accApp.Visible = false;
                Microsoft.Office.Interop.Access.Dao.Recordset rst = null;
                Microsoft.Office.Interop.Access.Dao.Database cdb = null;


                try
                {
                    accApp.OpenCurrentDatabase(ConnectionDatabase.DatabasePath, false, @"[somepassword]");

                    cdb = accApp.CurrentDb();
                    rst =
                        cdb.OpenRecordset(sql,
                        Microsoft.Office.Interop.Access.Dao.RecordsetTypeEnum.dbOpenSnapshot);
                    rst.MoveLast();
                    int recordCount = rst.RecordCount;
                    rst.MoveFirst();
                    object[,] recordsArray = (object[,])rst.GetRows(recordCount);

                    var rowCount = recordsArray.GetLength(1);
                    var columnCount = recordsArray.GetLength(0);

                    var dtTemp = new DataTable();
                    foreach (Microsoft.Office.Interop.Access.Dao.Field fld in rst.Fields)
                        dt.Columns.Add(fld.Name, typeof(string));

                    foreach (var r in Enumerable.Range(1, rowCount))
                        dt.Rows.Add(Enumerable.Range(1, columnCount)
                            .Select(c => recordsArray[c - 1, r - 1]).ToArray());

                }
                catch
                {
                    //TODO Add catch
                }
                finally
                {

                    GetWindowThreadProcessId(accApp.hWndAccessApp(), out int id);
                    if (rst != null) { Marshal.ReleaseComObject(rst); }
                    if (cdb != null) { Marshal.ReleaseComObject(cdb); }
                    if (accApp != null) { accApp.Quit(); Marshal.ReleaseComObject(accApp); }
                    rst = null;
                    cdb = null;
                    accApp = null;
                    //Process.GetProcessById(id).Kill();

                }

                return dt;
            }
        }

Locks 是一个静态类 Locks.AccessDB 只是一个空对象

【问题讨论】:

  • 如果我是你,我不会试图杀死它。我会将 Access 窗口移到看不见的地方 (SetWindowPos),然后我就不关心 Quit 做了什么。
  • 谢谢。这是我可以忍受的解决方法。我仍然想要一个答案来加深我的理解,但这对项目有用。再次感谢您。
  • 没有实际答案。显然,关闭 Access 正在做一些事情以在屏幕上显示自己。您对此无能为力。

标签: c# multithreading office-interop


【解决方案1】:

我倾向于相信,当您调用 all Quit() 时,Access 正在做自己的事情以在屏幕上显示自己。

您可以通过使用 SetWindowPos 将 Access 窗口移出屏幕来解决此问题,这样您在调用 Quit() 时就不会看到它。

【讨论】:

猜你喜欢
  • 2017-04-06
  • 2015-12-14
  • 2022-11-29
  • 1970-01-01
  • 2013-03-31
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
相关资源
最近更新 更多