询问者
请问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; } }
全部回复
-
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);
你可以提供一个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.
-
这段代码写了,就是我传的最后一段。
demo我中午弄吧
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.
- 已编辑 Hart WangModerator 2016年10月20日 8:42