2017-03-07 14 views
3

Delphi 2009에서 파일 소유자를 얻으려면 어떻게해야합니까? 이 회사 명 속성에 대해 잘 작동Delphi 2009 - 파일 소유자 이름 얻기

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; 

을 ...,하지만 난 어떻게 소유자를 얻는하지 마십시오

properties

내가 파일을 가져 기능을 가지고

는 다음과 같이 속성 . 또한

, 나는 파일이 버전 번호에서이 없기 때문에, 말이 파일 버전 번호, GetFileVersionInfoSize이 작동하지 않습니다,이없는 파일에 대한이 같은 방법을 사용하려고하면 모든.

GetFileVersionInfoSize에 대한 다른 방법이나 파일 소유자를 가져 오는 다른 방법이 있습니까? 나는 Windows apis에 익숙하지 않아서, 이것이 내가 원하는 것 (소유자의 이름을 얻는 것)을 달성하는 올바른 방법인지는 알 수 없다.

+0

원하는 파일 시스템 속성입니까? –

+0

'GetLastError()'가 실제로 오류가 발생하지 않는다면 GetFileVersionInfoSize()는 0을 반환하는 것은 오류가 아닙니다. '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 답변을 보완하기 위해이 파일은 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.