无法使用System.SYSUTILS.ForceDirectories创建文件夹



越来越多的用户抱怨他们无法安装/启动我的应用程序。

问题出在哪里:

使用System.SYSUTILS.ForceDirectories(...)构建了一个由4个目录组成的目录结构,这些目录最初并不存在。当应用程序第一次启动时,就会发生这种情况。在某些机器上,这似乎是不可能的,因为ForceDirectories() returns False

我确切地知道错误发生在哪里(以下只是一个代码片段):

if ( not TDirectory.Exists(self.TempInstallPath) ) then
begin
if (System.SYSUTILS.ForceDirectories(self.TempInstallPath)) then
begin
uGlobalFiles.DeleteDirectoryContents(self.TempInstallPath, self.GetLoggingFunc());
if ( not self.copyDatabase(source) ) then
raise TCopyDatabase_Exception.Create('Database could not be copied to: ' + sLineBreak + self.TempInstallPath);
end
else
begin
raise TPathCouldNotBeCreated_Exception.Create('adding a new directory failed with error: ' + sLineBreak + SysErrorMessage(GetLastError)
+ sLineBreak
+ 'destination folder: ' + self.TempInstallPath
+ sLineBreak
+ 'local user folder:' + self.LocaluserPath
+ sLineBreak
+ 'session time stamp:' + self.TimeStamp);
end;
end;

使用哪条路径:

出于充分的理由,我决定在用户的本地AppData文件夹中创建路径和信息。我从注册表中获得值:

HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerShell Folders

到目前为止我做了什么:到现在为止,我无法重现确切的错误。我试图从用户那里获得所有权,但这显示了一个不同的错误。还在该目录中摆弄特殊权限——拒绝"创建文件夹"等——都无济于事。

在这些情况下,我有什么遗漏或可以做的吗?

非常感谢您的帮助,非常感谢!

更新1

现在我得到本地用户文件夹这样做:

function GetShellFolder(CSIDLFolder : integer) : string;
begin
SetLength(Result, MAX_PATH);
SHGetSpecialFolderPath(0, PChar(Result), CSIDLFolder, false);  // (CSIDL_LOCAL_APPDATA -- FOLDERID_LocalAppData)
SetLength(Result, StrLen(PChar(Result)));
if (Result <> '') then
Result  := IncludeTrailingBackslash(Result);
end;

更新2

由于我已经使用了SysErrorMessage(GetLastError),我知道错误消息,它实际上表示没有错误。我还知道(从客户那里)第一个文件夹(要创建的4个文件夹中)是作为隐藏文件夹创建的,其他文件夹根本没有创建。不过,她可以使用上下文菜单创建文件夹。

更新3

UPDATE1中提到的更改解决了错误。由于注册表中未存储任何内容:

HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionExplorerShell Folders

程序试图直接写入C:\program Files。。。(可执行文件的路径),其中一些用户没有写入权限。

我接受了安德烈·鲁贝尔的解决方案,但每个发表评论的人都教会了我一些关于这件事的东西。谢谢大家。

更新4

综上所述。问题实际上在于提取本地用户路径的方式。在这个特定用户的情况下,注册表项没有值。因此,数据被复制到安装目录中,该目录位于Program Files。。。

长话短说:应用程序数据需要读/写访问权限,而用户无权访问,因此发生了错误。再次感谢所有的答案,它们把我带向了正确的方向。

使用

var
P: array [0 .. max_path] of Char;
begin
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, @P[0]);
end;

以获取Appdata目录。如果forcedirectories功能失败,请使用

SysErrorMessage(getlasterror)

以获得有意义的错误消息。

相关内容

  • 没有找到相关文章

最新更新