2016-06-07 216 views
-2

越来越多的用户抱怨说他们无法安装/启动我的应用程序。无法使用System.SYSUTILS.ForceDirectories创建文件夹

是什么问题:

使用System.SYSUTILS.ForceDirectories(...)包括4个目录,不摆在首位存在的目录结构建造。这发生在应用程序第一次启动时。 在某些机器上,这似乎是不可能的,因为​​3210。

我知道究竟在何处发生错误(以下仅仅是一个代码片段):

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 

我做了什么至今: 到目前为止,我无法重现确切的错误。我试图从用户那里获得所有权,但是显示出不同的错误。还要在该目录中设置特殊权限 - 拒绝“创建文件夹”等 - 都无济于事。

有什么我失踪或我可以在这些情况下做?

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

UPDATE1

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

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; 

UPDATE2

既然我已经使用SysErrorMessage(GetLastError函数),我知道了错误信息,这实际上表示没有错误。 我也知道(来自客户)第一个文件夹(创建的4个文件夹之外)被创建为隐藏文件夹,其他文件根本没有创建。不过,她可以使用上下文菜单创建文件夹。

UPDATE3

UPDATE1提到的改变解决了错误。由于没有被存储在注册表中:

HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders 

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

我接受的Andre Ruebel的解决方案,但大家谁评论教我对此事的东西。感谢大家。

UPDATE4

要总括起来。问题确实是本地用户路径被提取的方式。在这个特定用户的情况下,注册表项没有价值。因此,数据被复制到安装目录下,该目录位于Program Files ...

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

+1

不确定这是否相关,但是当打开该注册表项时右边第一个条目(标准)说:“!不要使用此注册表项”“使用SHGetFolderPath或SHGetKnownFolderPath函数” –

+2

这不是如何找到特殊的文件夹位置。使用api函数。 –

+0

谢谢,我总是乐于学习新的东西。你知道,这是最好的遗留代码,我更多的是一个蟒蛇人:) – rocksteady

回答

3

使用

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

得到AppData目录。 如果forcedirectories功能失效,使用

SysErrorMessage(getlasterror) 

得到一个有意义的错误消息。

+0

FWIW,'SHGetFolferPath(0,CSIDL_APPDATA,0,0,P)'也可能工作。 –

+0

我已经做了SysErrorMessage(getlasterror),只需滚动到代码片段的右边。 – rocksteady

+0

我发现[this](http://stackoverflow.com/questions/12771473/finding-a-windows-users-true-application-data-folder)它很好地解释它 – rocksteady