4

私が作成したツールを実行するためのボタンが付いた MS Access データベースがあります。ツールは機能します。Access DB は動作します。ツールを実行するための VBA が機能します。

ただし、VBA からツールを実行すると問題が発生します。XML 構成データをロードしようとすると、常にクラッシュします。エラー報告ツール (コントロール パネル -> 管理ツール -> イベント ビューア) をチェックして、これをテストしました。また、すべての XML データをハードコーディングしたツールの 2 番目のバージョンも作成しました。

これが発生する既知の理由があるかどうか、およびこのエラーを回避するための実行可能な解決策があるかどうか疑問に思っています。プロジェクト全体を再コンパイルして更新をプッシュすることなく、構成データを変更可能にする必要があるため、すべての構成データをハードコーディングすることは理想的なソリューションではありません。

情報:

  • MS Access 2010 with Visual Basic 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 )

このアプリケーションは、ユーザーが csv 内の列名をアクセス中のフィールドにマップできるようにする WinForms アプリケーションです。唯一の実際の問題は、XML 構成データをロードしようとする部分です。

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

繰り返しますが、構成データをアプリケーション自体にハードコーディングしても、アプリケーションの実行時にまったく問題はありません。ただし、XML 構成データを読み込もうとすると、XML ファイルの読み込み中に未処理の例外が発生したことを示すエラー イベントがイベント ビューアに表示されます。VBA シェル呼び出しの外でアプリケーションを実行すると、問題なく動作し、XML ファイルをロードできます。VBA シェルから XML を読み込もうとしたときにのみクラッシュします。

4

1 に答える 1

2

私の経験では、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:\Users\MyUserName\Documents
C:\Users\MyUserName\Documents
C:\Program Files (x86)\mytool\
C:\Program Files (x86)\mytool\

変ですね。
Environment.CurrentDirectoryアプリケーションがMS Accessから実行されるとすぐに、Directory.GetCurrentDirectory()両方とも私の「ドキュメント」フォルダを返します。
なぜこれが起こるのかわかりませんが、そうです。

解決策:
あなたのマシンで私のマシンと同じ結果が得られた場合、問題の解決策は簡単です: System.Threading.Thread.GetDomain().BaseDirectoryorAppDomain.CurrentDomain.BaseDirectoryを使用して現在のディレクトリを取得するだけです。


COM-Interop を使用しているときに誰かが同様の問題を抱えている場合に備えて: MS Access から COM-Interop を介して .NET アセンブリを実行すると、問題はさらに悪化します。
正しく思い出せば、と の両方が のディレクトリを返したため、どちらも機能System.Threading.Thread.GetDomain().BaseDirectoryAppDomain.CurrentDomain.BaseDirectoryませんでしたmsaccess.exe。.NET アセンブリの実際の場所を取得するため
に使用する必要がありました。this.GetType().Assembly.Location

于 2012-05-21T21:24:35.127 に答える