none
请问c# 怎么设置系统文件夹及子文件夹的共享?

    问题

  • 需求是winform程序中创建一个文件夹,并设置为共享(所有子文件夹和子文件都要共享),设置everyone有fullcontrol的权限,其他人连接进来可以操作。(操作系统不能确定,可能是win7也可能是server2003/2008等)

    试了几种方式,都有问题。我把几种情况列举下,语言组织不好,不好意思。

    问题一:共享只能共享根文件夹,打开共享内的文件提示 拒绝访问。我试着递归循环里面所有的文件夹并设置共享,但是文件夹内的文件依然拒绝访问。而且后期程序会生成大量文件夹和文件在里面,生成一个文件夹就设置一次共享肯定不行。

    问题二:根文件夹都共享不成功,拒绝访问。看了下文件夹属性-安全-组或用户名 里面用户没有everyone。然后我在程序里面先添加该文件夹everyone的操作权限fullcontrol,但是出来的效果却是特殊权限。依然不能解决问题。

    下面是几种共享的代码:(我对这些不懂,都是查的,希望大神们指点一下)

    第一种:

     // Create a ManagementClass object
                    ManagementClass managementClass = new ManagementClass("Win32_Share");
                    // Create ManagementBaseObjects for in and out parameters
                    ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
                    ManagementBaseObject outParams;
                    // Set the input parameters
                    inParams["Description"] = Description;
                    inParams["Name"] = ShareName;
                    inParams["Path"] = FolderPath;
                    inParams["Type"] = 0x0; // Disk Drive
                    //inParams["Access"] = null; //null = 使Everyone拥有完全控制权限
    
                    //Another Type:
                    //        DISK_DRIVE = 0x0
                    //        PRINT_QUEUE = 0x1
                    //        DEVICE = 0x2
                    //        IPC = 0x3
                    //        DISK_DRIVE_ADMIN = 0x80000000
                    //        PRINT_QUEUE_ADMIN = 0x80000001
                    //        DEVICE_ADMIN = 0x80000002
                    //        IPC_ADMIN = 0x8000003
                    //inParams["MaximumAllowed"] = int maxConnectionsNum;
                    // Invoke the method on the ManagementClass object
                    outParams = managementClass.InvokeMethod("Create", inParams, null);
                    // Check to see if the method invocation was successful
                    if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
                    {
                        throw new Exception("共享失败");
                    }
    第二种:
      CommandSilentExecution cmd = new CommandSilentExecution();
                    //cmd.RunCmd(" cacls " + FolderPath + " /g everyone:f net share " + ShareName + "=" + FolderPath + " /grant:everyone,full");
                    //cmd.RunCmd("net share " + ShareName + "=" + FolderPath + "");
                    cmd.RunCmd("net share " + ShareName + "=" + FolderPath + " /grant:everyone,full");
    
    
            public void RunCmd(string cmd)
            {
                proc.StartInfo.CreateNoWindow = true;
                proc.StartInfo.FileName = "cmd.exe";
                proc.StartInfo.UseShellExecute = false;
                proc.StartInfo.RedirectStandardError = true;
                proc.StartInfo.RedirectStandardInput = true;
                proc.StartInfo.RedirectStandardOutput = true;
                proc.Start();
                proc.StandardInput.WriteLine(cmd);
                proc.Close();
            }
    
    

    第三种:

     public enum MethodStatus : uint
        {
            Success = 0, 	//Success
            AccessDenied = 2, 	//Access denied
            UnknownFailure = 8, 	//Unknown failure
            InvalidName = 9, 	//Invalid name
            InvalidLevel = 10, 	//Invalid level
            InvalidParameter = 21, 	//Invalid parameter
            DuplicateShare = 22, 	//Duplicate share
            RedirectedPath = 23, 	//Redirected path
            UnknownDevice = 24, 	//Unknown device or directory
            NetNameNotFound = 25 	//Net name not found
        }
    
        public enum ShareType : uint
        {
            DiskDrive = 0x0, 	//Disk Drive
            PrintQueue = 0x1, 	//Print Queue
            Device = 0x2, 	//Device
            IPC = 0x3, 	//IPC
            DiskDriveAdmin = 0x80000000, 	//Disk Drive Admin
            PrintQueueAdmin = 0x80000001, 	//Print Queue Admin
            DeviceAdmin = 0x80000002, 	//Device Admin
            IpcAdmin = 0x80000003 	//IPC Admin
        }
        public enum AccessPrivileges : uint
        {
            /// <summary>
            /// 列出文件夹/读取数据
            /// </summary>
            FILE_READ_DATA = 0x00000001,
            /// <summary>
            /// 创建文件/写入数据
            /// </summary>
            FILE_WRITE_DATA = 0x00000002,
            /// <summary>
            /// 创建文件夹/附加数据
            /// </summary>
            FILE_APPEND_DATA = 0x00000004,
            /// <summary>
            /// 读取扩展属性
            /// </summary>
            FILE_READ_EA = 0x00000008,
            /// <summary>
            /// 写入扩展属性
            /// </summary>
            FILE_WRITE_EA = 0x00000010,
            /// <summary>
            /// 遍历文件夹/执行文件
            /// </summary>
            FILE_EXECUTE = 0x00000020,
            /// <summary>
            /// 删除子文件夹及文件
            /// </summary>
            FILE_DELETE_CHILD = 0x00000040,
            /// <summary>
            /// 读取属性
            /// </summary>
            FILE_READ_ATTRIBUTES = 0x00000080,
            /// <summary>
            /// 写入属性
            /// </summary>
            FILE_WRITE_ATTRIBUTES = 0x00000100,
            /// <summary>
            /// 删除
            /// </summary>
            DELETE = 0x00010000,
            /// <summary>
            /// 读取权限
            /// </summary>
            READ_CONTROL = 0x00020000,
            /// <summary>
            /// 更改权限
            /// </summary>
            WRITE_DAC = 0x00040000,
            /// <summary>
            /// 取得所有权
            /// </summary>
            WRITE_OWNER = 0x00080000,
            /// <summary>
            /// 无任何权限
            /// </summary>
            SYNCHRONIZE = 0x00100000,
            /// <summary>
            /// 所有权限
            /// </summary>
            Full = AccessPrivileges.DELETE | AccessPrivileges.FILE_APPEND_DATA | AccessPrivileges.FILE_DELETE_CHILD | AccessPrivileges.FILE_EXECUTE
            | AccessPrivileges.FILE_READ_ATTRIBUTES | AccessPrivileges.FILE_READ_DATA | AccessPrivileges.FILE_READ_EA | AccessPrivileges.FILE_WRITE_ATTRIBUTES
            | AccessPrivileges.FILE_WRITE_DATA | AccessPrivileges.FILE_WRITE_EA | AccessPrivileges.READ_CONTROL | AccessPrivileges.SYNCHRONIZE
            | AccessPrivileges.WRITE_DAC | AccessPrivileges.WRITE_OWNER
        }
    
        enum AceFlags : uint
        {
            NonInheritAce = 0,
            ObjectInheritAce = 1,
            ContainerInheritAce = 2,
            NoPropagateInheritAce = 4,
            InheritOnlyAce = 8,
            InheritedAce = 16
        }
    
        [Flags]
        enum AceType : uint
        {
            AccessAllowed = 0,
            AccessDenied = 1,
            Audit = 2
        }
    
        public class UserPrivileges
        {
            public string UserAccount { get; set; }
            public List<String> Privileges { get; set; }
            public string Domain { get; set; }
            public object ObjPrivileges
            {
                get;
                set;
            }
        }
    
    
        public class ShareHelper
        {
            static string[] filedesc = {"FILE_READ_DATA", "FILE_WRITE_DATA", "FILE_APPEND_DATA", "FILE_READ_EA",
    
    "FILE_WRITE_EA", "FILE_EXECUTE", "FILE_DELETE_CHILD", "FILE_READ_ATTRIBUTES",
    
    "FILE_WRITE_ATTRIBUTES", " ", " ", " ",
    
    " ", " ", " ", " ",
    
    "DELETE ", "READ_CONTROL", "WRITE_DAC", "WRITE_OWNER",
    
    "SYNCHRONIZE ", " ", " "," ",
    
    "ACCESS_SYSTEM_SECURITY", "MAXIMUM_ALLOWED", " "," ",
    
    "GENERIC_ALL", "GENERIC_EXECUTE", "GENERIC_WRITE","GENERIC_READ"};
    
            private ManagementObject mWinShareObject;
    
            private ShareHelper(ManagementObject obj) { mWinShareObject = obj; }
    
            #region Wrap Win32_Share properties
            public uint AccessMask
            {
                get { return Convert.ToUInt32(mWinShareObject["AccessMask"]); }
            }
    
            public bool AllowMaximum
            {
                get { return Convert.ToBoolean(mWinShareObject["AllowMaximum"]); }
            }
    
            public string Caption
            {
                get { return Convert.ToString(mWinShareObject["Caption"]); }
            }
    
            public string Description
            {
                get { return Convert.ToString(mWinShareObject["Description"]); }
            }
    
            public DateTime InstallDate
            {
                get { return Convert.ToDateTime(mWinShareObject["InstallDate"]); }
            }
    
            public uint MaximumAllowed
            {
                get { return Convert.ToUInt32(mWinShareObject["MaximumAllowed"]); }
            }
    
            public string Name
            {
                get { return Convert.ToString(mWinShareObject["Name"]); }
            }
    
            public string Path
            {
                get { return Convert.ToString(mWinShareObject["Path"]); }
            }
    
            public string Status
            {
                get { return Convert.ToString(mWinShareObject["Status"]); }
            }
    
            public ShareType Type
            {
                get { return (ShareType)Convert.ToUInt32(mWinShareObject["Type"]); }
            }
            #endregion
    
            #region Wrap Methods
            /// <summary>
            /// 删除共享
            /// </summary>
            /// <returns></returns>
            public MethodStatus Delete()
            {
                object result = mWinShareObject.InvokeMethod("Delete", new object[] { });
                uint r = Convert.ToUInt32(result);
    
                return (MethodStatus)r;
            }
    
            /// <summary>
            /// 创建共享
            /// </summary>
            /// <param name="path"></param>
            /// <param name="name"></param>
            /// <param name="type"></param>
            /// <param name="maximumAllowed"></param>
            /// <param name="description"></param>
            /// <param name="password"></param>
            /// <returns></returns>
            public static MethodStatus Create(string path, string name, ShareType type, uint maximumAllowed, string description, string password)
            {
                ManagementClass mc = new ManagementClass("Win32_Share");
                object[] parameters = new object[] { path, name, (uint)type, maximumAllowed, description, password, null };
    
                object result = mc.InvokeMethod("Create", parameters);
                uint r = Convert.ToUInt32(result);
    
                return (MethodStatus)r;
            }
    
            #endregion
    
            public static IList<ShareHelper> GetAllShares()
            {
                IList<ShareHelper> result = new List<ShareHelper>();
                ManagementClass mc = new ManagementClass("Win32_Share");
                ManagementObjectCollection moc = mc.GetInstances();
    
                foreach (ManagementObject mo in moc)
                {
                    ShareHelper share = new ShareHelper(mo);
                    result.Add(share);
                }
    
                return result;
            }
    
            public static ShareHelper GetNamedShare(string name)
            {
                // Not a very efficient implementation obviously, but heck... This is sample code. ;)
                IList<ShareHelper> shares = GetAllShares();
    
                foreach (ShareHelper s in shares)
                    if (s.Name == name)
                        return s;
    
                return null;
            }
    
            public static MethodStatus SetPrivileges(string path, List<UserPrivileges> listPrivilege)
            {
                ManagementObject mo = new ManagementObject(string.Format("Win32_LogicalFileSecuritySetting.Path='{0}'", path));
                ManagementBaseObject outParams = mo.InvokeMethod("GetSecurityDescriptor", null, null);
    
                if ((uint)outParams.Properties["ReturnValue"].Value != 0)
                {
                    return MethodStatus.NetNameNotFound;
                }
                ManagementBaseObject Descriptor = (ManagementBaseObject)outParams.Properties["Descriptor"].Value;
    
                List<ManagementBaseObject> newDacl = new List<ManagementBaseObject>();
    
                foreach (UserPrivileges up in listPrivilege)
                {
    
                    ManagementClass trustee = new ManagementClass("win32_trustee");
                    trustee.Properties["Name"].Value = up.UserAccount;
                    trustee.Properties["Domain"].Value = null;
    
    
                    ManagementClass ace = new ManagementClass("win32_ace");
                    ace.Properties["AccessMask"].Value = up.ObjPrivileges; //AccessPrivileges.FileReadData | AccessPrivileges.FileReadAttributes | AccessPrivileges.FileReadEA
                    //| AccessPrivileges.ReadControl | AccessPrivileges.FileExecute;
                    ace.Properties["AceFlags"].Value = AceFlags.ObjectInheritAce | AceFlags.ContainerInheritAce | AceFlags.NoPropagateInheritAce;
                    ace.Properties["AceType"].Value = AceType.AccessAllowed;
                    ace.Properties["Trustee"].Value = trustee;
                    newDacl.Add(ace);
                }
                ManagementBaseObject inParams = mo.GetMethodParameters("SetSecurityDescriptor");
                Descriptor.Properties["Dacl"].Value = newDacl.ToArray();
    
    
                inParams["Descriptor"] = Descriptor;
                ManagementBaseObject ret = mo.InvokeMethod("SetSecurityDescriptor", inParams, null);
    
                uint returnValue = (uint)ret.Properties["ReturnValue"].Value;
                return (MethodStatus)returnValue;
            }
    
            public static List<UserPrivileges> GetPrivileges(string path)
            {
                List<UserPrivileges> list = new List<UserPrivileges>();
                ManagementPath mPath = new ManagementPath();
                mPath.Server = ".";
                mPath.NamespacePath = @"root\cimv2";
                mPath.RelativePath = @"Win32_LogicalFileSecuritySetting.Path='" + path + "'"; // using tmp as folder name
    
                ManagementObject lfs = new ManagementObject(mPath);
    
                ManagementBaseObject outParams = lfs.InvokeMethod("GetSecurityDescriptor", null, null);
                if (((uint)(outParams.Properties["ReturnValue"].Value)) == 0)
                {
    
                    ManagementBaseObject Descriptor = ((ManagementBaseObject)(outParams.Properties["Descriptor"].Value));
    
                    ManagementBaseObject[] DaclObject = ((ManagementBaseObject[])(Descriptor.Properties["Dacl"].Value));
    
                    foreach (ManagementBaseObject mbo in DaclObject)
                    {
                        UserPrivileges up = new UserPrivileges();
                        ManagementBaseObject Trustee = ((ManagementBaseObject)(mbo["Trustee"]));
                        up.Domain = Trustee.Properties["Domain"].Value == null ? "" : Trustee.Properties["Domain"].Value.ToString();
                        up.UserAccount = Trustee.Properties["Name"].Value.ToString();
    
    
                        UInt32 mask = (UInt32)mbo["AccessMask"];
    
                        int[] m = { (int)mask };
    
                        System.Collections.BitArray ba = new System.Collections.BitArray(m);
    
                        int i = 0;
    
                        IEnumerator baEnum = ba.GetEnumerator();
                        up.Privileges = new List<string>();
                        while (baEnum.MoveNext())
                        {
    
                            if ((bool)baEnum.Current)
    
                                up.Privileges.Add(filedesc[i].Trim());
    
                            i++;
    
                        }
                        list.Add(up);
                    }
    
    
    
                }
    
                List<UserPrivileges> listNew = new List<UserPrivileges>();
                foreach (var up in list)
                {
                    UserPrivileges upNew = listNew.Where(x => x.UserAccount == up.UserAccount).FirstOrDefault();
                    if (upNew != null)
                    {
                        upNew.Privileges.AddRange(up.Privileges);
                        upNew.Privileges = upNew.Privileges.Distinct().ToList();
                    }
                    else
                    {
                        listNew.Add(up);
                    }
                }
                return listNew; ;
            }
    
        }

    设置文件夹操作权限:

    private static void AddpathFilePower(string pathname, string username, string power)
            {
                try
                {
    
                    FileInfo dirinfo = new FileInfo(pathname);
    
                    if ((dirinfo.Attributes & FileAttributes.ReadOnly) != 0)
                    {
                        dirinfo.Attributes = FileAttributes.Normal;
                    }
    
                    //取得访问控制列表   
                    FileSecurity dirsecurity = dirinfo.GetAccessControl();
    
                    switch (power)
                    {
                        case "FullControl":
                            //dirsecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit, PropagationFlags.InheritOnly, AccessControlType.Allow));
                            //dirsecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.FullControl,AccessControlType.Allow));
                            dirsecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.FullControl, AccessControlType.Allow));
                            break;
                        case "ReadOnly":
                            dirsecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.Read, AccessControlType.Allow));
                            break;
                        case "Write":
                            dirsecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.Write, AccessControlType.Allow));
                            break;
                        case "Modify":
                            dirsecurity.AddAccessRule(new FileSystemAccessRule(username, FileSystemRights.Modify, AccessControlType.Allow));
                            break;
                    }
                    dirinfo.SetAccessControl(dirsecurity);
    
                }
                catch (Exception)
                {
    
                    throw;
                }
            }


    2016年10月13日 6:51

全部回复

  • Hi,

    你使用了下面的代码吗? 可以参考一下

    DirectoryInfo info = new DirectoryInfo(path[x]);
    
    DirectorySecurity security = info.GetAccessControl();
    
    security.AddAccessRule(new FileSystemAccessRule(logonName, FileSystemRights.Modify, InheritanceFlags.ContainerInherit, PropagationFlags.None, AccessControlType.Allow));
    
    security.AddAccessRule(new FileSystemAccessRule(logonName, FileSystemRights.Modify, InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
    
    info.SetAccessControl(security); 
    

    这儿有详细的信息,你可以看一下。https://social.msdn.microsoft.com/Forums/vstudio/en-US/e2294cb5-5d8a-4275-9651-b0a2933fccc1/create-a-folder-with-permissions-set-to-this-folder-subfolders?forum=csharpgeneral

    你可以提供一个demo给我们吗? 这样方便测试

    可以上传到onedrive https://onedrive.live.com/

    Best Regards,

    Hart


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.

    2016年10月13日 8:34
    版主
  • 可否通过调用DOS命令来实现


    专注于.NET ERP/CRM开发框架,C/S架构,SQL Server + ORM(LLBL Gen Pro) + Infragistics WinForms

    2016年10月13日 15:30
  • 这段代码写了,就是我传的最后一段。

    demo我中午弄吧

    2016年10月14日 1:36
  • 第二种就是,但是没有作用
    2016年10月14日 1:36
  • 这段代码写了,就是我传的最后一段。

    demo我中午弄吧

    你有debug的代码吗?第二部分代码有没有执行成功?

    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. Click HERE to participate the survey.


    2016年10月18日 6:04
    版主