VBA,MS访问和外部应用程序

本文关键字:外部 应用程序 访问 MS VBA | 更新日期: 2023-09-27 18:34:46

我有一个MS Access数据库,上面有一个按钮,应该运行我编写的工具。该工具有效。访问数据库工作正常。运行该工具的 VBA 有效。

但是,从VBA运行该工具时存在问题。尝试加载 XML 配置数据时,它总是崩溃。我通过检查我的错误报告工具(控制面板 -> 管理工具 ->事件查看器(对此进行了测试。我还编写了我的工具的第二个版本,其中包含所有XML数据硬编码到其中。

我想知道是否有发生这种情况的已知原因,以及是否有可行的解决方案来解决此错误。硬编码我的所有配置数据并不是一个理想的解决方案,因为配置数据需要可修改,而无需重新编译整个项目并推出更新。

信息:

  • MS Access 2010 with Visual Basic for Applications (使用 Shell for Applications应用程序调用(
  • 使用引用的 XML 配置数据的 C# 应用程序(IO、Linq、Xml.Linq、Data.OleDb、全球化(

感谢您提供的任何帮助。

根据请求,以下是我用于运行应用程序的代码:

Dim hProcess As Long
Dim myPath As String
dim myFile As String
myPath = Environ("ProgramFiles(x86)" & "'mytool'"
myFile = "mytool.exe"
hProcess = Shell( myPath & myFile, vbNormalFocus )

该应用程序是一个 WinForms 应用程序,允许用户将 csv 中的列名映射到访问中的字段。唯一实际的问题是它尝试加载 XML 配置数据的部分:

XDocument xDoc = XDocument.Load(Environment.CurrentDirectory + "''config.xml");

同样,如果我将配置数据硬编码到应用程序本身中,则在运行应用程序时根本没有问题。但是,如果我尝试加载 XML 配置数据,它会在事件查看器中给出一个错误事件,指出加载 XML 文件时存在未经处理的异常。如果我在 VBA Shell 调用之外运行应用程序,它运行良好并且可以加载 XML 文件。它仅在尝试从VBA命令行管理程序加载XML时崩溃。

VBA,MS访问和外部应用程序

根据我的经验,从MS Access执行.NET代码似乎"搞砸"了一些.NET 的"获取当前目录"方法,如果您在没有 Access 的情况下直接运行完全相同的 .NET 应用程序,这些方法都可以正常工作。

如果您想了解我在说什么,请在 Visual Studio 中创建一个新的控制台应用程序并粘贴以下代码:

using System;
using System.IO;
namespace CurrentDirTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(Environment.CurrentDirectory);
            Console.WriteLine(Directory.GetCurrentDirectory());
            Console.WriteLine(System.Threading.Thread.GetDomain().BaseDirectory);
            Console.WriteLine(AppDomain.CurrentDomain.BaseDirectory);
            Console.ReadLine();
        }
    }
}

当我直接从Visual Studio运行时,它会输出以下内容(如预期的那样(:

C:''Dev''Code''CurrentDirTest''CurrentDirTest''bin''Debug
C:''Dev''Code''CurrentDirTest''CurrentDirTest''bin''Debug
C:''Dev''Code''CurrentDirTest''CurrentDirTest''bin''Debug''
C:''Dev''Code''CurrentDirTest''CurrentDirTest''bin''Debug''

现在,将已编译.exe放在Program Files (x86)'mytool'文件夹中,并尝试使用问题中的VBA代码从Access调用它。

当我在我的机器上执行此操作时,我得到这个:

C:''用户''我的用户名''文档
C:''用户''我的用户名''文档
C:''程序文件 (x86(''mytool''
C:''程序文件 (x86(''mytool''

很奇怪,不是吗?
Environment.CurrentDirectoryDirectory.GetCurrentDirectory()都会在从MS Access执行应用程序后立即返回我的"文档"文件夹。
我不知道为什么会发生这种情况,但它确实如此。

溶液:
如果你在你的机器上得到的结果和我在我的机器上得到的结果一样,你的问题的解决方案很简单:只需使用System.Threading.Thread.GetDomain().BaseDirectoryAppDomain.CurrentDomain.BaseDirectory来获取当前目录。


以防万一有人在使用 COM 互操作时遇到类似的问题:当您从 MS Access 通过 COM-Interop 执行 .NET 程序集时,问题甚至更糟。
如果我没记错的话,System.Threading.Thread.GetDomain().BaseDirectoryAppDomain.CurrentDomain.BaseDirectory都对我不起作用,因为两者都返回了msaccess.exe的目录。
我必须使用this.GetType().Assembly.Location来获取 .NET 程序集的实际位置。