using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.Security.Principal;
using Microsoft.VisualBasic;
namespace Common;
///
/// 文件操作策略
///
public abstract class FileDirOpStra
{
public abstract void FileCreate(string absolutePath, DateTime mtime);
public abstract void DirCreate(Dir dir, bool IsRecursion = true);
public abstract void FileModify(string absolutePath, DateTime mtime);
public abstract void FileDel(string absolutePath);
public abstract void DirDel(Dir dir, bool IsRecursion = true);
}
///
/// 文件目录打包
///
///
public class FileDirOpForPack(string srcRootPath, string dstRootPath) : FileDirOpStra
{
///
/// 目标根目录
///
public readonly string DstRootPath = dstRootPath;
///
/// 源目录
///
public readonly string SrcRootPath = srcRootPath;
///
/// 最终完成时的压缩
///
public void FinallyCompress()
{
var x = DstRootPath;
}
public override void FileCreate(string absolutePath, DateTime mtime)
{
throw new NotImplementedException();
}
public override void DirCreate(Dir dir, bool IsRecursion = true)
{
throw new NotImplementedException();
}
public override void FileModify(string absolutePath, DateTime mtime)
{
throw new NotImplementedException();
}
public override void FileDel(string absolutePath)
{
throw new NotImplementedException();
}
public override void DirDel(Dir dir, bool IsRecursion = true)
{
throw new NotImplementedException();
}
}
public class FileDirOpForUnpack(string srcCompressedPath, string dstRootPath) : FileDirOpStra
{
///
/// 解压缩,必须首先调用
///
public void FirstUnComparess()
{
var x = SrcCompressedPath;
}
///
/// 目标根目录
///
public readonly string DstRootPath = dstRootPath;
///
/// 源目录
///
public readonly string SrcCompressedPath = srcCompressedPath;
///
/// 最终完成时的压缩
///
public override void FileCreate(string absolutePath, DateTime mtime)
{
throw new NotImplementedException();
}
public override void DirCreate(Dir dir, bool IsRecursion = true)
{
throw new NotImplementedException();
}
public override void FileModify(string absolutePath, DateTime mtime)
{
throw new NotImplementedException();
}
public override void FileDel(string absolutePath)
{
throw new NotImplementedException();
}
public override void DirDel(Dir dir, bool IsRecursion = true)
{
throw new NotImplementedException();
}
}
///
/// 文件目录权限校验
///
public class FileDirOpForAccessCheck : FileDirOpStra
{
public override void FileCreate(string absolutePath, DateTime mtime)
{
throw new NotImplementedException();
}
public override void DirCreate(Dir dir, bool IsRecursion = true)
{
throw new NotImplementedException();
}
public override void FileModify(string absolutePath, DateTime mtime)
{
throw new NotImplementedException();
}
public override void FileDel(string absolutePath)
{
throw new NotImplementedException();
}
public override void DirDel(Dir dir, bool IsRecursion = true)
{
throw new NotImplementedException();
}
}
public enum FileAccess
{
Read,
Write,
Delete,
Execute
}
public enum DirAcess
{
///
/// 读取权限
///
Read,
///
/// 写入权限
///
Write,
///
/// 修改权限
///
Modify,
///
/// 列出文件夹权限
///
ListDirectory,
///
/// 创建文件权限
///
CreateFiles,
///
/// 创建文件夹权限
///
CreateDirectories,
///
/// 删除文件权限
///
Delete,
///
/// 删除文件夹及其子文件
///
DeleteSubdirectoriesAndFiles,
}
///
/// 运行此软件的用户与目标软件的用户最好是 一个用户,一个用户组,或者运行此软件的用户具备最高权限。
///
public class AccessWrapper
{
///
///
///
///
public static void FreeThisDirAccess(string absolutePath)
{
if (
CheckDirAccess(
absolutePath,
[
DirAcess.Read,
DirAcess.Write,
DirAcess.Modify,
DirAcess.Delete,
DirAcess.ListDirectory,
DirAcess.CreateFiles,
DirAcess.CreateDirectories,
DirAcess.DeleteSubdirectoriesAndFiles
]
)
) { }
else
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
DirectoryInfo dirInfo = new(absolutePath);
//获得该文件的访问权限
var dirSecurity = dirInfo.GetAccessControl();
//设定文件ACL继承
InheritanceFlags inherits =
InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit;
var cUser =
WindowsIdentity.GetCurrent().User
?? throw new Exception("GetWindowsIdentity failed. 你需要手动处理发布内容!");
FileSystemAccessRule ReadRule =
new(
cUser,
FileSystemRights.Read,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule WriteRule =
new(
cUser,
FileSystemRights.Write,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule ModifyRule =
new(
cUser,
FileSystemRights.Modify,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule DeleteRule =
new(
cUser,
FileSystemRights.Delete,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule ListDirectoryRule =
new(
cUser,
FileSystemRights.ListDirectory,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule CreateFilesRule =
new(
cUser,
FileSystemRights.CreateFiles,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule CreateDirsRule =
new(
cUser,
FileSystemRights.CreateDirectories,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
FileSystemAccessRule DeleteSubdirectoriesAndFilesRule =
new(
cUser,
FileSystemRights.DeleteSubdirectoriesAndFiles,
inherits,
PropagationFlags.None,
AccessControlType.Allow
);
if (
dirSecurity.ModifyAccessRule(AccessControlModification.Add, ReadRule, out _)
&& dirSecurity.ModifyAccessRule(AccessControlModification.Add, WriteRule, out _)
&& dirSecurity.ModifyAccessRule(
AccessControlModification.Add,
ModifyRule,
out _
)
&& dirSecurity.ModifyAccessRule(
AccessControlModification.Add,
ListDirectoryRule,
out _
)
&& dirSecurity.ModifyAccessRule(
AccessControlModification.Add,
CreateFilesRule,
out _
)
&& dirSecurity.ModifyAccessRule(
AccessControlModification.Add,
CreateDirsRule,
out _
)
&& dirSecurity.ModifyAccessRule(
AccessControlModification.Add,
DeleteRule,
out _
)
&& dirSecurity.ModifyAccessRule(
AccessControlModification.Add,
DeleteSubdirectoriesAndFilesRule,
out _
)
) { }
else
{
throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!");
}
//设置访问权限
dirInfo.SetAccessControl(dirSecurity);
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
//TODO Linux文件权限
}
else
{
throw new NotSupportedException(
$"{RuntimeInformation.OSDescription} is not supported."
);
}
}
}
public static void FreeThisFileAccess(string absolutePath)
{
if (
CheckFileAccess(
absolutePath,
[FileAccess.Read, FileAccess.Write, FileAccess.Delete, FileAccess.Execute]
)
) { }
else
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
FileInfo fileInfo = new(absolutePath);
//获得该文件的访问权限
FileSecurity fileSecurity = fileInfo.GetAccessControl();
var cUser =
WindowsIdentity.GetCurrent().User
?? throw new Exception("GetWindowsIdentity failed. 你需要手动处理发布内容!");
FileSystemAccessRule ReadRule =
new(cUser, FileSystemRights.Read, AccessControlType.Allow);
FileSystemAccessRule WriteRule =
new(cUser, FileSystemRights.Write, AccessControlType.Allow);
FileSystemAccessRule DeleteRule =
new(cUser, FileSystemRights.Delete, AccessControlType.Allow);
FileSystemAccessRule ExecuteRule =
new(cUser, FileSystemRights.ExecuteFile, AccessControlType.Allow);
if (
fileSecurity.ModifyAccessRule(AccessControlModification.Add, ReadRule, out _)
&& fileSecurity.ModifyAccessRule(
AccessControlModification.Add,
WriteRule,
out _
)
&& fileSecurity.ModifyAccessRule(
AccessControlModification.Add,
DeleteRule,
out _
)
&& fileSecurity.ModifyAccessRule(
AccessControlModification.Add,
ExecuteRule,
out _
)
) { }
else
{
throw new Exception("AddAccessRule failed. 你需要手动处理发布内容!");
}
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
//TODO Linux文件权限
}
else
{
throw new NotSupportedException(
$"{RuntimeInformation.OSDescription} is not supported."
);
}
}
}
public static bool CheckDirAccess(string absolutePath, DirAcess[] access)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
DirectoryInfo dirInfo = new(absolutePath);
//获得该文件的访问权限
var dirSecurity = dirInfo.GetAccessControl();
var ac = dirSecurity
.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount))
.Cast();
#pragma warning disable CA1416 // Validate platform compatibility
var it =
from i in ac
where i.IdentityReference == WindowsIdentity.GetCurrent().User
select i;
#pragma warning restore CA1416 // Validate platform compatibility
List caccess = [];
foreach (var i in it)
{
if (i.FileSystemRights == FileSystemRights.FullControl)
{
return true;
}
else if (i.FileSystemRights == FileSystemRights.Read)
{
caccess.Add(DirAcess.Read);
}
else if (i.FileSystemRights == FileSystemRights.Write)
{
caccess.Add(DirAcess.Write);
}
else if (i.FileSystemRights == FileSystemRights.Delete)
{
caccess.Add(DirAcess.Delete);
}
else if (i.FileSystemRights == FileSystemRights.Modify)
{
caccess.Add(DirAcess.Modify);
}
else if (i.FileSystemRights == FileSystemRights.ListDirectory)
{
caccess.Add(DirAcess.ListDirectory);
}
else if (i.FileSystemRights == FileSystemRights.CreateFiles)
{
caccess.Add(DirAcess.CreateFiles);
}
else if (i.FileSystemRights == FileSystemRights.CreateDirectories)
{
caccess.Add(DirAcess.CreateDirectories);
}
else if (i.FileSystemRights == FileSystemRights.DeleteSubdirectoriesAndFiles)
{
caccess.Add(DirAcess.DeleteSubdirectoriesAndFiles);
}
}
foreach (var i in access)
{
if (!caccess.Contains(i))
{
return false;
}
}
return true;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
//TODO Linux文件权限
return true;
}
else
{
throw new NotSupportedException(
$"{RuntimeInformation.OSDescription} is not supported."
);
}
}
public static bool CheckFileAccess(string absolutePath, FileAccess[] access)
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
FileInfo fileInfo = new(absolutePath);
//获得该文件的访问权限
FileSecurity fileSecurity = fileInfo.GetAccessControl();
var ac = fileSecurity
.GetAccessRules(true, true, typeof(System.Security.Principal.NTAccount))
.Cast();
#pragma warning disable CA1416 // Validate platform compatibility
var it =
from i in ac
where i.IdentityReference == WindowsIdentity.GetCurrent().User
select i;
#pragma warning restore CA1416 // Validate platform compatibility
List caccess = [];
foreach (var i in it)
{
if (i.FileSystemRights == FileSystemRights.FullControl)
{
return true;
}
else if (i.FileSystemRights == FileSystemRights.Read)
{
caccess.Add(FileAccess.Read);
}
else if (i.FileSystemRights == FileSystemRights.Write)
{
caccess.Add(FileAccess.Write);
}
else if (i.FileSystemRights == FileSystemRights.Delete)
{
caccess.Add(FileAccess.Delete);
}
else if (i.FileSystemRights == FileSystemRights.ExecuteFile)
{
caccess.Add(FileAccess.Execute);
}
}
foreach (var i in access)
{
if (!caccess.Contains(i))
{
return false;
}
}
return true;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
//TODO Linux文件夹权限
return true;
}
else
{
throw new NotSupportedException(
$"{RuntimeInformation.OSDescription} is not supported."
);
}
}
///
/// 获取当前用户
///
///
///
public static string GetCurrentUser()
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
return System.Security.Principal.WindowsIdentity.GetCurrent().Name;
}
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
{
return Environment.UserName;
}
else
{
throw new NotSupportedException(
$"{RuntimeInformation.OSDescription} is not supported."
);
}
}
}