获取应用程序根目录物理路径(Web and Windows)

  这两个计划写一个小类库,需要在不同项目下任意调用。该类库需要对磁盘文件进行读写,所以就需要获取程序执行的磁盘路径,就简单的对获取磁盘路径的方法进行研究。

  借助搜索引擎,我从网上搜罗来多种方法,都可以直接或间接的获取到应用程序执行的根目录。大概总结一下,一共有以下 11 种:

    Server.MapPath("~")  //使用 HTTP 上下文中的 Server 对象来获取Web站点的根目录
    
    System.AppDomain.CurrentDomain.BaseDirectory  //使用应用程序域对象获取当前线程的应用程序域的基准目录

    System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase  //使用应用程序域对象获取当前线程的应用程序域的配置信息中的应用程序目录
    
    System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName  //获取当前进程的主模块的文件名(全路径。由该文件路径可以得到程序集所在的目录)
 
    System.Environment.CurrentDirectory  //获取应用程序环境的当前目录

    System.IO.Directory.GetCurrentDirectory()  //使用静态类 Directory 下的 GetCurrentDirectory 方法获取当前程序的路径

    System.Reflection.Assembly.GetCallingAssembly().Location  //获取调用该方法的方法所在的程序集,并获取该程序集文件路径(由该文件路径可以得到程序集所在的目录)

    System.Reflection.Assembly.GetEntryAssembly().Location  //获取包含该应用程序入口点的程序集(可执行文件),并获取该程序集文件的路径(由该文件路径可以得到程序集所在的目录)

    System.Reflection.Assembly.GetExecutingAssembly().Location  //获取执行该方法的程序集,并获取该程序集的文件路径(由该文件路径可以得到程序集所在的目录)

    System.Windows.Forms.Application.StartupPath  //获取启动应用程序的可执行文件所在的目录

    System.Windows.Forms.Application.ExecutablePath  //获取启动应用程序的可执行文件的路径(由该文件路径可以得到应用程序所在的目录)

  当然,这些方法并不全都可用。

  要在类库里使用,当然要在类库里试试。

  新建一个解决方案,添加一个类库项目,然后再添加一个控制台项目和 Web 项目。项目结构如图:

  首先,在类库项目里添加一个类 ProjectPath。代码如下:

namespace Common
{
    public class ProjectPath
    {
        public static Dictionary<string, string> GetCurrentPaths()
        {
            Dictionary<string, string> paths = new Dictionary<string, string>();

            paths.Add("System.AppDomain.CurrentDomain.BaseDirectory",
                System.AppDomain.CurrentDomain.BaseDirectory);
            paths.Add("System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase", 
                System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase);
            paths.Add("System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName", 
                System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName);
            paths.Add("System.Environment.CurrentDirectory",
                System.Environment.CurrentDirectory);
            paths.Add("System.IO.Directory.GetCurrentDirectory()",
                System.IO.Directory.GetCurrentDirectory());
            paths.Add("System.Reflection.Assembly.GetCallingAssembly().Location",
                System.Reflection.Assembly.GetCallingAssembly().Location);
            try
            {/* System.Reflection.Assembly.GetEntryAssembly() 方法被 Web 应用程序调用时返回值是 null,
                访问其 Location 属性将产生异常 */
                paths.Add("System.Reflection.Assembly.GetEntryAssembly().Location",
                   System.Reflection.Assembly.GetEntryAssembly().Location);
            }
            catch { }
            paths.Add("System.Reflection.Assembly.GetExecutingAssembly().Location",
                System.Reflection.Assembly.GetExecutingAssembly().Location);
            paths.Add("System.Windows.Forms.Application.StartupPath", 
                System.Windows.Forms.Application.StartupPath);
            paths.Add("System.Windows.Forms.Application.ExecutablePath",
                System.Windows.Forms.Application.ExecutablePath);
            //Web 项目特有方式,必需在 HTTP 上下文中才能访问 Server 对象
            //paths.Add("Server.MapPath(\"~\")", Server.MapPath("~"));

            return paths;
        }
    }
}

  在段代码里,ProjectPath 类提供一个 GetCurrentPaths 方法来返回使用各种方式获取程序目录结果的字典。
  OK,先在控制台项目里测试,代码如下:

    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<string, string> paths = ProjectPath.GetCurrentPaths();

            foreach (string key in paths.Keys)
            {
                Console.WriteLine(key);
                Console.WriteLine(paths[key]);
                Console.WriteLine();
            }

            Console.Read();
        }
    }

  执行以后,将在控制台打印执行结果,如图:

  从执行结果来讲,控制台项目(包括 WindowsForm 应用程序)使用任何方式都能直接或间接获取程序集所在的目录。不过从结果也能看出,各种方法执行的功能是不一样的。

  接下来,在 Web 项目中测试,代码如下:

    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            this.form1.InnerHtml += "Server.MapPath(\"~\")<br />";
            this.form1.InnerHtml += Server.MapPath("~");
            this.form1.InnerHtml += "<br />";
            this.form1.InnerHtml += "<br />";

            Dictionary<string, string> paths = ProjectPath.GetCurrentPaths();
            foreach (string key in paths.Keys)
            {
                this.form1.InnerHtml += key;
                this.form1.InnerHtml += "<br />";
                this.form1.InnerHtml += paths[key];
                this.form1.InnerHtml += "<br />";
                this.form1.InnerHtml += "<br />";
            }

        }
    }

  运行 Web 项目,执行结果如图:

  同样的代码,Web 项目的执行结果大不一样。可以说乱七八糟。

  首先,Server.MapPath() 方法不容质疑,是 Web 程序提供的特有方法。其它的返回的要不是生成的 DLL 文件所在的临时目录,要不就是 VS 集成的Web服务器所在的目录。只有 System.AppDomain.CurrentDomain.BaseDirectory 属性和 System.AppDomain.CurrentDomain.SetupInformation.ApplicationBase 属性能够顺利得到Web应用程序运行的目录。    

  

 

 

posted @ 2012-06-30 18:53  小浩叔叔  阅读(10047)  评论(2编辑  收藏  举报