为什么environment.specialfolder.mydocuments返回错误的值? [英] Why does environment.specialfolder.mydocuments return wrong value?

查看:382
本文介绍了为什么environment.specialfolder.mydocuments返回错误的值?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个WPF / .NET4.5.2应用程序,它是在Windows 10计算机上开发的,但部署在Windows 7计算机上。



在我的开发机器上。 ..



I have a WPF/.NET4.5.2 application that is developed on a Windows 10 machine but deployed on a Windows 7 machine.

On my development machine...

Environment.GetFolderPath( Environment.SpecialFolder.MyDocuments )



。 ..正确地返回 C:/ Users /< username> / Documents



当我在目标上运行相同的代码时在Windows 7机器上,我得到了相同的文件夹,但在Windows 7机器上,该文件夹名为 C:/ Users /< username> / My Documents ,因此我的代码无法找到文件夹。



我的尝试:



我是在网上发现了几篇关于此的文章。在许多文章中,作者解释了为什么这是错误的方法(例如,显然访问注册表并不总是因为我可能理解的原因,如果我的头发更少)。



我发现的唯一一篇似乎有令人信服的方法的文章是获取所有特殊文件夹在.NET中[ ^ ],但这对于这样一个常见的要求来说似乎非常复杂。



I不禁感到我在这里缺少一些简单的知识。有谁知道这里可能出了什么问题?


...correctly returns "C:/Users/<username>/Documents".

When I run this same code on the target Windows 7 machine, I get the same folder returned but, on the Windows 7 machine, the folder is named "C:/Users/<username>/My Documents", so my code fails to find the folder.

What I have tried:

I've found several articles about this on the net. In many of the articles, the author explains why this is the wrong way to do it (e.g. apparently accessing the Registry is not always going to work for reasons that I might understand if I had even less hair).

The only article I found that seems to have a convincing way to do it is Getting All "Special Folders" in .NET[^] , but this seems very complicated for such a common requirement.

I can't help feeling there is some simple piece of knowledge I am missing here. Does anyone know what may be going wrong here?

推荐答案

请参考:我的文档与文档文件夹 [ ^ ]。在那里你会找到关于文件我的文件文件夹之间差异的简短说明。



正如MSDN文档所述:

Please, refer thiss: My Documents vs Documents folder[^]. There you'll find short explanation about differences between documents and my documents folders.

As MSDN documentation states:
Quote:

GetFolderPath 方法返回与此枚举关联的位置。 这些文件夹的位置在不同的操作系统上可以有不同的值,用户可以更改某些位置,并且位置已本地化。



有关特殊文件夹的更多信息,请参阅Windows文档中的 KNOWNFOLDERID 常量。

The GetFolderPath method returns the locations associated with this enumeration. The locations of these folders can have different values on different operating systems, the user can change some of the locations, and the locations are localized.

For more information about special folders, see the KNOWNFOLDERID constants in the Windows documentation.





结论:要获得正确的文件夹(文件而不是我的文件),你必须使用 SHGetKnownFolderPath API函数。您可以在此处找到的实现:VBnet VisualBasic开发人员资源中心 [ ^ ]



最后我强烈建议您阅读此提示:我应该在哪里存储我的数据? [ ^ ]



Conclusion: to get correct folder (documents instead of my documents) you have to use SHGetKnownFolderPath API function. An implementation you'll find here: VBnet� Visual Basic Developers Resource Centre[^]

Finally i'd strongly suggest to read this tip: Where should I store my data?[^]


除了Maciej Los post之外,如果用户使用的是虚拟机,则文档路径不仅在不同的Windows操作系统上有所不同( VM)在外部操作系统上,Documents文件夹路径可以是基本操作系统路径,而不是Windows操作系统文档文件夹路径。如果您尝试访问VM外部的路径,则会引发异常。



以下是解决这个问题的解决方案。



机器详情POCO:

Further to Maciej Los post, the Document Path not only varies on different Windows OSes, if the user is using a Virtual Machine (VM) on a foreign OS, the Documents folder path can be the base OS path and not the Windows OS Documents Folder path. If you try to access the path outside the VM, then an exception will be thrown.

Below is a solution that will fix this problem.

Machine Details POCO:
public class VirtualMachineDetails
{
    public string Manufacturer { get; set; }
    public string Model { get; set; }
    public bool IsVirtual
    {
        get
        {
            return IsParallels || IsVirtualBox || IsVmWare || IsVirtualPc;
        }
    }
    public bool IsParallels { get; internal set; }
    public bool IsVmWare { get; set; }
    public bool IsVirtualBox { get; set; }
    public bool IsVirtualPc { get; set; }
    public string DocumentsPath { get; set; }
}



填写信息的扩展方法:


Extension methods to fill out the information:

using System;
using System.IO;
using System.Management;

public static class VirtualMachineDetailsExtensions
{
    public static void Init(this VirtualMachineDetails host)
    {
        using (var searcher =
            new ManagementObjectSearcher("Select * from Win32_ComputerSystem"))
        {
            using (var items = searcher.Get())
            {
                foreach (var item in items)
                {
                    host.Manufacturer = item["Manufacturer"].ToString();
                    host.Model = item["Model"].ToString();

                    string manufacturer = host.Manufacturer.ToLower();
                    string model = host.Model.ToLower();

                    host.IsVirtualPc = 
                        manufacturer == "microsoft corporation" &&
                                        model.Contains("virtual");
                    host.IsParallels = manufacturer.Contains("parallels");
                    host.IsVmWare = manufacturer.Contains("vmware");
                    host.IsVirtualBox = model == "virtualbox";
                }
            }
        }
        host.DocumentsPath = host.FixDocPath();
    }

    private static string FixDocPath(this VirtualMachineDetails host)
    {
        string pathSeperator = @"\";

        string path = Environment.GetFolderPath(
                       Environment.SpecialFolder.MyDocuments);

        string userPath = Environment.GetFolderPath(
                           Environment.SpecialFolder.UserProfile);

        var fixPath = new Func<string, string, string>((p, u) => (p.Contains(u)) ? 
                p : 
                Path.Combine(u, p.Substring(p.LastIndexOf(pathSeperator))));

        if (host.IsVirtual)
        {
            string parallelsPath = @"\\Mac\Home";
            string vmWarePath = @"\\vmware-host\Shared Folders";

            if (host.IsParallels)
            {
                if (path.Contains(parallelsPath))
                    path = path.Replace(parallelsPath, userPath);
                else
                    fixPath(path, userPath);
            }

            else if (host.IsVmWare)
            {
                if (path.Contains(vmWarePath))
                    path = path.Replace(vmWarePath, userPath);
                else
                    fixPath(path, userPath);
            }

            else
                fixPath(path, userPath);
        }

        return path;
    }
}



使用:


To use:

var vm = new VirtualMachineDetails();

vm.Init();

var documentsPath = vm.DocumentsPath;


这篇关于为什么environment.specialfolder.mydocuments返回错误的值?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆