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时崩溃。
根据我的经验,从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.CurrentDirectory
和Directory.GetCurrentDirectory()
都会在从MS Access执行应用程序后立即返回我的"文档"文件夹。
我不知道为什么会发生这种情况,但它确实如此。
溶液:
如果你在你的机器上得到的结果和我在我的机器上得到的结果一样,你的问题的解决方案很简单:只需使用System.Threading.Thread.GetDomain().BaseDirectory
或AppDomain.CurrentDomain.BaseDirectory
来获取当前目录。
以防万一有人在使用 COM 互操作时遇到类似的问题:当您从 MS Access 通过 COM-Interop 执行 .NET 程序集时,问题甚至更糟。
如果我没记错的话,System.Threading.Thread.GetDomain().BaseDirectory
和AppDomain.CurrentDomain.BaseDirectory
都对我不起作用,因为两者都返回了msaccess.exe
的目录。
我必须使用this.GetType().Assembly.Location
来获取 .NET 程序集的实际位置。