Para poder editar archivos INI u otros datos desde mi aplicación, si se encuentra instalada en Archivos de programa, resulta que tenía que acceder en modo administrador y/o añadir un manifiesto con privilegios de administrador. Podía acceder a las claves del registro HKLM para saber la ubicación de las carpetas del sistema Programfiles o Commonfiles. Pero yo quería guardar archivos de datos de mi programa en la carpeta ProgramData que para eso está.
Para ello utilizaba el componente ComputerInfo de las famosas JVCL, que me cargaba mucho la aplicación. Así que rascando dentro de este componente deduje esta función que me va muy bien para detectar e instalar datos en la carpeta de ProgramData sin necesidad de tener que usar privilegios. La he probado con XE5 y Windows 8 y me funciona bien. Si alguien la quiere mejorar, seguro que lo agradeceremos todos. Bueno ahí va:
Añado la librería Winapi.ShlObj en las uses
Y genero la función:
function Tform1.RutaProgramData: string; var FolderID: PItemIdList; begin FolderID := nil; if Succeeded(SHGetSpecialFolderLocation(0, CSIDL_COMMON_APPDATA, FolderID)) then begin SetLength(result, 260); //->pongo a 260 de ancho y luego la recorto con trim if SHGetPathFromIdList(FolderID, PChar(result)) then //cogo la ruta y la pongo en result result:=trim(result) else result := ''; //-> o ExtractFilePath(ParamStr(0)); end; end;
Luego la llamo desde una varialble string del FormCreate o por ejemplo: showmessage(RutaProgramData);