简体   繁体   English

System.MissingMethodException: 不能使用 dirInfo.GetAccessControl(); 在 C# 中

[英]System.MissingMethodException: cannot use dirInfo.GetAccessControl(); in c#

Issue:问题:

I am following the microsoft reference in order to set directory permissions on a network share.我正在关注microsoft 参考,以便在网络共享上设置目录权限。

Despite the Intellicode not showing any issue, I receive the following error as soon as a function is called which contains dirInfo.GetAccessControl();尽管 Intellicode 没有显示任何问题,但只要调用包含dirInfo.GetAccessControl();的函数,我就会收到以下错误dirInfo.GetAccessControl();

System.MissingMethodException: 'Method not found: 'System.Security.AccessControl.DirectorySecurity System.IO.DirectoryInfo.GetAccessControl()'.' System.MissingMethodException: '找不到方法:'System.Security.AccessControl.DirectorySecurity System.IO.DirectoryInfo.GetAccessControl()'。'

The function to execute is as follows:要执行的函数如下:

public static void SetFullPermission(string path, string domainAccount)
{
    NTAccount ntaccount = new NTAccount("my_domain", domainAccount);
    var ds = new DirectorySecurity();
    DirectoryInfo dirInfo = new DirectoryInfo(path);
    ds = dirInfo.GetAccessControl();
    ds.AddAccessRule(new FileSystemAccessRule(ntaccount, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
    ds.SetAccessRuleProtection(true, false); // disable inheritance and clear any inherited permissions
    dirInfo.SetAccessControl(ds);
}

As soon as I uncomment the line var ds = new DirectorySecurity();一旦我取消注释var ds = new DirectorySecurity(); the code gets executed but no permissions are set.代码被执行但没有设置权限。

Code reference代码参考

For reference, the following code might be useful.作为参考,以下代码可能有用。 The calling code looks like the following:调用代码如下所示:

System.Net.NetworkCredential cred = new System.Net.NetworkCredential("my_admin",pwd);
using (new NetworkConnection(@"\\my_fileserver\Data\Home", cred))
{
    string path = $@"\\my_fileserver\Data\Home\testuserfolder";
    string domainName = "my_domain";
    string userNameToCreate = "testuser";
    Directory.CreateDirectory(path);
    SetFullPermission(path, userNameToCreate);
}

The code which calls SetFullPermission utilizes a class found in How to provide user name and password when connecting to a network share because my normal account has no permissions on the network drive.调用SetFullPermission的代码利用了如何在连接到网络共享时提供用户名和密码中找到的类,因为我的普通帐户在网络驱动器上没有权限。

The class NewNetworkConnection() is as follows: NewNetworkConnection()类如下:

using System;
using System.ComponentModel;
using System.Net;
using System.Runtime.InteropServices;

namespace FileInterface
{
    public class NetworkConnection : IDisposable
    {
        string _networkName;

        public NetworkConnection(string networkName,
            NetworkCredential credentials)
        {
            _networkName = networkName;

            var netResource = new NetResource()
            {
                Scope = ResourceScope.GlobalNetwork,
                ResourceType = ResourceType.Disk,
                DisplayType = ResourceDisplaytype.Share,
                RemoteName = networkName
            };

            var userName = string.IsNullOrEmpty(credentials.Domain)
                ? credentials.UserName
                : string.Format(@"{0}\{1}", credentials.Domain, credentials.UserName);

            var result = WNetAddConnection2(
                netResource,
                credentials.Password,
                userName,
                0);

            if (result != 0)
            {
                throw new Win32Exception(result);
            }
        }

        ~NetworkConnection()
        {
            Dispose(false);
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {
            WNetCancelConnection2(_networkName, 0, true);
        }

        [DllImport("mpr.dll")]
        private static extern int WNetAddConnection2(NetResource netResource,
            string password, string username, int flags);

        [DllImport("mpr.dll")]
        private static extern int WNetCancelConnection2(string name, int flags,
            bool force);
    }

    [StructLayout(LayoutKind.Sequential)]
    public class NetResource
    {
        public ResourceScope Scope;
        public ResourceType ResourceType;
        public ResourceDisplaytype DisplayType;
        public int Usage;
        public string LocalName;
        public string RemoteName;
        public string Comment;
        public string Provider;
    }

    public enum ResourceScope : int
    {
        Connected = 1,
        GlobalNetwork,
        Remembered,
        Recent,
        Context
    };

    public enum ResourceType : int
    {
        Any = 0,
        Disk = 1,
        Print = 2,
        Reserved = 8,
    }

    public enum ResourceDisplaytype : int
    {
        Generic = 0x0,
        Domain = 0x01,
        Server = 0x02,
        Share = 0x03,
        File = 0x04,
        Group = 0x05,
        Network = 0x06,
        Root = 0x07,
        Shareadmin = 0x08,
        Directory = 0x09,
        Tree = 0x0a,
        Ndscontainer = 0x0b
    }
}

Solution reference解决方案参考

The following solution information might be important:以下解决方案信息可能很重要:

  • The solution has a main project Ticketing solution targeting .NET Core该解决方案有一个针对.NET Core的主项目Ticketing solution
  • The project where the issues code relies in is a .NET Framework class library targeting .NET framework 4.8问题代码所依赖的项目是一个面向.NET framework 4.8.NET Framework类库

在此处输入图片说明

The reason for the different framework targets is that some code requires the one framework, other code or reference might only work with the other.不同框架目标的原因是一些代码需要一个框架,其他代码或参考可能只适用于另一个。

In a Multi-Target Solution, the .net core code must be used, eventhough the target is .Net Framework 4.8:在多目标解决方案中,必须使用 .net 核心代码,即使目标是 .Net Framework 4.8:

change the GetAccessControl and SetAccesscontrol (see uncommented lines for difference)更改GetAccessControlSetAccesscontrol (有关差异,请参阅未注释的行)

public static void SetFullPermission(string path, string domainAccount)
{
    NTAccount ntaccount = new NTAccount("skan_nt1", domainAccount);
    var ds = new DirectorySecurity();
    DirectoryInfo dirInfo = new DirectoryInfo(path);
    ds = FileSystemAclExtensions.GetAccessControl(dirInfo);
    //ds = dirInfo.GetAccessControl();
    ds.AddAccessRule(new FileSystemAccessRule(ntaccount, FileSystemRights.FullControl, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit, PropagationFlags.None, AccessControlType.Allow));
    ds.SetAccessRuleProtection(true, false); // disable inheritance and clear any inherited permissions
    FileSystemAclExtensions.SetAccessControl(dirInfo,ds);
    //Directory.SetAccessControl(path, ds);
}

additionally, make sure nuget package is installed: System.Security.AccessControl另外,请确保安装了 nuget 包: System.Security.AccessControl

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM