C# xattr file attributes
I'm creating a cross-platform software and I want to know if there is any (easy) way to read/write Unix (Mac OSX/Linux) extended file attributes in C#.
I've just read about xattr namespaces, but I haven't found any information about C# implementation or bindings of this feature.
P.S. The only thing I found so far is python-xattr library, but I don't want to use it because:
- I don't want to obligate the users to install Python 开发者_如何学C(there is already Mono/.NET dependency to deal with)
- By using Python I will have a performance decrease (C# is compiled, while Python is interpreted)
- I don't want to rely/depend on external tools (if it's possible), because it's not safe
You should use the syscalls in Mono.Unix.Native.Syscall.*attr*. 
The nuget assembly is called Mono.Posix.NETStandard
Note that the name of the name-value pair is prefixed with a namespace. 
  According to man 7 xattr
Currently, the security, system, trusted, and user extended attribute classes are defined as described below. Additional classes may be added in the future.
public static void Test()
{
    string path = "/root/Desktop/CppSharp.txt";
    // Mono.Unix.Native.Syscall.getxattr()
    // Mono.Unix.Native.Syscall.fgetxattr()
    // Mono.Unix.Native.Syscall.lgetxattr()
    // Mono.Unix.Native.Syscall.setxattr()
    // Mono.Unix.Native.Syscall.fsetxattr()
    // Mono.Unix.Native.Syscall.lsetxattr
    // Mono.Unix.Native.Syscall.llistxattr()
    // Mono.Unix.Native.Syscall.flistxattr()
    // Mono.Unix.Native.Syscall.llistxattr()
    // Mono.Unix.Native.Syscall.removexattr()
    // Mono.Unix.Native.Syscall.fremovexattr()
    // Mono.Unix.Native.Syscall.lremovexattr()
    if (System.IO.File.Exists(path))
        System.Console.WriteLine("path exists");
    else
        System.Console.WriteLine("path doesn't exists");
    System.Text.Encoding enc = new System.Text.UTF8Encoding(false);
    string[] values = null;
    int setXattrSucceeded = Mono.Unix.Native.Syscall.setxattr(path, "user.foobar",
        enc.GetBytes("Hello World äöüÄÖÜ"), Mono.Unix.Native.XattrFlags.XATTR_CREATE);
    if (setXattrSucceeded == -1)
    {
        Mono.Unix.Native.Errno er = Mono.Unix.Native.Stdlib.GetLastError();
        string message = Mono.Unix.Native.Stdlib.strerror(er);
        // https://stackoverflow.com/questions/12662765/how-can-i-get-error-message-for-errno-value-c-language
        System.Console.WriteLine(message);
    } // End if (setXattrSucceeded == -1)
    byte[] data = null;
    long szLen = Mono.Unix.Native.Syscall.getxattr(path, "user.foobar", out data);
    string value = enc.GetString(data);
    System.Console.WriteLine(value);
    Mono.Unix.Native.Syscall.listxattr(path, System.Text.Encoding.UTF8, out values);
    System.Console.WriteLine(values);
    // https://man7.org/linux/man-pages/man2/getxattr.2.html
} // End Sub TestExtendedAttributes 
I think Mono.Unix.Native.Syscall.setxattr would be a better solution, which is in Mono.Posix module.
The final solution might be the following, tell me what do you think?
FileAttrsManager is an abstract class, used to create 2 derived classes:
- FileAttrsManagerDos: manages advanced attributes using DSOFile.dll*
- FileAttrsManagerUnix: manages advanced attributes using IronPython* and python-xattr**
[ * ] http:\\www.microsoft.com/download/en/details.aspx?displaylang=en&id=8422
[ ** ]  http:\\ironpython.codeplex.com
[ ** * ]  http:\\pypi.python.org/pypi/xatt
Extended attributes operation (such as SetPropery(string key, object value) and GetProperty(string key) etc) will be managed in a static class (FileAttrsProvider) that initializes a FileAttrsManager object to one of two derived types i.e.:
public static class FileAttrProvider
{
    private static FileAttrReader _reader = null;
    public static void Initialize()
    {
        switch (Environment.OSVersion.Platform)
        {
            case PlatformID.MacOSX:
            case PlatformID.Unix:
                _reader = new FileAttrReaderUnix();
                break;
            case PlatformID.Win32NT:
                _reader = new FileAttrReaderDos();
                break;
        }
    }
}
While the derived type depends on the environment, the original type is used in order to ensure an automatic dispatch of all the methods call on _reader object).
 
         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论