2017-11-09 13 views
2

ローカルコンピュータのすべてのユーザー(各ユーザー)のマイドキュメントフォルダのパスを取得する方法を探しています。 私はいくつかの記事を見つけましたが、現在のユーザーに対してこれを行う方法を示しています。マシンの全ユーザーからマイドキュメントフォルダのパスを取得する方法

SHGetKnownFolderPathを使用して、以下のコードをテストしましたが、ログに記録されたユーザーのみが動作します。 WindowsIdentityオブジェクトを受け取るクラスctorでは、他のユーザーのトークンで作成しますが、返されるパスはログインしているユーザーのものです。

フォルダのパスを取得する方法を知っている人はいますか?

ありがとうございました。

using Syroot.Windows.IO; 
using System; 
using System.Collections.Generic; 
using System.Runtime.InteropServices; 

namespace ConsoleApplication2 
{ 
class Program 
{ 
    private static Dictionary<KnownFolderType, KnownFolder> _knownFolderInstances; 
    static void Main(string[] args) 
    { 
     KnownFolderType type = KnownFolderType.Documents; 
     KnownFolder knownFolder = new KnownFolder(type); 

    //Ctor with WindowsIdentity parameter 
    //public KnownFolder(KnownFolderType type, WindowsIdentity identity) 
    //{ 
    // Type = type; 
    // Identity = identity; 
    //} 

    // Write down the current and default path. 
    Console.WriteLine(knownFolder.Type.ToString()); 
     try 
     { 
      Console.Write("Current Path: "); 
      Console.WriteLine(knownFolder.Path); 
      Console.Write("Default Path: "); 
      Console.WriteLine(knownFolder.DefaultPath); 
     } 
     catch (ExternalException ex) 
     { 
      // While uncommon with personal folders, other KnownFolders don't exist on every system, and trying 
      // to query those returns an error which we catch here. 
      Console.WriteLine("<Exception> " + ex.ErrorCode); 
     } 

     Console.ReadLine(); 
    } 

    private static KnownFolder GetInstance(KnownFolderType type) 
    { 
     // Check if the caching directory exists yet. 
     if (_knownFolderInstances == null) 
     { 
      _knownFolderInstances = new Dictionary<KnownFolderType, KnownFolder>(); 
     } 

     // Get a KnownFolder instance out of the cache dictionary or create it when not cached yet. 
     KnownFolder knownFolder; 
     if (!_knownFolderInstances.TryGetValue(type, out knownFolder)) 
     { 
      knownFolder = new KnownFolder(type); 
      _knownFolderInstances.Add(type, knownFolder); 
     } 
     return knownFolder; 
    } 

    /// <summary> 
    /// The per-user Documents folder. 
    /// Defaults to &quot;%USERPROFILE%\Documents&quot;. 
    /// </summary> 
    public static KnownFolder Documents 
    { 
     get { return GetInstance(KnownFolderType.Documents); } 
    } 
} 
} 

KnownFolder.cs

using System; 
using System.Runtime.InteropServices; 
using System.Security.Principal; 

namespace Syroot.Windows.IO 
{ 
/// <summary> 
/// Represents a special Windows directory and provides methods to retrieve information about it. 
/// </summary> 
public sealed class KnownFolder 
{ 
    // ---- CONSTRUCTORS & DESTRUCTOR ------------------------------------------------------------------------------ 

    /// <summary> 
    /// Initializes a new instance of the <see cref="KnownFolder"/> class for the folder of the given type. It 
    /// provides the values for the current user. 
    /// </summary> 
    /// <param name="type">The <see cref="KnownFolderType"/> of the known folder to represent.</param> 
    public KnownFolder(KnownFolderType type) 
     : this(type, WindowsIdentity.GetCurrent()) 
    { 
    } 

    /// <summary> 
    /// Initializes a new instance of the <see cref="KnownFolder"/> class for the folder of the given type. It 
    /// provides the values for the given impersonated user. 
    /// </summary> 
    /// <param name="type">The <see cref="KnownFolderType"/> of the known folder to represent.</param> 
    /// <param name="identity">The <see cref="WindowsIdentity"/> of the impersonated user which values will be 
    /// provided.</param> 
    public KnownFolder(KnownFolderType type, WindowsIdentity identity) 
    { 
     Type = type; 
     Identity = identity; 
    } 

    // ---- PROPERTIES --------------------------------------------------------------------------------------------- 

    /// <summary> 
    /// Gets the type of the known folder which is represented. 
    /// </summary> 
    public KnownFolderType Type 
    { 
     get; 
     private set; 
    } 

    /// <summary> 
    /// Gets the <see cref="WindowsIdentity"/> of the user whose folder values are provided. 
    /// </summary> 
    public WindowsIdentity Identity 
    { 
     get; 
     private set; 
    } 

    /// <summary> 
    /// Gets or sets the default path of the folder. 
    /// This does not require the folder to be existent. 
    /// </summary> 
    /// <exception cref="ExternalException">The known folder could not be retrieved.</exception> 
    public string DefaultPath 
    { 
     get 
     { 
      return GetPath(KnownFolderFlags.DontVerify | KnownFolderFlags.DefaultPath); 
     } 
     set 
     { 

     } 
    } 

    /// <summary> 
    /// Gets or sets the path as currently configured. 
    /// This does not require the folder to be existent. 
    /// </summary> 
    /// <exception cref="ExternalException">The known folder could not be retrieved.</exception> 
    public string Path 
    { 
     get 
     { 
      return GetPath(KnownFolderFlags.DontVerify); 
     } 
     set 
     { 
      SetPath(KnownFolderFlags.None, value); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the path as currently configured, with all environment variables expanded. 
    /// This does not require the folder to be existent. 
    /// </summary> 
    /// <exception cref="ExternalException">The known folder could not be retrieved.</exception> 
    public string ExpandedPath 
    { 
     get 
     { 
      return GetPath(KnownFolderFlags.DontVerify | KnownFolderFlags.NoAlias); 
     } 
     set 
     { 
      SetPath(KnownFolderFlags.DontUnexpand, value); 
     } 
    } 

    // ---- METHODS (PUBLIC) --------------------------------------------------------------------------------------- 

    /// <summary> 
    /// Creates the folder using its Desktop.ini settings. 
    /// </summary> 
    /// <exception cref="ExternalException">The known folder could not be retrieved.</exception> 
    public void Create() 
    { 
     GetPath(KnownFolderFlags.Init | KnownFolderFlags.Create); 
    } 

    // ---- METHODS (PRIVATE) -------------------------------------------------------------------------------------- 

    private string GetPath(KnownFolderFlags flags) 
    { 
     IntPtr outPath; 
     int result = SHGetKnownFolderPath(Type.GetGuid(), (uint)flags, Identity.Token, out outPath); 
     if (result >= 0) 
     { 
      return Marshal.PtrToStringUni(outPath); 
     } 
     else 
     { 
      throw new ExternalException("Cannot get the known folder path. It may not be available on this system.", 
       result); 
     } 
    } 

    private void SetPath(KnownFolderFlags flags, string path) 
    { 
     int result = SHSetKnownFolderPath(Type.GetGuid(), (uint)flags, Identity.Token, path); 
     if (result < 0) 
     { 
      throw new ExternalException("Cannot set the known folder path. It may not be available on this system.", 
       result); 
     } 
    } 

    /// <summary> 
    /// Retrieves the full path of a known folder identified by the folder's known folder ID. 
    /// </summary> 
    /// <param name="rfid">A known folder ID that identifies the folder.</param> 
    /// <param name="dwFlags">Flags that specify special retrieval options. This value can be 0; otherwise, one or 
    /// more of the <see cref="KnownFolderFlags"/> values.</param> 
    /// <param name="hToken">An access token that represents a particular user. If this parameter is NULL, which is 
    /// the most common usage, the function requests the known folder for the current user. Assigning a value of -1 
    /// indicates the Default User. The default user profile is duplicated when any new user account is created. 
    /// Note that access to the Default User folders requires administrator privileges.</param> 
    /// <param name="ppszPath">When this method returns, contains the address of a string that specifies the path of 
    /// the known folder. The returned path does not include a trailing backslash.</param> 
    /// <returns>Returns S_OK if successful, or an error value otherwise.</returns> 
    /// <msdn-id>bb762188</msdn-id> 
    [DllImport("Shell32.dll")] 
    private static extern int SHGetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, 
     IntPtr hToken, out IntPtr ppszPath); 

    /// <summary> 
    /// Redirects a known folder to a new location. 
    /// </summary> 
    /// <param name="rfid">A <see cref="Guid"/> that identifies the known folder.</param> 
    /// <param name="dwFlags">Either 0 or <see cref="KnownFolderFlags.DontUnexpand"/>.</param> 
    /// <param name="hToken"></param> 
    /// <param name="pszPath"></param> 
    /// <returns></returns> 
    /// <msdn-id>bb762249</msdn-id> 
    [DllImport("Shell32.dll")] 
    private static extern int SHSetKnownFolderPath([MarshalAs(UnmanagedType.LPStruct)]Guid rfid, uint dwFlags, 
     IntPtr hToken, [MarshalAs(UnmanagedType.LPWStr)]string pszPath); 

    // ---- ENUMERATIONS ------------------------------------------------------------------------------------------- 

    /// <summary> 
    /// Represents the retrieval options for known folders. 
    /// </summary> 
    /// <msdn-id>dd378447</msdn-id> 
    [Flags] 
    private enum KnownFolderFlags : uint 
    { 
     None      = 0x00000000, 
     SimpleIDList    = 0x00000100, 
     NotParentRelative   = 0x00000200, 
     DefaultPath    = 0x00000400, 
     Init      = 0x00000800, 
     NoAlias     = 0x00001000, 
     DontUnexpand    = 0x00002000, 
     DontVerify    = 0x00004000, 
     Create     = 0x00008000, 
     NoAppcontainerRedirection = 0x00010000, 
     AliasOnly     = 0x80000000 
    } 
} 
} 
+0

あなたは 'SHGetKnownFolderPath'機能を使用できます。しかし、あなたのアプリには、マシンユーザーのセキュリティトークンを取得するのに十分な特権が必要です。 – dymanoid

+0

マイドキュメントがリダイレクトされているかどうか、ローカルドライブのADホームドライブを探していますか?どのバージョンのWindowsですか? – NetMage

+0

@dymanoidマシンユーザーのトークンを取得する方法は? – Alvimar

答えて

1

私はそれを考え出しました。 システムからすべてのSIDを取得した後、 "HKEY_USERS" + "SID" + "\ Software \ Microsoft \ Windows \ CurrentVersion \ Explorer \ Shell Folders"の形式で "Personal"キーで各SIDのWindowsレジストリを検索しました。 \ Personal "を選択します。 「個人」キーは、各ユーザーの「マイドキュメント」フォルダの現在のパスを保持します。

は、SIDを取得:

public static List<string> GetMachineSids() 
    { 
     ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_UserProfile"); 
     var regs = searcher.Get(); 
     string sid; 

     List<string> sids = new List<string>(); 

     foreach (ManagementObject os in regs) 
     { 
      if (os["SID"] != null) 
      { 
       sid = os["SID"].ToString(); 
       sids.Add(sid); 
      } 
     } 

     searcher.Dispose(); 
     return sids.Count > 0 ? sids : null; 
    } 

マイドキュメントのパスを取得:

public static List<string> GetMyDocumentsPathAllUsers() 
    { 
     const string parcialSubkey = @"\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders"; 
     string subkey = string.Empty; 
     const string keyName = "Personal"; 

     //get sids 
     List<string> sids = GetMachineSids(); 
     List<string> myDocumentsPaths = new List<string>(); 

     if (sids != null) 
     { 
      foreach (var sid in sids) 
      { 
       //get paths     
       subkey = sid + parcialSubkey; 

       using (RegistryKey key = Registry.Users.OpenSubKey(subkey)) 
       { 
        if (key != null) 
        { 
         Object o = key.GetValue(keyName); 
         if (o != null) 
         { 
          myDocumentsPaths.Add(o.ToString()); 
         } 
        } 
       } 
      } 
     } 

     return myDocumentsPaths.Count > 0 ? myDocumentsPaths : null; 
    } 
関連する問題