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;