2017-03-07 102 views
3

如何在Delphi 2009中獲取文件的所有者?Delphi 2009 - 獲取文件的所有者名稱

properties

我該得到的文件屬性的函數是這樣的:

type 
    TCustomFileInfo= record 
    CompanyName, 
    Owner, 
    SpecialBuild: string; 
    procedure Clear; 
    end; 

function GetFileInfo(const FileName: string): TCustomFileInfo; 
type 
    PLandCodepage = ^TLandCodepage; 
    TLandCodepage = record 
    wLanguage, 
    wCodePage: word; 
    end; 
var 
    dummy, 
    len: cardinal; 
    buf, pntr: pointer; 
    lang: string; 
begin 
    len := GetFileVersionInfoSize(PChar(FileName), dummy); 
    if len = 0 then 
    RaiseLastOSError; 
    GetMem(buf, len); 
    try 
    if not GetFileVersionInfo(PChar(FileName), 0, len, buf) then 
     RaiseLastOSError; 

    if not VerQueryValue(buf, '\VarFileInfo\Translation\', pntr, len) then 
     RaiseLastOSError; 

    lang := Format('%.4x%.4x', [PLandCodepage(pntr)^.wLanguage, PLandCodepage(pntr)^.wCodePage]); 

    // Get Company's name, if available... 
    if VerQueryValue(buf, PChar('\StringFileInfo\' + lang + '\CompanyName'), pntr, len){ and (@len <> nil)} then 
     result.CompanyName := PChar(pntr); 
    finally 
    FreeMem(buf); 
    end; 
end; 

...這對於這個公司名稱屬性工作正常,但我也不怎麼讓業主。

此外,當我嘗試對文件使用相同的方法時,沒有文件版本號GetFileVersionInfoSize不起作用,這是有道理的,因爲該文件沒有版本號在所有。

GetFileVersionInfoSize還有另外一種方法來獲取文件的所有者嗎?我不是很習慣windows apis,所以我真的不知道這是否是實現我想要的東西的正確方式(獲取所有者的名字)。

+0

這是您要的文件系統屬性? –

+0

'GetFileVersionInfoSize()'返回0不是錯誤,除非'GetLastError()'表示實際發生錯誤。即使'GetLastError()'返回0,'RaiseLastOSError()'總會引發'EOSError'異常。 –

+0

@DavidHeffernan我拍了一張照片,不幸的是用葡萄牙語,但我認爲你可以理解:[圖片](https:/ /puu.sh/uywsh/5f59bf2dc9.png) – Alisson

回答

7

有關文件所有權的信息未存儲在版本資源中,因此您不能使用VerQueryValue()來訪問它。

所有權關係到一個文件的安全性,所以你需要使用GetFileSecurity()GetNamedSecurityInfo()代替,如果你有一個文件名,或者GetUserObjectSecurity()如果你有一個打開的句柄到文件中。

無論使用哪種方式,您都會提供一個SECURITY_INFORMATION值作爲輸入,指定您要檢索的信息的類型。在這種情況下,您將使用OWNER_SECURITY_INFORMATION來請求文件所有者的SID。如果成功,您可以使用LookupAccountSid()或WMI獲取所有者的姓名。

+0

在你的答案後,我搜索了'GetFileSecurity()'的一個用法示例,並找到[this sample](http://www.delphipages.com/forum/showthread。 PHP?p值= 194849)。我可以得到用戶和域名,感謝幫助我! – Alisson

2

僅作爲對Remy答案的補充,此a是使用Win32_LogicalFileOwnerWin32_LogicalFileSecuritySetting WMI類獲取文件所有者的示例代碼。

{$APPTYPE CONSOLE} 

{$R *.res} 

uses 
    SysUtils, 
    ActiveX, 
    ComObj, 
    Variants; 


function GetFileOwner(const AFileName : string) : string; 
var 
    LSWbemLocator, LWMIService, LObjects, LObject : OLEVariant; 
    FileName  : string; 
    LEnumerator : IEnumvariant; 
    iValue   : LongWord; 
begin; 
    Result := ''; 
    LSWbemLocator := CreateOleObject('WbemScripting.SWbemLocator'); 
    LWMIService := LSWbemLocator.ConnectServer('localhost', 'root\CIMV2', '', ''); 

    //Escape the `\` chars in the FileName value because the '\' is a reserved character in WMI. 
    FileName  := StringReplace(AFileName, '\', '\\', [rfReplaceAll]); 
    LObjects := LWMIService.ExecQuery(Format('ASSOCIATORS OF {Win32_LogicalFileSecuritySetting="%s"} WHERE AssocClass = Win32_LogicalFileOwner ResultRole = Owner', [FileName])); 

    LEnumerator := IUnknown(LObjects._NewEnum) as IEnumVariant; 
    if LEnumerator.Next(1, LObject, iValue) = 0 then 
    Result := string(LObject.AccountName); // 
end; 

begin 
try 
    CoInitialize(nil); 
    try 
    Writeln(GetFileOwner('C:\Foo.Bar')); 
    finally 
     CoUninitialize; 
    end; 
except 
    on E:Exception do 
     Writeln(E.Classname, ':', E.Message); 
    end; 
    Readln; 
end. 
相關問題