c# - 使用 Win32 API 移动文件时自动设置安全属性?(C#)
问题描述
我目前正在开发一个必须将文件移动到另一个应用程序文件夹的应用程序。但其他应用程序必须对复制的文件具有特定权限。当我使用 Win32 API 来 MoveFileFromApp(它是 uwp 应用程序)时,它不会更新安全属性以继承文件夹。这是 MoveFile (C#) 的代码
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
internal static extern bool MoveFileFromApp(
string lpExistingFileName,
string lpNewFileName
);
有谁知道如何在移动时自动为文件夹设置这些安全权限?非常感谢 !(对不起,不清楚的问题......)
解决方案
我尝试通过以下代码在 UWP 应用程序中使用P/InvokeSetNamedSecurityInfo
方法。UWP 应用程序中始终存在错误ERROR_ACCESS_DENIED (错误代码为 5)。但是在Win32中,使用带有值的方法来继承安全属性是成功的。SetNamedSecurityInfo
UNPROTECTED_DACL_SECURITY_INFORMATION
在 UWP 中,对文件系统访问权限有一些限制。虽然SetNamedSecurityInfo
可以成功调用该方法,但它并没有按预期工作。
在 UWP 中使用 SetNamedSecurityInfo 方法的代码:
public uint DACL_SECURITY_INFORMATION = 0x00000004;
public uint UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000;
public uint ACL_REVISION = 0x2;
[StructLayout(LayoutKind.Sequential)]
public struct ACL
{
public byte AclRevision;
public byte Sbz1;
public ushort AclSize;
public ushort AceCount;
public ushort Sbz2;
}
public enum SE_OBJECT_TYPE
{
SE_UNKNOWN_OBJECT_TYPE = 0,
SE_FILE_OBJECT,
SE_SERVICE,
SE_PRINTER,
SE_REGISTRY_KEY,
SE_LMSHARE,
SE_KERNEL_OBJECT,
SE_WINDOW_OBJECT,
SE_DS_OBJECT,
SE_DS_OBJECT_ALL,
SE_PROVIDER_DEFINED_OBJECT,
SE_WMIGUID_OBJECT,
SE_REGISTRY_WOW64_32KEY,
SE_REGISTRY_WOW64_64KEY,
}
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern bool MoveFileFromAppW(
string lpExistingFileName,
string lpNewFileName);
[DllImport("advapi32.DLL", CharSet = CharSet.Unicode, SetLastError = true)]
internal static extern uint SetNamedSecurityInfo(
string lpFileName,
SE_OBJECT_TYPE ObjectType,
uint SecurityInfo,
IntPtr psidOwner,
IntPtr psidGroup,
ref ACL pDacl,
IntPtr pSacl);
[DllImport("advapi32.dll", SetLastError = true)]
internal static extern bool InitializeAcl(ref ACL pAcl, int nAclLength, uint dwAclRevision);
[DllImport("api-ms-win-core-file-fromapp-l1-1-0.dll", CharSet = CharSet.Auto,
CallingConvention = CallingConvention.StdCall,
SetLastError = true)]
internal static extern bool MoveFileFromApp(
string lpExistingFileName,
string lpNewFileName
);
public void SetFilePermission(string FileName)
{//Use the method to let the file inherit the security attributes from parent object
bool ret = false;
ACL pDacl = new ACL();
ret = InitializeAcl(ref pDacl, Marshal.SizeOf<ACL>(), ACL_REVISION);
uint SecurityInfo = DACL_SECURITY_INFORMATION | UNPROTECTED_DACL_SECURITY_INFORMATION;
uint err = SetNamedSecurityInfo(FileName, SE_OBJECT_TYPE.SE_FILE_OBJECT, SecurityInfo, IntPtr.Zero, IntPtr.Zero, ref pDacl, IntPtr.Zero);
}
推荐阅读
- cypress - 打开 cypress 时出现 applitool 错误
- azure - 如何在 Azure 发布管道上创建自定义参数
- python - 频繁的 Python2.7 核心转储
- java - 使用 () 时 IntelliJ IDEA 控制台输入失败
- node.js - 在 Yocto 中的节点上安装 sqlite3 显示错误 node-pre-gyp ERR!堆栈错误:无法执行'/usr/local/bin/node
- python - 我正在寻找在python中嵌套数字列表的简短方法?
- css - max-width + full-width 不起作用网格子内的元素
- python - 有没有办法通过 django rest api 返回多个 json 对象?
- python - ImportError:使用scrapy时没有名为counsor.settings的模块
- laravel - Laravel Log 带有 UserId 和日期的客户日志文件