无法使用 System.SYSUTILS.ForceDirectories 创建文件夹
Cannot create Folder using System.SYSUTILS.ForceDirectories
越来越多的用户抱怨他们不能install/start我的应用程序。
问题是什么:
使用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_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
到目前为止我做了什么:
到目前为止,我无法重现确切的错误。我试图从用户那里取得所有权,但这显示了一个不同的错误。还搞乱了该目录中的特殊权限 - 拒绝 "create folder" 等 - 都无济于事。
在这些情况下我有什么遗漏或我可以做的吗?
非常感谢帮助,非常感谢!
更新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_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
程序试图直接写入 C:\Program Files...(可执行文件的路径),有些用户没有写入权限。
我接受了Andre Ruebel的解决方案,但是评论的每个人都在这件事上教了我一些东西。谢谢大家。
更新4
总结一下。问题确实是提取本地用户路径的方式。对于这个特定用户,注册表项没有任何价值。因此,数据被复制到位于 Program Files 下的安装目录...
长话短说:应用程序数据需要 read/write 用户没有特权的访问权限,因此发生了错误。
再次感谢所有的答案,它们引导我走向正确的方向。
使用
var
P: array [0 .. max_path] of Char;
begin
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, @P[0]);
end;
获取Appdata目录。
如果 forcedirectories 函数失败,请使用
SysErrorMessage(getlasterror)
获取有意义的错误消息。
越来越多的用户抱怨他们不能install/start我的应用程序。
问题是什么:
使用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_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
到目前为止我做了什么: 到目前为止,我无法重现确切的错误。我试图从用户那里取得所有权,但这显示了一个不同的错误。还搞乱了该目录中的特殊权限 - 拒绝 "create folder" 等 - 都无济于事。
在这些情况下我有什么遗漏或我可以做的吗?
非常感谢帮助,非常感谢!
更新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_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
程序试图直接写入 C:\Program Files...(可执行文件的路径),有些用户没有写入权限。
我接受了Andre Ruebel的解决方案,但是评论的每个人都在这件事上教了我一些东西。谢谢大家。
更新4
总结一下。问题确实是提取本地用户路径的方式。对于这个特定用户,注册表项没有任何价值。因此,数据被复制到位于 Program Files 下的安装目录...
长话短说:应用程序数据需要 read/write 用户没有特权的访问权限,因此发生了错误。 再次感谢所有的答案,它们引导我走向正确的方向。
使用
var
P: array [0 .. max_path] of Char;
begin
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, @P[0]);
end;
获取Appdata目录。 如果 forcedirectories 函数失败,请使用
SysErrorMessage(getlasterror)
获取有意义的错误消息。