2017-07-16 100 views
5

我想学习如何使用.NET核心在Linux/Unix上设置文件权限。我已经在这里发现了一个问题,指向System.IO.FileSystem的方向,但我似乎找不到有关如何使用它的任何文档。使用.NET核心的Linux/Unix上的文件权限

简而言之,我想从一个只能在Linux上运行的.net核心应用程序中chmod一个文件644,但在如何继续下去的时候感到茫然。

谢谢。

+0

Microsoft在Windows上使用其文件权限模型并将其转换为Linux/UNIX。所以对'chmod'的调用是内部的,https://github.com/dotnet/corefx/blob/bffef76f6af208e2042a2f27bc081ee908bb390b/src/Common/src/Interop/Unix/System.Native/Interop.ChMod.cs并且仅用于https://github.com/dotnet/corefx/blob/801dde95a5eac06140d0ac633ac3f9bfdd25aca5/src/System.IO.FileSystem/src/System/IO/FileSystemInfo.Unix.cs所以你的情况,你必须翻译644到相应的Windows文件权限然后使用Windows方式来操作文件。 –

回答

6

目前,.NET Core中没有内置的API。但是,.NET Core团队正致力于在.NET Core上提供Mono.Posix。这暴露了API在托管代码中执行这种操作。见https://github.com/dotnet/corefx/issues/15289https://github.com/dotnet/corefx/issues/3186。您可以尝试在这里这个API的早期版本:https://www.nuget.org/packages/Mono.Posix.NETStandard/1.0.0-beta1

var unixFileInfo = new Mono.Unix.UnixFileInfo("test.txt"); 
    // set file permission to 644 
    unixFileInfo.FileAccessPermissions = 
     FileAccessPermissions.UserRead | FileAccessPermissions.UserWrite 
     | FileAccessPermissions.GroupRead 
     | FileAccessPermissions.OtherRead; 

如果你不想使用Mono.Posix,您可以通过调用本机代码实现相同的功能。使用P/Invoke,可以从libc调用chmod函数。有关本机API的更多详细信息,请参阅man 2 chmod

using System; 
using System.IO; 
using System.Runtime.InteropServices; 
using static System.Console; 

class Program 
{ 
    [DllImport("libc", SetLastError = true)] 
    private static extern int chmod(string pathname, int mode); 

    // user permissions 
    const int S_IRUSR = 0x100; 
    const int S_IWUSR = 0x80; 
    const int S_IXUSR = 0x40; 

    // group permission 
    const int S_IRGRP = 0x20; 
    const int S_IWGRP = 0x10; 
    const int S_IXGRP = 0x8; 

    // other permissions 
    const int S_IROTH = 0x4; 
    const int S_IWOTH = 0x2; 
    const int S_IXOTH = 0x1; 

    static void Main(string[] args) 
    { 
     WriteLine("Setting permissions to 0755 on test.sh"); 
     const int _0755 = 
      S_IRUSR | S_IXUSR | S_IWUSR 
      | S_IRGRP | S_IXGRP 
      | S_IROTH | S_IXOTH; 
     WriteLine("Result = " + chmod(Path.GetFullPath("test.sh"), (int)_0755)); 

     WriteLine("Setting permissions to 0644 on sample.txt"); 
     const int _0644 = 
      S_IRUSR | S_IWUSR 
      | S_IRGRP 
      | S_IROTH; 
     WriteLine("Result = " + chmod(Path.GetFullPath("sample.txt"), _0644)); 

     WriteLine("Setting permissions to 0600 on secret.txt"); 
     const int _0600 = S_IRUSR | S_IWUSR; 
     WriteLine("Result = " + chmod(Path.GetFullPath("secret.txt"), _0600)); 
    } 
} 
1

我由刚开始一个新的进程和执行的bash命令chmod解决了这个问题。

实施例:

public static void Exec(string cmd) 
{ 
    var escapedArgs = cmd.Replace("\"", "\\\""); 

    var process = new Process 
    { 
     StartInfo = new ProcessStartInfo 
     { 
      RedirectStandardOutput = true, 
      UseShellExecute = false, 
      CreateNoWindow = true, 
      WindowStyle = ProcessWindowStyle.Hidden, 
      FileName = "/bin/bash", 
      Arguments = $"-c \"{escapedArgs}\"" 
     } 
    }; 

    process.Start(); 
    process.WaitForExit(); 
} 

然后:

Exec("chmod 644 /path/to/file.txt"); 

还可以使用此Exec方法运行的任何其它类型的bash命令。