Не удается создать папку, используя 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;
Какой путь используется:
Не зря я решил создать пути и информацию в папке Local 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 ответ
Использование
var
P: array [0 .. max_path] of Char;
begin
SHGetFolderPath(0, CSIDL_APPDATA, 0, 0, @P[0]);
end;
чтобы получить каталог Appdata. Если функция принудительных каталогов не работает, используйте
SysErrorMessage(getlasterror)
чтобы получить осмысленное сообщение об ошибке.