Windows 什么会导致SHGetFolderLocation返回false,Lasterror设置为59?
我有一个应用程序有时无法获取Windows 什么会导致SHGetFolderLocation返回false,Lasterror设置为59?,windows,delphi,winapi,Windows,Delphi,Winapi,我有一个应用程序有时无法获取AppData文件夹的路径 这种情况似乎只发生在我们的Citrix服务器场上,而不是每个用户,也不是所有时间(我几乎无法复制它) 问题表现在以下方面: SHGetFolderLocation就是这样调用的: Value := SHGetFolderLocation (0, CLSID, 0, 0, pidl); try case Value of S_OK: begin if not ShGetPathfromIDList(
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\u APPDATA
,定义为0x001a
)
根据堆栈跟踪,我们看到,SHGetFolderLocation
返回false,触发对RaiseLastesError
的调用,这表明最后一个错误代码是59:
System Error. Code: 59. An unexpected network error occurred
我绞尽脑汁想弄清楚我是如何收到这样一条错误消息的:即使出现了网络问题,我也看不出有什么理由受到它的影响
有什么建议吗?SHGetFolderLocation()
和SHGetPathfromIDList()
不通过GetLastError()
报告错误代码,因此在这种情况下不能使用RaiseLastError()
SHGetFolderLocation()
返回一个HRESULT
值。您可以将该值传递给RTL的olcheck()
函数,如果HRESULT
值表示错误,该函数将引发异常
不幸的是,shGetPathFromIdleist()
根本不报告错误代码,因此如果要在异常失败时引发异常,则必须手动引发自己的异常
除非SHGetFolderLocation()
返回S_OK
,否则不应调用CoTaskMemFree()
,因为这是将pidl
更新为指向已分配内存的唯一条件。任何其他返回值都会将您的pidl
指针改为nil
试试这个:
olcheck(SHGetFolderLocation(0,CLSID,0,0,pidl));
尝试
如果不是SHGetPathFromIDList(pidl,Path),则
引发异常.Create('无法从PIDL获取文件系统路径');
结果:=字符串(路径);
最后
CoTaskMemFree(pidl);
结束;
只需使用SHGetFolderPath()
即可大大简化:
olcheck(SHGetFolderPath(0,CSIDL,0,SHGFP_TYPE_CURRENT,Path));
为什么您认为SHGetFolderLocation对GetLastError结果有影响?您的值中已经有正确的错误代码,只需调用OleCheck(值)而不是RAISELASTERROR。好问题,谢谢。我会修改代码,看看我得到了什么。别忘了,如果值等于S_FALSE,OleCheck不会引发异常。也许使用OleError而不是OleCheck更好。@DenisAnisimovSHGetFolderLocation()
不会返回S\u FALSE
。而ocheck()
在S_FALSE
上没有出现的原因是,这不是一个错误条件,而是一个成功条件。看起来在Citrix环境中使用了文件夹重定向,可能有时候重定向的位置不可用或太忙?(例如,将AppData重定向到文件服务器就像是对文件服务器的dos攻击)。“如果SHGetFolderLocation()返回的不是S_OK,则不要调用CoTaskMemFree(),因为这是pidl指针具有有意义值的唯一条件。”这实际上是错误的:文档声明“ppidl参数在失败时设置为NULL”()@Stephane谢谢,我已经更新了声明的措辞