2016-06-07 206 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