0

組織内の各ユーザーがファイルをバックアップするためのネットワーク共有を持つサーバーがあります。すべての共有は、サーバー上の同じフォルダー内に物理的に存在します。つまり、D:\UserArchives\user1$、d:\UserArchives\user2$ です。すべての共有には、ドル記号が付けられて非表示になります。

C# を使用して、各ユーザーがそれぞれの共有で利用できる空き容量を取得しようとしています。

ここから選択した回答を使用して共有を列挙しています: Enumrating Network Shares with C#

ここから GetDiskFreeSpaceEx を使用して空き領域を取得しようとしています: http://social.msdn.microsoft.com/Forums/ar-SA/csharpgeneral/thread/b7db7ec7-34a5-4ca6-89e7-947190c4e043

アプリを user1 として実行すると、共有に適切な量の空き容量が取得され、user2 の共有にアクセスできないためセキュリティ例外が発生し、その逆も同様です。これは予期されることです。両方の共有にアクセスできる管理者アカウントとしてアプリを実行すると、user1 + user2 の空き容量が返されます。

GetDiskFreeSpaceEx のドキュメントに次のように記載されているため、これも理にかなっています。

 "Retrieves information about the amount of space that is available on a disk volume, which is the total amount of space, the total amount
 of free space, and the total amount of free space available to the
 user that is associated with the calling thread."

私の質問は、ネットワーク全体で C# でこれをどのように達成するかです。サーバーに対してローカルなソリューションは必要ありません。

これまでの私のコード:

        static void Main(string[] args)
        {
            string server = "filesvr1";
            try
            {
            //Impersonator is a class for impersonating a different windows account
                using (new Impersonator("UserName", "Domain", "Password"))
                {
                    GetUserShareInfo(server);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("ERROR: " + ex.Message);
            }
        }
        static void GetUserShareInfo(string server) 
        {
            ShareCollection shi;
            if (server != null && server.Trim().Length > 0)
            {
                Console.WriteLine("\nShares on {0}:", server);
                shi = ShareCollection.GetShares(server);
                if (shi != null) 
                {
                    foreach(Share si in shi) 
                    {
                        // If you don't have permissions to the share you will get security exceptions.
                        if (si.IsFileSystem) 
                        {
                            string userName = si.NetName.Substring(0, si.NetName.Length - 1);
                            try
                            {
                                //Network Share Size
                                Console.WriteLine(FreeSpace("\\\\" + server + "\\" + si.Root.Name));
                            }
                            catch (Exception ex)
                            {
                                Console.WriteLine(userName + " - " + ex.Message);
                            }
                        }
                    }
                }
                else
                    Console.WriteLine("Unable to enumerate the shares on {0}.\n"
                        + "Make sure the machine exists, and that you have permission to access it.", server);
            }
        }

   public static long FreeSpace(string folderName)
        {
            if (string.IsNullOrEmpty(folderName))
            {
                throw new ArgumentNullException("folderName");
            }

            if (!folderName.EndsWith("\\"))
            {
                folderName += '\\';
            }

            long free = 0, dummy1 = 0, dummy2 = 0;

            if (GetDiskFreeSpaceEx(folderName, ref free, ref dummy1, ref dummy2))
            {
                return free;
            }
            else
            {
                return -1;
            }
        }

        [SuppressMessage("Microsoft.Security", "CA2118:ReviewSuppressUnmanagedCodeSecurityUsage"), SuppressUnmanagedCodeSecurity]
        [DllImport("Kernel32", SetLastError = true, CharSet = CharSet.Auto)]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool GetDiskFreeSpaceEx
        (
            string lpszPath,                    // Must name a folder, must end with '\'.
            ref long lpFreeBytesAvailable,
            ref long lpTotalNumberOfBytes,
            ref long lpTotalNumberOfFreeBytes
        );
4

0 に答える 0