2011-11-25 5 views
3

내가 가지고있는이 기능이 작동하지 않습니다 :에서 SHGetFolderPath 날

function GetProfilePath: string; 
const 
    SHGFP_TYPE_CURRENT = 0; 
var 
    hToken: THandle; 
    ProfilePath: packed array[ 0..MAX_PATH ] of Char; 
begin 
    ZeroMemory(@ProfilePath[0], SizeOf(ProfilePath)); 
    OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hToken); 
    SHGetFolderPath(0, CSIDL_APPDATA, hToken , SHGFP_TYPE_CURRENT, @ProfilePath[ 0 ]); 
    CloseHandle(hToken); 
    Result := ProfilePath; 
end; 

에서 SHGetFolderPath는 E_FAIL (0X80004005)와 빈 PROFILEPATH 버퍼를 반환합니다. MSDN에 따르면 E_FAIL은 "nFolder의 CSIDL은 유효하지만 해당 폴더가 존재하지 않음"을 의미합니다. 그러나 폴더는 존재합니다. 저는 꽤 확신합니다. 간단한 테스트 응용 프로그램을 만들고 동일한 코드를 실행하면 잘 작동합니다.

무엇이 잘못되었을 수 있습니까?

업데이트 : Delphi에서 실행할 때 내 응용 프로그램이 제대로 작동하지 않는 것으로 나타났습니다. 별도로 실행하면 모두 정상입니다.

감사합니다, 로마

+0

** 모든 API 호출에서 반환 값을 확인해야합니다 **. – OnTheFly

답변

2

사용자 토큰의 사용은 불필요하게 복잡한 보인다. 하지만, 말하자면, 내 컴퓨터에서 코드를 실행했을 때 오류없이 정상적으로 작동했습니다. 프로세스의 사용자 토큰에 해당 폴더에 대한 충분한 권한이 없을 수도 있습니다. 아니면 폴더가 실제로 존재하지 않습니다!

API가 더 간단하면 SHGetSpecialFolderPath을 사용하는 것이 더 나을 것이라고 생각합니다. 그에 대한 나의 래퍼는 다음과 같습니다 폴더가 실제로 존재하지 않는 경우

물론
function GetSpecialFolderPath(const CSIDL: Integer): string; 
var 
    Buffer: TWin32PathBuffer; 
begin 
    if SHGetSpecialFolderPath(Application.Handle, @Buffer[0], CSIDL, False) then begin 
    Result := Buffer; 
    end else begin 
    RaiseLastOSError; 
    end; 
end; 

,이 버전으로 그냥 같은 방법으로 실패 할 수 있습니다.


OK, 나는 당신의 질문에이 댓글을 다시 읽었습니다 :

나는 간단한 테스트 응용 프로그램을 작성하고 동일한 코드를 실행하는거야

, 그것은 잘 작동합니다.

다른 컨텍스트에서 실제 코드를 실행하는 것처럼 들립니다. 아마도 서비스 에서요? 또는 사용자 가장으로. 어쩌면 이것이 그 문제를 푸는 데 도움이 될지도 모른다. 코드가 실패한 환경/컨텍스트/설정에 대해 우리에게 말하지 않는 것은 무엇입니까?


코드에 대한 아주 간단한 설명입니다. 당신은 필요 이상의 많은 요소와 ProfilePath을 정의한 및 packed 배열에 대한 불필요 :

ProfilePath: array[ 0..MAX_PATH-1 ] of Char; 

또는 더 나은, 다시 사용하는 델파이 RTL, TWin32PathBuffer에 정의 된 유형입니다.

+0

팁 주셔서 감사합니다. 코드가 정확하지만 응용 프로그램에서 EOSError 예외 ("OS 함수 호출이 실패했습니다")가 발생합니다. "C : \ Document and Settings \ {사용자 이름} \ Application Data"폴더는 존재하며 다른 많은 응용 프로그램에서 사용됩니다. –

+0

최신 업데이트의 중간 섹션을 참조하십시오. 특정 앱에 대한 추가 정보가 아직 없을 것이라고 확신합니다. 아마 귀하의 코드 (및 광산) 평범한 바닐라 테스트 애플 리케이션에서 잘 작동합니다. –

+0

내 응용 프로그램이 서비스가 아니며 가장 (impersonation)을 사용하지 않습니다. 실제로, 나는 그 맥락이 중요하다는 것을 이해하지만 어떤 맥락의 세부 사항이 이해가되는지 모른다. –