WritePrivateProfileString - est imprévisible

Sep 19 2020

Nous utilisons un outil qui utilise en interne le simple appel Win-Api WritePrivateProfileString.

Je connais le drapeau de définition UNICODE à mapper vers WritePrivateProfileString**A**ouWritePrivateProfileString**W**

J'écris quelque chose dans le fichier INI, ce fichier n'existe pas auparavant.

Et il se comporte différemment sur certains systèmes. Pourquoi?

Par exemple: un caractère "§" qui est A7 (hex) en ASCI, est parfois écrit au format Unicode C2 A7 (hex). mais seulement sur certains systèmes, et je ne sais pas POURQUOI?! Quelle est la condition système pour écrire ANSI ou UNICODE?

J'essayais de créer le fichier en premier, avant d'écrire dessus et j'ai même essayé de définir le format, en ajoutant déjà quelques caractères, car je pensais l' WritePrivateProfileStringutiliser en isTextUnicodeinterne, mais aucune chance ici.

Quelqu'un comprend-il cette documentation API de la bonne manière:
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringa

Si le fichier a été créé à l'aide de caractères Unicode, la fonction écrit des caractères Unicode dans le fichier. Sinon, la fonction écrit des caractères ANSI.

Je ne peux pas vraiment accepter cette documentation ici. Je sais que je dois me tromper ici d'une manière ou d'une autre ;-) Ou comment le faire correctement?

Tout ce que nous voulons, c'est écrire dans N'IMPORTE QUEL cas sur N'IMPORTE QUEL système, simplement ANSI dans le fichier INI. (Je ne peux pas le changer en méthode WritePrivateProfileString**A**car nous utilisons un outil qui utilise simplement la WritePrivateProfileStringfonction en interne.) Quoi qu'il en soit, cela fonctionne pour 90% des PC là-bas correctement, mais sur certains, nous avons encore des lettres unicode dans le fichier INI .

Je sais aussi que l'ASCI n'est pas à la pointe de la technologie, mais nous effectuons un calcul CRC de ces valeurs INI et «A7» n'est pas «C2 A7», ce qui conduit à un calcul erroné, c'est pourquoi nous besoin d'un format ASCII simple.

Merci pour toute aide.

Réponses

2 Tony Sep 21 2020 at 16:52

J'ai trouvé la cause principale:
https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows

En avril 2018, avec l'insider build 17035 (build nominal 17134) pour Windows 10, une case à cocher «Beta: Use Unicode UTF-8 for Worldwide language support» est apparue pour définir la page de codes de paramètres régionaux sur UTF-8. [A] Cela permet d'appeler Fonctions "étroites", y compris fopen et SetWindowTextA, avec des chaînes UTF-8. En mai 2019, Microsoft a ajouté la possibilité pour un programme de définir la page de codes sur UTF-8 elle-même et a commencé à recommander que tous les logiciels le fassent et utilisent exclusivement UTF-8.

Ce paramètre a été activé sur certains systèmes et il était responsable de la modification de mon code ANSI attendu en UNICODE dans le fichier INI.

Oui, je comprends que nous devons aller dans la direction UNICODE à l'avenir. Mais maintenant aussi Microsoft nous pousse dans cette direction, ce qui n'est pas mal, mais je n'étais pas au courant de ce paramètre ou de cette stratégie auparavant.

@IInspectable: oui vous avez raison 0xA7 n'est pas ASCII mais ANSI (ou ASCII-8, Extended ASCII) je l'avais mélangé, merci.

i486 Sep 21 2020 at 18:33
  1. Utilisez toujours la WritePrivateProfileStringWversion.

     [DllImport("kernel32.dll", CharSet = CharSet.Unicode, SetLastError = true,
     EntryPoint = "WritePrivateProfileStringW")]
     [return: MarshalAs(UnmanagedType.Bool)]
     public static extern bool WritePrivateProfileString(string lpAppName, string lpKeyName, string lpString, string lpFileName);
    
  2. Lorsque les fichiers INI n'existent pas, créez-les avec un marqueur de fichier Unicode (deux premiers octets FF FE). De cette façon, toutes les chaînes sont stockées sous Unicode. Pour créer un fichier ini vierge, vous pouvez utiliser ceci:

     File.WriteAllText(ini_file_path, "; Your comment\r\n", Encoding.Unicode);
    

Une ligne vide / commentaire au début est recommandée. Écrivez au moins "\r\n".