Ir al contenido



Foto

Carpetas del sistema: Conocer la ubicación de ProgramData en Windows7/8


  • Por favor identifícate para responder
6 respuestas en este tema

#1 edusalou

edusalou

    Newbie

  • Miembros
  • Pip
  • 6 mensajes
  • LocationSalou

Escrito 06 junio 2014 - 09:49

Como aprendiz, me gustaría aportar mi granito de arena, a esos truquitos de Delphi que tanto echo en falta.
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:



delphi
  1. function Tform1.RutaProgramData: string;
  2. var
  3. FolderID: PItemIdList;
  4. begin
  5.   FolderID := nil;
  6.   if Succeeded(SHGetSpecialFolderLocation(0, CSIDL_COMMON_APPDATA, FolderID)) then
  7.   begin
  8.     SetLength(result, 260); //->pongo a 260 de ancho y luego la recorto con trim
  9.     if SHGetPathFromIdList(FolderID, PChar(result)) then //cogo la ruta y la pongo en result
  10.       result:=trim(result) else result := ''; //-> o ExtractFilePath(ParamStr(0));
  11.   end;
  12. end;



Luego la llamo desde una varialble string del FormCreate o por ejemplo: showmessage(RutaProgramData);

  • 0

#2 ELKurgan

ELKurgan

    Advanced Member

  • Miembro Platino
  • PipPipPip
  • 548 mensajes
  • LocationEspaña

Escrito 07 junio 2014 - 10:47

Gracias por el aporte, amigo

(y)
  • 0

#3 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 07 junio 2014 - 12:42

Añadir que al código le falta:


delphi
  1. uses ShlObj, ShFolder;


Y  queda perfecto.

Saludos.
  • 0

#4 edusalou

edusalou

    Newbie

  • Miembros
  • Pip
  • 6 mensajes
  • LocationSalou

Escrito 11 junio 2014 - 06:49

Puedo cambiar CSIDL_COMMON_APPDATA por todas estas carpetas especiales a las que se puedo acceder:
CSIDL_DESKTOP, CSIDL_INTERNET, CSIDL_PROGRAMS,
  CSIDL_PRINTERS, CSIDL_PERSONAL, CSIDL_FAVORITES,
  CSIDL_STARTUP, CSIDL_RECENT,
  CSIDL_SENDTO, CSIDL_BITBUCKET, CSIDL_STARTMENU,
  CSIDL_DESKTOPDIRECTORY, CSIDL_DRIVES, CSIDL_NETWORK,
  CSIDL_NETHOOD, CSIDL_FONTS, CSIDL_TEMPLATES,
  CSIDL_COMMON_STARTMENU, CSIDL_COMMON_PROGRAMS,
  CSIDL_COMMON_STARTUP, CSIDL_COMMON_DESKTOPDIRECTORY,
  CSIDL_APPDATA, CSIDL_PRINTHOOD,  CSIDL_ALTSTARTUP,
  CSIDL_COMMON_ALTSTARTUP, CSIDL_COMMON_FAVORITES,
  CSIDL_INTERNET_CACHE, CSIDL_COOKIES, CSIDL_HISTORY
Pero no encuentro la carpeta del usuario Appdata\Roaming para guardar ahí mis datos. Supongo que deberé detectarla desde el registro. ¿Hay otra forma de localizarla?
  • 0

#5 edusalou

edusalou

    Newbie

  • Miembros
  • Pip
  • 6 mensajes
  • LocationSalou

Escrito 11 junio 2014 - 07:29

Encontré la carpeta de datos del usuario: sólo cambiar CSIDL_COMMON_APPDATA por CSIDL_APPDATA
Y si la busco por el registro la función sería más o menos así:


delphi
  1. function CarpetaUsuario : TFileName;
  2. begin
  3.   with TRegistry.Create do
  4.   try
  5.     RootKey := HKEY_CURRENT_USER;
  6.     OpenKey('\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Shell folders', false);
  7.     result := ReadString('AppData');
  8.     CloseKey;
  9.   finally
  10.     free;
  11.   end;
  12. end;



Saludos

  • 0

#6 Delphius

Delphius

    Advanced Member

  • Administrador
  • 6.280 mensajes
  • LocationArgentina

Escrito 12 junio 2014 - 06:19

Estuve intrigado por el nombre de esa API. Por la sigla SH llegué a pensar que se trataba de una función de alguna biblioteca de terceros (en donde es habitual utilizar una sigla para nombrar sus unidades, clases y/o procedimientos).
Consulté en MSDN sobre dicha función y mi curiosidad fue el doble.
Aquí pueden ver que se advierte en que no es soportada, y que en un futuro será eliminada:

[SHGetSpecialFolderLocation is not supported and may be altered or unavailable in the future. Instead, use SHGetFolderLocation.]


Entonces me fijo en lo que dice sobre SHGetFolderLocation, y me doy con esto:

Deprecated. Retrieves the path of a folder as an ITEMIDLIST structure.

Marcada como desatendida.

Y más abajo hay una sección de notas que se lee:

Note  As of Windows Vista, this function is merely a wrapper for SHGetKnownFolderIDList. The CSIDL value is translated to its associated KNOWNFOLDERID and SHGetKnownFolderIDList is called. New applications should use the known folder system rather than the older CSIDL system, which is supported only for backward compatibility.

The SHGetFolderLocation, SHGetFolderPath, SHGetSpecialFolderLocation, and SHGetSpecialFolderPath functions are the preferred ways to obtain handles to folders on systems earlier than Windows Vista. Functions such as ExpandEnvironmentStrings that use the environment variable names directly, in the form %VariableName%, may not be reliable.

This function is a superset of SHGetSpecialFolderLocation, included with earlier versions of the Shell.


Se lee entonces que para Vista+ es aconsejable utilizar directamente SHGetKnownFolderIDList ya que SHGetFolderLocation no es más que un "envoltorio" de ésta, y se mantiene por compatibilidad. Nomás. Sólo para entornos Anteriores a Vista es una vía segura y preferible utilizar la API que ha comentado edusalou en su código.

Si es así como dice la documentación, entonces es una pura casualidad de que funcione Windows 8.
La verdad es que no entiendo.

Saludos,
  • 0

#7 escafandra

escafandra

    Advanced Member

  • Moderadores
  • PipPipPip
  • 3.898 mensajes
  • LocationMadrid - España

Escrito 13 junio 2014 - 04:35


Si es así como dice la documentación, entonces es una pura casualidad de que funcione Windows 8.
La verdad es que no entiendo.


Si, delphius, es habitual encontrar esas cosas en M$. Muchas APIs son obsoletas pero siguen funcionando a la perfección  ^o|

Saludos.
  • 0