1

我将 WebApplication 的 gPRC 版本从0.12.0更新到0.13.0,但它开始无法创建Channel对象。以下是抛出的异常:

在此处输入图像描述

它试图定位grpc_csharp_ext.dllAppData\\Local\\Temp\\Temporary ASP.NET Files\\root\\c8490d1a\\9f150f28\\assembly\\dl3\\5d08d985\\2c1c8757_6474d101\\nativelibs\\windows_x86\\grpc_csharp_ext.dll. 我什至将 DLL 存储在本地bin文件夹中,但这并没有帮助。如果我创建控制台应用程序,则不会出现此问题。我不确定它为什么要在所述位置搜索 dll?有谁知道如何使它适用于 Web 应用程序?

编辑GRPC 社区根据链接修复了此问题。我也验证了相同的。现在我们需要保留grpc_csharp_ext.dllbin\nativelibs\windows_x86\(对于 32 位 dll)和bin\nativelibs\windows_x64\(对于 64 位 dll)

4

1 回答 1

0

Asp.net在动态编译期间执行影子复制程序集。它复制 Grpc.Core.dll 但不复制包含本机grpc_csharp_ext.dll文件的文件夹nativelibs。我已经通过以编程方式处理nativelibs文件夹解决了这个问题。

从 Global.asax 中的 Application_Start 调用复制方法。

public class WebApplication : HttpApplication
{
    protected void Application_Start()
    {
        GrpcInitializer.EnsureGrpcCSharpExtNativeDll();
    }
}

复印机:

public static class GrpcInitializer
{
    public static void EnsureGrpcCSharpExtNativeDll()
    {
        var grpcCoreAssembly = Assembly.GetAssembly(typeof(Grpc.Core.Channel));
        var srcFolderPath = Path.GetDirectoryName(new Uri(grpcCoreAssembly.CodeBase).LocalPath);

        CopyGrpcCSharpExtNativeDll(srcFolderPath);
    }

    public static void CopyGrpcCSharpExtNativeDll(string srcFolderPath)
    {
        var grpcCoreAssembly = Assembly.GetAssembly(typeof(Grpc.Core.Channel));
        var grpcDllLocation = Path.GetDirectoryName(grpcCoreAssembly.Location);
        if (grpcDllLocation == null)
            return;

        var targetFolderPath = Path.Combine(grpcDllLocation, "nativelibs");
        if (Directory.Exists(targetFolderPath))
            return;

        srcFolderPath = Path.Combine(srcFolderPath, "nativelibs");

        DirectoryCopy(srcFolderPath, targetFolderPath, true);
    }

    private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
    {
        if (string.IsNullOrEmpty(sourceDirName) || string.IsNullOrEmpty(destDirName))
        {
            throw new ArgumentNullException(
                $"Directory paths cannot be empty. sourceDirName: {sourceDirName} | destDirName: {destDirName}");
        }

        var dir = new DirectoryInfo(sourceDirName);
        if (!dir.Exists)
        {
            throw new DirectoryNotFoundException("Source directory does not exist or could not be found: " +
                                                 sourceDirName);
        }

        var dirs = dir.GetDirectories();
        if (!Directory.Exists(destDirName))
        {
            Directory.CreateDirectory(destDirName);
        }

        var files = dir.GetFiles();
        foreach (var file in files)
        {
            string temppath = Path.Combine(destDirName, file.Name);
            file.CopyTo(temppath, false);
        }

        if (copySubDirs)
        {
            foreach (var subdir in dirs)
            {
                var temppath = Path.Combine(destDirName, subdir.Name);
                DirectoryCopy(subdir.FullName, temppath, true);
            }
        }
    }
}
于 2016-03-28T11:47:24.590 回答