DLLImport在VS中工作,但在IIS中不工作

时间:2014-10-10 12:08:16

标签: c# asp.net web-services iis dll

我们有使用第三方DLL的Soap Webservice项目。在Visual Studio中,当我运行程序时,它完美地工作。它可以找到dll。但是当我把项目放到IIS中时,webservice找不到dll。这是下面的DLLImport部分。

[DllImport(@"/dll/y1d431_mit.dll",
        EntryPoint = "Y1DPackG", SetLastError = false, ExactSpelling = true)]
    private static extern void Y1DPackG(ref int ErrorNumb, ref int ErrorMsgs,
        string RegCustomer, int RegPassword, int CostOptim, int IgnoreLast,
        int EffortLev, int ReduceLays, int PrefShort, int DiffStocks,
        int DiffPieces, int ReusLength, int GapItIt, int GapItEnd,
        int GapGripEnd, int OptimTime, int IterMult, int LayByMark,
        int RunMsgMode, int ReservInp2, ref int StockGrLth, ref int StockGrCst,
        ref short StockGrQty, ref int PartGrLth, ref int PartGrMrkID, ref short PartGrQty,
        ref int Critsum, ref int Effsum, ref int StockSum, ref int PartSum,
        ref int LengthSum, ref int WasteSum, ref int CostSum, ref int LastStockNo,
        ref int LastParts, ref int LastLength, ref int LastWaste, ref int LastCost,
        ref int PatternSum, ref int LayoutSum, ref int LayoutCuts, ref int ReservOut1,
        ref int ReservOut2, ref short StockGrNo, ref short PartGrNo, ref short PartStockNo,
        ref short StockLayNo, ref short StockPatNo, ref short StockParts, ref int StockWaste);

IIS根据DLLImport语句在哪里查找dll文件?我应该在哪里根据DLLIMPORT语句放置dll文件,以便IIS找到它?

2 个答案:

答案 0 :(得分:1)

加载Sysinternal的免费process monitor。在运行执行dllimport的代码之前启动它,并在错误输出后停止事件收集。此工具将告诉您正在发生的每件事情,包括IIS开始搜索它的位置。它还会告诉您是否收到权限错误。

如果64位系统上的32位dll,权限错误很可能会因为dll将通过WOW64运行而可能被复制到WOW64目录中执行。默认情况下,这不是任何匿名互联网用户帐户有权访问的目录。

答案 1 :(得分:1)

谢谢马克。 Process Monitor准确地显示了Windows在哪里寻找我的DLLImport非托管/本机DLL及其所有从属/导入。我找到2种方法来找到我的DLL:

方法1:SetDllDirectory()

using System.Web;

public myClass
{
    private static bool dllIsLoaded = false;

    [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    static extern bool SetDllDirectory(string lpPathName);

    public void myDllLoader()
    {
        if (!dllIsLoaded)
        {
#if DEBUG
            string dllDir = Path.Combine(HttpRuntime.AppDomainAppPath, @"Lib\Debug\");
#else
            string dllDir = Path.Combine(HttpRuntime.AppDomainAppPath, @"Lib\Release\");
#endif
            SetDllDirectory(dllDir);
             // Call any function in your DLL to load it.  Stays loaded for the duration of the app.
            string ver = myDllGetVersion();
            SetDllDirectory("");    // Reset path to original

            dllIsLoaded = true;
        }
    }
}

方法2:在PATH环境变量前加上我的DLL的应用程序目录:

using System.Web;

string dllDir = Path.Combine(HttpRuntime.AppDomainAppPath, @"myAppDLLDirectory\");
string currentPath = Environment.GetEnvironmentVariable("path");
Environment.SetEnvironmentVariable("path", $"{dllDir};{currentPath}");

此PATH修改仅影响当前进程。

p.s。如果您的错误消息说找不到DLL,但是您的DLL在DLL搜索路径中,则实际上可能意味着找不到您要导入的DLL之一。例如,我的DLL依赖于开发计算机上的“ vcruntime140d.dll”和“ ucrtbased.dll”,而不依赖于要部署到的服务器。使用“ dumpbin.exe / imports my.dll”列出依赖项。可从Visual Studio“ x64本机工具命令提示符”中获得转储。