FileStream.SetAccessControl引发UnauthorizedAccessException :: File.SetAccessControl起作用 [英] FileStream.SetAccessControl throws UnauthorizedAccessException :: File.SetAccessControl Works
问题描述
大家好,
我再次征求意见. . .
我最近更新了一些代码以使用FileStream.原因是由于在调用XmlDocument.Save(path)
方法和调用我的SetOwner(path, impersonator)
方法(如下所示)之间由单独的应用程序删除了文件,导致遇到异常.在指定了 FileShare.None 选项的情况下使用文件流将使我可以锁定文件,直到所有操作成功完成为止.
但是,更改代码后,出现了System.UnauthorizedAccessException
异常.经调查,似乎是SetAccessControl方法引发了异常.我已经在下面添加了相关代码,并在注释中显示了如何调用该工作方法.
知道为什么File.SetAccessControl不在时FileStream.SetAccessControl会引发访问异常吗?
预先感谢,
JB
Hi Guys,
I''m once again after some advice. . .
I''ve recently updated some code to use a FileStream. The reason for this is I encounterred an exception due to a file being deleted by a seperate application between calling an XmlDocument.Save(path)
method and calling my SetOwner(path, impersonator)
method (below). Using the file stream with the FileShare.None option specified would allow me to lock the file until all operations had successfully completed.
However, after changing the code I get a System.UnauthorizedAccessException
exception. On investigation it seems to be the SetAccessControl method which is throwing the exception. I''ve included the relevant code below, as well as showing in comments how the working method can be called.
Any idea why the FileStream.SetAccessControl throws an access exception when the File.SetAccessControl doesn''t?
Thanks in advance,
JB
public void WriteFile(string path, Impersonator impersonator, XmlDocument xmlFile)
{
impersonator.Impersonate();
using (FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
{
xmlFile.Save(fs);
SetOwner(fs, impersonator); //doesn't work
fs.Close();
}
//SetOwner(path, impersonator); //works
impersonator.StopImpersonating();
}
void SetOwner(string path, Impersonator impersonator)
{
System.Security.AccessControl.FileSecurity security = File.GetAccessControl(path);
IdentityReference owner = new NTAccount(SecurityManager.JoinAccount(impersonator.Domain, impersonator.User));
security.SetOwner(owner); //if setting to a different account to your own, requires backup operator or admin rights, if impersonation isn't used.
File.SetAccessControl(path,security);
}
void SetOwner(FileStream fileStream, Impersonator impersonator)
{
System.Security.AccessControl.FileSecurity security = fileStream.GetAccessControl();
IdentityReference owner = new NTAccount(SecurityManager.JoinAccount(impersonator.Domain, impersonator.User));
security.SetOwner(owner); //if setting to a different account to your own, requires backup operator or admin rights, if impersonation isn't used.
fileStream.SetAccessControl(security);
}
如果相关,可以在此处找到有关Impersonator类的更多信息(此后代码有所更改,但是基本原理是相同的.)
http://www.codeproject.com/Messages/3656550/Re-Impersonation-using- Csharp.aspx [ ^ ]
异常堆栈跟踪为(已编辑以从名称空间中删除我的公司名称):
More info on the Impersonator class can be found here, should it be of relevance (the code has changed a little since then, but the basics are the same).
http://www.codeproject.com/Messages/3656550/Re-Impersonation-using-Csharp.aspx[^]
The exception stack trace is (editted to remove my company name from the namespace):
System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
at System.Security.AccessControl.FileSystemSecurity.Persist(SafeFileHandle handle, String fullPath)
at MyCompanyName.IO.FileSecurity.SetOwner(FileStream fileStream, Impersonator impersonator) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.IO\FileSecurity.cs:line 87
at MyCompanyName.IO.FileSecurity.WriteFile(String path, Impersonator impersonator, XmlDocument xmlFile) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.IO\FileSecurity.cs:line 29
at MyCompanyName.IO.FileSecurity.WriteFile(String path, String account, XmlDocument xmlFile) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.IO\FileSecurity.cs:line 19
at MyCompanyName.InterfaceAppLite.Port.XmlFileSystemSendPort.SendData(InterfaceData data) in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.Port\XmlFileSystemSendPort.cs:line 91
at MyCompanyName.InterfaceAppLite.Port.AbstractSendPort.Process() in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.Port\AbstractSendPort.cs:line 31
at MyCompanyName.InterfaceAppLite.Common.AbstractProcess.Run() in C:\Projects\MyCompanyName.InterfaceApp.Services\MyCompanyName.InterfaceAppLite.Common\AbstractProcess.cs:line 50
推荐答案
您仍然可以在新方法中使用File.SetAccessControl()
代替FileStream.SetAccessControl()
.我愿意打赌它也会起作用. MSDN实际上建议这种做法:
虽然可以在现有文件上使用FileStream类和SetAccessControl,但请考虑使用File.SetAccessControl方法,因为它更易于使用."
http://msdn.microsoft.com/en-us/library/system. io.filestream.setaccesscontrol.aspx [ ^ ]
You can still useFile.SetAccessControl()
in your new method in place ofFileStream.SetAccessControl()
. I''d be willing to bet it works, too. MSDN actually recommends this practice:
"While the FileStream class and SetAccessControl can be used on an existing file, consider using the File.SetAccessControl method as it is easier to use."
http://msdn.microsoft.com/en-us/library/system.io.filestream.setaccesscontrol.aspx[^]
太好了-谢谢Rick!
现在,我已经按照您的建议(包括在下面)更新了我的代码,并且它工作得很好.我没有尝试过此操作,因为我认为锁是文件流所拥有的,因此从其他对象访问文件会导致问题-否则很容易学习:).
再次感谢,
JB
That''s great - thanks Rick!
I''ve now updated my code as per your recommendation (included below), and it works perfectly. I''d not tried this as I thought the lock was owned by the file stream, so accessing the file from a different object would cause issues - nice to learn otherwise :).
Thanks again,
JB
public void WriteFile(string path, Impersonator impersonator, XmlDocument xmlFile)
{
impersonator.Impersonate();
using (FileStream fs = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
{
xmlFile.Save(fs);
SetOwner(path, impersonator);
fs.Close();
}
impersonator.StopImpersonating();
}
这篇关于FileStream.SetAccessControl引发UnauthorizedAccessException :: File.SetAccessControl起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!