C#更改文件訪問權限全部者(適用於各個Windows版本)

前面也提到了,前段時間在作Online Judge系統,在正式上線前有幾個比較老的版本,其中第一個版本使用ACL來控制權限以確保安全(可是這個版本徹底創建在IIS上,因此這樣作是沒效果的),遇到了一些問題,至於問題是什麼之後有機會再說,那麼解決這些問題曾想到一個辦法,更改文件的全部者。c#

在搜索引擎裏搜索「C# 修改文件全部者」都會搜索到不少相似《c# 更改文件訪問權限 全部者(適用於win7如下版本) 》,可是就沒出現過《c# 更改文件訪問權限 全部者(適用於各個Windows版本) 》。爲何要特地強調適用於win7如下版本,是由於安全

FileInfo fi = new FileInfo(@"d:\囧.txt");
FileSecurity fs = fi.GetAccessControl();
NTAccount currentAccount = (NTAccount)fs.GetOwner(typeof(NTAccount));
Console.WriteLine("先前的全部者爲 " + currentAccount.Value);
NTAccount admins = new NTAccount("administrators");//注意 這裏是administrators 而不是administrator 他表示管理員組而非一個單個的賬號
fs.SetOwner(admins);
fi.SetAccessControl(fs);
Console.WriteLine("當前的全部者爲 " + fi.GetAccessControl().GetOwner(typeof(NTAccount)).Value);

這樣作會在Windows 7以及更高版本上go die(不容許將安全標識符做爲此對象的全部者),高版本Windows須要用Win32API,若是手工去操做會複雜不少。偶然在StackOverflow上找到一篇文章說到了一個解決方案,因爲年代久遠不可考(實際上是懶當時沒記忘了)因此就不貼原文了。dom

爆棧網上的答主給的方法是使用一個外部庫,這個庫看名字就知道是幹什麼的,用起來也特別方便:搜索引擎

貼段老代碼(應該是這麼用的,這個版本還能跑起來):code

File.Copy(outfileName, tempfileName);
var everyone = new SecurityIdentifier(WellKnownSidType.WorldSid, null);
var domain = new FileInfo(outfileName).GetAccessControl().GetOwner(typeof(NTAccount)).Value.Split('\\')[0];
var user = new FileInfo(outfileName).GetAccessControl().GetOwner(typeof(NTAccount)).Value.Split('\\')[1];
var ediFileOwner = new NTAccount(domain, user);
var fileSecurity = File.GetAccessControl(outfileName);
File.SetAccessControl(outfileName, fileSecurity);
File.Delete(outfileName);
File.Move(tempfileName, outfileName);
var aosSID = (SecurityIdentifier)ediFileOwner.Translate(typeof(SecurityIdentifier));
File.SetAccessControl(outfileName, fileSecurity);
using (new Impersonator(/*UserName*/, domain, /*UserPassword*/))
{
    fileSecurity = File.GetAccessControl(outfileName);
    fileSecurity.SetOwner(ediFileOwner);
    File.SetAccessControl(outfileName, fileSecurity);
}

在註釋處填寫要更改成的全部者的帳戶名和密碼。雖然看起來很複雜的樣子,其實過程很是簡單:建立源文件的副本,得到它的信息,幹掉源文件,更名副本而後調用Impersonator來設置全部者。對象

使用前,這個鍋是楊某的:blog

執行後,這個鍋就甩了:索引

相關文章
相關標籤/搜索