我有一个应用程序,有时无法获取AppData
文件夹的路径。
这种情况似乎只发生在我们的Citrix服务器场上,并非针对每个用户,而且并非一直如此(我几乎无法复制)。
问题通过以下方式表现出来:
SHGetFolderLocation
的调用方式为:
Value := SHGetFolderLocation (0, CLSID, 0, 0, pidl);
try
case Value of
S_OK:
begin
if not ShGetPathfromIDList(pidl, Path) then
RaiseLastOSError();
Result := trim(string(Path));
break;
end;
else
RaiseLastOSError();
end;
finally
CoTaskMemFree(pidl);
end;
({CLSID
设置为CSIDL_APPDATA
,定义为0x001a
)
根据堆栈跟踪,我们看到的是SHGetFolderLocation
返回false,触发了对RaiseLastOSError
的调用,这表明最后一个错误代码是59:
System Error. Code: 59. An unexpected network error occurred
我正在全力以赴,试图找出如何收到这样的错误消息:即使出现网络问题,我也看不到任何SHGetFolderLocation
受其影响的原因。 / p>
有什么建议吗?
答案 0 :(得分:2)
SHGetFolderLocation()
和SHGetPathfromIDList()
不会通过GetLastError()
报告错误代码,因此在这种情况下您不能使用RaiseLastOSError()
。
SHGetFolderLocation()
返回一个HRESULT
值。您可以将该值传递给RTL的OleCheck()
函数,如果HRESULT
值表示错误,则会引发异常。
不幸的是,SHGetPathfromIDList()
根本不报告错误代码,因此,如果您想引发异常,则如果失败,则必须手动引发自己的异常。
除非CoTaskMemFree()
返回SHGetFolderLocation()
,否则您不应调用S_OK
,因为这是将pidl
更新为指向已分配内存的唯一条件。任何其他返回值都会将pidl
指针设置为nil
。
尝试一下:
OleCheck(SHGetFolderLocation(0, CLSID, 0, 0, pidl));
try
if not SHGetPathFromIDList(pidl, Path) then
raise Exception.Create('Cannot get filesystem path from PIDL');
Result := string(Path);
finally
CoTaskMemFree(pidl);
end;
只需使用SHGetFolderPath()
即可大大简化:
OleCheck(SHGetFolderPath(0, CSIDL, 0, SHGFP_TYPE_CURRENT, Path));