WritePrivateProfileString: è imprevedibile
Stiamo utilizzando uno strumento che utilizza internamente la semplice chiamata Win-Api WritePrivateProfileString.
Sono a conoscenza del flag di definizione UNICODE da mappare su WritePrivateProfileString**A**oWritePrivateProfileString**W**
Sto scrivendo qualcosa nel file INI, quel file non esiste prima.
E si comporta in modo diverso su alcuni sistemi. Perché?
Ad esempio: un carattere "§" che è A7 (esadecimale) in ASCI, a volte è scritto come formato Unicode C2 A7 (esadecimale). ma solo su alcuni sistemi, e non so PERCHÉ ?! Qual è la condizione di sistema per scrivere ANSI o UNICODE?
Stavo cercando di creare il file prima, prima di scriverlo e ho anche provato a definire il formato, aggiungendo già alcuni caratteri, perché pensavo che lo WritePrivateProfileStringusasse isTextUnicodeinternamente, ma qui nessuna possibilità.
Qualcuno comprende questa documentazione API nel modo giusto:
https://docs.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-writeprivateprofilestringa
Se il file è stato creato utilizzando caratteri Unicode, la funzione scrive caratteri Unicode nel file. In caso contrario, la funzione scrive caratteri ANSI.
Non posso davvero accettare questa documentazione qui. So che in qualche modo devo sbagliarmi qui ;-) O come farlo giusto?
Tutto quello che vogliamo è scrivere in QUALSIASI caso su QUALSIASI sistema semplicemente ANSI nel file INI. (Non posso cambiarlo con il metodo WritePrivateProfileString**A**perché stiamo usando uno strumento che usa solo la WritePrivateProfileStringfunzione internamente.) Comunque, funziona correttamente per il 90% dei PC là fuori, ma su alcuni abbiamo ancora lettere Unicode nel file INI .
So anche che ASCI non è all'avanguardia, ma stiamo eseguendo alcuni calcoli CRC di quei valori INI e "A7" non è "C2 A7", il che porta a un calcolo errato, questo è il motivo per cui noi bisogno di un semplice formato ASCII.
Grazie per tutto l'aiuto.
Risposte
Ho trovato la causa principale:
https://en.wikipedia.org/wiki/Unicode_in_Microsoft_Windows
Nell'aprile 2018 con la build interna 17035 (build nominale 17134) per Windows 10, è apparsa una casella di controllo "Beta: usa Unicode UTF-8 per il supporto della lingua in tutto il mondo" per impostare la codepage delle impostazioni locali su UTF-8. [A] Ciò consente di chiamare funzioni "narrow", inclusi fopen e SetWindowTextA, con stringhe UTF-8. Nel maggio 2019 Microsoft ha aggiunto la possibilità per un programma di impostare la codepage su UTF-8 stesso e ha iniziato a raccomandare che tutto il software lo faccia e utilizzi esclusivamente UTF-8.
Questa impostazione è stata attivata su alcuni sistemi ed era responsabile della modifica del codice ANSI previsto in UNICODE nel file INI.
Sì, capisco che in futuro dobbiamo andare nella direzione di UNICODE. Ma ora anche Microsoft ci sta spingendo in questa direzione, il che non è male, ma prima non ero a conoscenza di questa impostazione o strategia.
@IInspectable: sì hai ragione 0xA7 non è ASCII ma ANSI (o ASCII-8, ASCII esteso) l'ho confuso, grazie.
Usa sempre la
WritePrivateProfileStringWversione.[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);Quando i file INI non esistono, crearli con un indicatore di file Unicode (primi due byte FF FE). In questo modo tutte le stringhe vengono memorizzate come Unicode. Per creare un file ini vuoto puoi usare questo:
File.WriteAllText(ini_file_path, "; Your comment\r\n", Encoding.Unicode);
Si consiglia una riga vuota / di commento all'inizio. Scrivi almeno "\r\n".