2

我有一个 C# 程序在 XP Pro SP3 上的 IIS 中作为 CGI 应用程序运行。在我引用库程序集类并在程序代码中使用它之前,它运行良好。如果我手动运行 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。
===
LOG:此绑定在默认加载上下文中开始。
LOG:未找到应用程序配置文件。
LOG:使用来自 c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\config\machine.config 的机器配置文件。
LOG:此时未将策略应用于引用(私有、自定义、部分或基于位置的程序集绑定)。
日志:正在尝试下载新的 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

第二次编辑打电话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);
};

但是,.NET 的其他部分由于 URL 格式错误而失败file:///?/,所以我想知道如何强制不更改 URL 的解决方案。传递正常的 URL

于 2016-06-16T15:53:52.150 回答
0

另一种解决方案是使用来自另一个 CGI 的 EXE(例如来自 PHP、anotehr EXE 或 CMD)的 EXE 启动进程。

要将 *.cmd 用作 CGI,请键入运行 EXE 的简单 CMD 脚本

@echo off
%~dp0\myprogram.exe

并配置 IIS 以将 CMD 作为 CGI 运行。对 EXE 文件执行相同的操作,只需在正确的设置中键入您的 CMD。然后转到Handler Mappings,选择CGI-exe并将其更改*.exe*.cmd. 最后转到 CGI 面板并将Use new console...更改为True

于 2016-06-16T16:32:51.550 回答