确定服务器或客户端上的应用程序执行目录

时间:2013-12-19 21:29:28

标签: c# asp.net-mvc unit-testing system.reflection

这是我的问题。我想在运行时将库加载到我的应用程序中。这将允许应用程序使用接口的新实现而无需重新编译。应用程序将在其自己的目录中搜索库。我有代码可以达到这个目的:

 var path = Assembly.GetExecutingAssembly().Location;
 path = Path.GetDirectoryName(path);
 path = Path.Combine(path, "<my assembly>.dll");

 var assembly = Assembly.LoadFile(path);

此代码在单元测试中完美运行。但是,该应用程序是一个Web应用程序。当我将此代码作为应用程序的一部分运行时,Assembly.GetExecutingAssembly().Location将返回.net框架内的临时目录。 (C:\ Windows \ Microsoft.NET \ Framework64 \ v4.0.30319 \ Temporary ASP.NET Files \ ...)我可以通过使用Server.MapPath解决这个问题,但是代码将不再是单元可测试的

我真的很想找到能够以平台无关的方式给我执行目录的东西,也就是说,它会在单元测试和Web应用程序中搜索正确的目录。

我试过了:

Assembly.GetExecutingAssembly().Location //Works as a test but not on a server
Application.ExecutablePath //Not an executable, so this won't work
System.AppDomain.CurrentDomain.BaseDirectory //Almost works in web app, but stops too early in the directory structure
Environment.CurrentDirectory //returns system32 directory

2 个答案:

答案 0 :(得分:1)

这是我在测试环境和Web应用程序中使用的:

    private static string AssemblyDirectory
    {
        get
        {
            string codeBase = Assembly.GetExecutingAssembly().CodeBase;
            var uri = new UriBuilder(codeBase);
            string path = Uri.UnescapeDataString(uri.Path);
            return Path.GetDirectoryName(path);
        }
    }

答案 1 :(得分:0)

您可以使用此类方法。它将返回装配的真实位置。

public static string GetAssemblyLocation(Assembly assembly)
{
    if (assembly.IsDynamic)
    {
        return null;
    }

    string codeBase = assembly.CodeBase;
    UriBuilder uri = new UriBuilder(codeBase);

    string path = Uri.UnescapeDataString(uri.Path);
    path = Path.GetDirectoryName(path);
    path += "\\" + Path.GetFileName(assembly.Location);

    return path;
}

CodeBase将返回程序集的原始位置。在Web应用程序的情况下,当所有程序集在Temporary文件夹中使用卷影副本时,CodeBase仍将返回Bin文件夹中的路径。但是使用协议,比如这个文件:// c:/somesite/bin/someassembly.dll。所以这个方法只是得到它并将其转换为通常的文件路径。