2

XP Pro SP3 の IIS で CGI アプリケーションとして実行されている C# プログラムがあります。ライブラリ アセンブリ クラスを参照してプログラムのコードで使用するまでは、正常に動作します。CGI プログラムを手動で実行すると、読み込まれて実行されます。しかし、IIS によって実行されると、参照されたアセンブリは、親の実行可能ファイルと同じディレクトリにあるにもかかわらず、バインドに失敗します。これが私が得るバインディングログです:

=== プレバインド状態情報 ===
ログ: ユーザー = STEVIENEW\IUSR_STEVIENEW
ログ: DisplayName = VOEvent、バージョン = 3.0.7.0、カルチャ = ニュートラル、PublicKeyToken = null
 (完全指定)
ログ: Appbase = file://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/
ログ: 初期 PrivatePath = NULL
アセンブリの呼び出し: MsgChkCGI、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null。
===
ログ: このバインドはデフォルトのロード コンテキストで開始されます。
ログ: アプリケーション構成ファイルが見つかりません。
ログ: c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config のマシン構成ファイルを使用しています。
ログ: 現時点ではポリシーが参照に適用されていません (プライベート、カスタム、部分、または場所に基づくアセンブリ バインド)。
ログ: 新しい URL ファイルのダウンロードを試みています://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent.DLL.
ログ: 新しい URL ファイルのダウンロードを試みています://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent/VOEvent.DLL.
ログ: 新しい URL ファイルのダウンロードを試みています://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent.EXE.
ログ: 新しい URL ファイルのダウンロードを試みています://?/C:/Documents and Settings/Robert B. Denny/My Documents/iis/vomsgtst/VOEvent/VOEvent.EXE.

Appbase は正しいです (ただし、URI の「?」は何ですか????? おそらくそれがヒントです)。アセンブリ voevent.dll は、MsgChkCGI.exe と同じディレクトリ (Appbase!) にあります。そして、exeをダブルクリックするだけで、正しく起動します(CGI環境変数がないためにエラーが発生しますが、これは予想どおりです)。

何が起こっているか知っている人はいますか?

4

3 に答える 3

3

なぜそうなるのかはわかりません。

回避策として、処理できますAppDomain.CurrentDomain.AssemblyResolve

編集:ハンドラーを追加する同じメソッドで別のアセンブリの型を使用する場合、メソッド内のコードが実際に実行される前にアセンブリが JITter によって読み込まれるため、イベントは発生しないことに注意してください。
したがって、別のアセンブリの型を使用するコードを別のメソッドに配置し、 を処理した後にそのメソッドを呼び出す必要がありますAssemblyResolve

2番目の編集: 呼び出しAssembly.Load(File.ReadAllBytes(path))ます。
また、質問を編集してFileNotFoundExceptionfromのすべての詳細を含めることはできますAssembly.LoadFileか?

于 2010-02-19T03:34:03.643 に答える
1

SLaksの回答に基づいて、解決策を書きました

Assembly assembly = Assembly.GetEntryAssembly();
Uri codeBaseUrl = new Uri(assembly.CodeBase);
// hack IIS CGI malformed url
if (codeBaseUrl.ToString().StartsWith("file:///?/"))
    codeBaseUrl = new Uri("file:///" + codeBaseUrl.ToString().Substring(10));
string dir = Uri.UnescapeDataString(codeBaseUrl.AbsolutePath);
dir = Path.GetDirectoryName(dir);

AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
    var dllName = new AssemblyName(args.Name).Name + ".dll";
    dllName = Path.Combine(dir, dllName);

    return Assembly.LoadFile(dllName);
};

ただし、不正な URL が原因で .NET の他の部分が失敗するため、URLfile:///?/を強制的に変更しないようにする方法を知りたいです。通常の URL を渡します。

于 2016-06-16T15:53:52.150 に答える
0

別の解決策は、別の CGI (PHP、別の EXE、または CMD など) から EXE を使用してプロセスを開始することです。

*.cmd を CGI として使用するには、EXE を実行する単純な CMD スクリプトを入力します。

@echo off
%~dp0\myprogram.exe

また、CMD を CGI として実行するように IIS を構成します。EXE ファイルの場合と同じように、適切な設定で CMD を入力するだけです。次にHandler Mappingsに移動し、 CGI-exeを選択して を に変更*.exe*.cmdます。最後に CGI パネルに移動し、Use new console...Trueに変更します。

于 2016-06-16T16:32:51.550 に答える