FileStream.SetAccessControl引发UnauthorizedAccessException :: File.SetAccessControl起作用 [英] FileStream.SetAccessControl throws UnauthorizedAccessException :: File.SetAccessControl Works

查看:128
本文介绍了FileStream.SetAccessControl引发UnauthorizedAccessException :: File.SetAccessControl起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

大家好,

我再次征求意见. . .

我最近更新了一些代码以使用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 use File.SetAccessControl() in your new method in place of FileStream.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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆