10
votes

Trouver un dossier de données d'application "True" de l'utilisateur Windows?

J'ai une application Delphi 6 qui, comme la plupart des applications Windows, lit / écrit des données sur le dossier "Données d'application local" de l'utilisateur. J'utilise le code ci-dessous pour déterminer ce dossier. Jusqu'à présent, ce code a travaillé pour la plupart de mes utilisateurs. J'ai rencontré un utilisateur dont les données d'application locales ne figurent pas dans le dossier attendu:

// Function to get the app data special folder.
function GetAppdataFolder: string;
begin
   Result := GetSpecialFolderLocation(CSIDL_APPDATA);
end;


2 commentaires

@Sertacakyuz - Il s'est avéré que la cause réelle du problème était que l'utilisateur devait installer mon programme avec des droits d'administration, ce qui ne se produit pas sur la plupart des systèmes de l'utilisateur. Pour être juste pour ceux qui avaient déjà répondu au poste d'origine, j'ai réviendais le poste à la forme originale et j'ai créé un nouveau poste pour la nouvelle question: Stackoverflow. com / questions / 12772615 / ...


Où est GetSpecialFolderLocation? (Quelle unité dois-je ajouter à ma clause utilisée?)


3 Réponses :


5
votes

Vous pouvez utiliser ceci (un wrapper). Vous devrez ajouter Shlapi à votre clause utilisée. Passez-le csidl_appdata comme votre échantillon ci-dessus fait. Pour une liste des différentes valeurs CSIDL _ , reportez-vous à la section page MSDN ici xxx

Si vous prenez en charge plus tôt de Windows (XP et ci-dessous), lequel votre texte apparaît est le cas , vous pouvez utiliser shgetfolderPath à la place: xxx

Si vous ne prenez en charge que Vista et plus haut, vous devez utiliser shgetnonnolderpath à la place, et transmettez-le un connaisfolderid .

En ce qui concerne la question du registre, Windows Vista et 7 sont beaucoup plus restrictifs sur les endroits qu'un utilisateur non administrateur peut écrire à, et l'un des Les endroits qui se produisent est dans HKLM et HKCR. Beaucoup d'articles qui avaient l'habitude d'être dans ces ruches sont maintenant dans HKCU ou sont en miroir là-bas.


4 commentaires

La question n'est-elle pas la question sur laquelle csidl à utiliser plutôt que de la convertir à un chemin? Il me semble que Robert sait déjà comment convertir un CSIDL en un chemin. Ou suis-je la lisant de manière incorrecte?


Je pense que vous le lisez de manière incorrecte. Son texte semble indiquer qu'il ne lit pas le chemin (il présume de l'emplacement), et a donc des problèmes avec un utilisateur sur Win7 où les données sont au mauvais endroit. Il dit qu'il est pas capable d'utiliser la solution qu'il a trouvée parce que c'est de .NET et il utilise Delphi.


J'ai lu le code dans la question comme étant le code qui est actuellement utilisé. Et puis il y a les références à csidl_common_appdata et csidl_local_appdata . Robert demande lequel utiliser. Au moins c'est comme ça que je le lis. Je pense que Robert utilise getSpecialfolderLocation de la bibliothèque Jedi. Je pense que Robert utilise une machine XP et ne reconnaît pas la réorganisation des dossiers de profil que MS fabriquées à Vista. Il pense que les différents chemins indiquent quelque chose de plus que cela.


@Kenwhite. Merci. S'il vous plaît voir ma mise à jour récente dans le message d'origine.



8
votes

Le code .NET Vous connaissez le lien vers Utilisations Environnement.Specialfolder.ApplicationData qui est exactement identique au csidl_appdata . Votre code est donc déjà équivalent au code .NET à laquelle vous liez. Et ceux-ci font tous deux référence au même endroit que folderid_roamingappdata .

Vérifiez la documentation de folderid_roamingAppData . Il dit: xxx

Le "chemin de défaut" est ce que vous verrez sur Vista ou plus tard. Le "chemin hérité" est ce que vous voyez sur XP.

Le comportement différent que vous avez observé n'est rien de plus que la différence attendue entre XP et Vista / 7/8.

sur Ma machine Windows, xxx

évalue à xxx

en d'autres termes, votre code fait déjà la bonne chose. Vous n'avez pas besoin de vous modifier du tout. Continuez à utiliser getSpecialfolderLocation (csidl_appdata) .


Qu'est-ce qui est étrange sur la situation particulière de cet utilisateur est que plusieurs clés de registre normalement trouvées dans HKEY_LOCAL_MACHINE sont en fait situées dans HKEY_CURRENT_USER.

Ce n'est pas rare. Très souvent, les applications configurent les paramètres par défaut dans hklm , puis les copient sur hkcu lorsque l'application est d'abord exécutée. Sans connaître plus de détails sur les paramètres en question, il est difficile de commenter cet aspect de votre question.


6 commentaires

J'ai répondu à la question que vous avez posée. Votre mise à jour est peut-être liée à l'UAC qui n'est pas présente sur XP. Je pense que ce n'est pas juste de changer complètement la question comme celle-ci. Je mets beaucoup d'efforts dans cette réponse. Je pense que vous devriez revenir à la question, accepter la réponse et poser une nouvelle question. Avec beaucoup de détails qui ne sont pas ici.


J'ai retourné mon article sur la forme d'origine avant d'avoir introduit le problème des droits de l'administrateur comme vous l'avez demandé.


C'était juste une simple erreur. Je voulais accepter votre réponse à l'origine. C'est réparé.


@SertaCakyuz - Je vois. J'ai déclenché par inadvertance l'extrait de code lorsque j'ai coupé le texte que j'ai utilisé pour lancer un nouveau fil. Je peux voir comment cela est déroutant. Désolé pour ça. C'est restauré.


@Robert - Donc c'était une erreur .. je suis vraiment désolé de l'avoir pris conscient. Je reprends mon bowvote et je supprimerai tous mes commentaires depuis un moment.


@David: Pour le dossier: nous recevons des rapports d'accident de Vista / 7 ordinateurs où "shgetfolderPath (0, csidl_appdata (0, csidl_appdata, 0, shgfp_type_current, chemin)" renvoie réellement "C: \ utilisateurs \ utilisateurs \ HEFF \ Data" au lieu de "C : \ Utilisateurs \ heff \ appdata \ itinérance ". Nous ne pouvons pas écrire dans ce dossier et notre programme se bloque à cause de cela.



5
votes

Si c'est une question de choix intelligemment entre les dossiers spéciaux CSIDL_APPDATA, CSIDL_COMMON_AppData et CSIDL_LOCAL_APPDATA, quelle est la logique pour le faire?

Oui, c'est juste une question de cela. Votre code fonctionne déjà comme prévu.

csidl_appdata ( folderid_roamingappdata ) est destiné aux données accessibles au compte d'utilisateur actuel du thread appelant (qui peut être impersonnée) sur plusieurs machines (données "itinérantes") .

csidl_local_appdata ( folderid_localappdata ) est destiné aux données accessibles au compte d'utilisateur actuel du thread d'appel sur la machine locale uniquement (données "locales").

csidl_common_appdata ( folderid_programdata ) est destiné aux données accessibles à tout compte d'utilisateur sur la machine locale uniquement (pas "itinérance").


0 commentaires