在C#中获取主目录的路径?


101

好的,我已经检查了Environment.SpecialFolder,但是这里没有任何内容。

我想在C#中获取当前用户的主目录。(例如,c:\documents and settings\user在XP,c:\users\userVista和/home/userUnix下)。

我知道我可以阅读环境变量来找出答案,但是我想以跨平台的方式做到这一点。

我可以通过.NET(最好使用mscorlib)进行任何操作吗?

更新:好的,这是我最终使用的代码:

string homePath = (Environment.OSVersion.Platform == PlatformID.Unix || 
                   Environment.OSVersion.Platform == PlatformID.MacOSX)
    ? Environment.GetEnvironmentVariable("HOME")
    : Environment.ExpandEnvironmentVariables("%HOMEDRIVE%%HOMEPATH%");

2
繁荣。西部最快的枪支:P
鲍里斯·卡伦斯

关于您的机器的Dunno,但是在我的XP盒子上,%HOMEDRIVE %% HOMEPATH%是网络目录,而不是c:\ Documents and Settings \ user \ MSalters \
MSalters

老实说,我认为这个确切的问题是.NET的未实现...您应该查看CSIDLS的文档(msdn.microsoft.com/zh-cn/library/bb762494.aspx),以查看完整的列表。 Windows支持的内容:您实际上正在寻找的是CSIDL_PROFILE,它在Windows中受支持,但由于某些不可思议的原因而不受.NET支持。
马修·沙利

1
我认为您下次应该将结果放在答案中。
彼得

PlatformID.MacOSX不是必需的,PlatformID.Unix在MacOSX上也返回true(或者至少是以前返回的)。
Stefan Steiger,2015年

Answers:


51

Environment.SpecialFolder.Personal实际上并不返回主文件夹,而是返回“ 我的文档”文件夹。在Win32上获取主文件夹的最安全方法是读取%HOMEDRIVE%%HOMEPATH%。读取环境变量实际上非常容易移植(在Unix和Windows上),因此我不确定发布者为什么不想这样做。

编辑添加:对于跨平台(Windows / Unix)C#,我将$HOME在Unix和OSX以及%HOMEDRIVE%%HOMEPATH%Windows上阅读。


我知道* nix上不存在HOMEDRIVE的事实,并且通常它只是HOME,而不是HOMEPATH。
马修·沙利

马修,您说得对。我在原始评论中添加了说明。
sigint

12
您不能在Windows上使用%USERPROFILE%吗?
卢卡斯·琼斯

1
$ HOME也可以在OS X上使用。就我而言,这仍然不是正确的答案,因为您正在执行平台检测...但是要获得所需的确切值,这就是您必须要做的。
马修·沙利

2
person-b,%USERPROFILE%和%HOMEDRIVE %% HOMEPATH%在个人PC上通常是相同的,但通常指向网络环境中的不同位置。例如,在工作中,我的USERPROFILE是C:\ Documents and Settings \ username,但主目录是Z:\,这是由IT定期备份的网络驱动器。
sigint

92
Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)

个人是我的文档(或Win7及更高版本中的文档)。


8
请注意,UserProfile是.NET 4.0中的新增功能,如果您使用.NET 2.0 / 3.5,则必须手动调用win32 API,并将UserProfile的值设置为40
linquize 2012年

除Windows 95、98和ME外,“我的文档”与主目录不同。
乔恩·汉娜

1
不要忘记使用System.IO.Path.DirectorySeparatorChar来构建文件路径以保持其可移植性。
thomiel 2014年

4
不要手动使用DirectorySeperatorChar。使用Path.Combine。
John Gietzen 2015年

14

我相信您正在寻找的是:

System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal)

作为参考,它实际上包含在中mscorlib


返回“我的文档”文件夹。
MiffTheFox

Windows与主目录最接近的 “我的文档” 。
MSalters

8
@MStallers否,%HOMEDRIVE %% HOMEPATH%是。
MiffTheFox

不太...但是替代方法是PInvoke,OP要求提供托管解决方案。
马修·沙利

7
请注意,您所需的是.NET 4.0中提供的Environment.SpecialFolder.UserProfile
linquize 2012年

8

在DotNetCore 1.1 System.Environment.SpecialFolder中不存在。它可能存在于2.0-beta中。在此之前,您可以使用以下方法:

var envHome = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "HOMEPATH" : "HOME";
var home = Environment.GetEnvironmentVariable(envHome);`

我正在使用2.0并System.Environment.SpecialFolder存在
-snotyak

4

底线答案是“否”。.NET中没有简单的基于系统的方法来获取主目录,因此我们可以期望在Windows上的.NET和Mono中都实现。

您将需要进行一些操作系统检测并跳转到特定于操作系统的代码。


1

当您说跨平台方式时,还需要支持哪些其他操作系统?如果您在非Windows操作系统上运行,则可能需要进行一些简单的OS检测以选择查找主目录的方法。

该网站似乎提供了一种在Windows中执行所需操作的方法。


除非您使用Framework Environment的某些笨拙的实现,否则GetFolder()应该跨平台工作。
R. Martinho Fernandes

2
应该。MS的实现无法做到这一点。
R. Martinho Fernandes

1

可以使用GetEnvironmentVariablein 来完成System.IO

public string GetUserHome() {
    var homeDrive = Environment.GetEnvironmentVariable("HOMEDRIVE");
    if (!string.IsNullOrWhiteSpace(homeDrive))
    {
        var homePath = Environment.GetEnvironmentVariable("HOMEPATH");
        if (!string.IsNullOrWhiteSpace(homePath))
        {            
            var fullHomePath = homeDrive + Path.DirectorySeparatorChar + homePath;
            return Path.Combine(fullHomePath, "myFolder");
        }
        else
        {
            throw new Exception("Environment variable error, there is no 'HOMEPATH'");
        }
    }
    else
    {
        throw new Exception("Environment variable error, there is no 'HOMEDRIVE'");
    }
}

然后在Windows下生成: C:\\\\Users\\myusername\\myFolder

请注意,如果您使用

var fullHomePath = Path.Combine(homeDrive.ToString(), homePath.ToString())

它失败,因为它产生: \\Users\\myusername\\myFolder


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.