NSIS WriteINISTr Unicode

Saya mencoba membuat penginstal NSIS untuk aplikasi yang saya tulis.

Penginstal mengambil sejumlah detail pengguna dan menuliskannya ke dalam file INI. Masalah yang saya alami saat ini adalah file INI yang dibuat adalah ASCII. Ini berarti jika pengguna memasukkan sesuatu yang bersifat Unicode atau dari bahasa yang tidak didukung, saya mendapatkan ???? di dalam file ini.

Menggunakan NSIS bagaimana cara menulis file Unicode INI?

Pembaruan 1: Oke, jadi setelah menyadari ada versi baru NSIS (v3.0a) yang memiliki lebih banyak opsi untuk Unicode, saya pikir saya akan menginstal ini untuk melihat apakah itu berfungsi.

Kode aplikasi sebelumnya sepenuhnya kompatibel dan exe dibuat, namun, masalahnya masih tetap bahwa WriteINIStr tidak menulis unicode.


person Matt Seymour    schedule 03.07.2013    source sumber


Jawaban (2)


Jika Anda menggunakan rilis stabil terbaru 2.46, NSIS tidak mendukung unicode dan Anda harus membuat sendiri file .ini melalui FileOpen / FileWrite / FileClose dan mengonversi teks melalui plugin sistem.

Ada cabang unicode yang telah lama ditunggu-tunggu yang sedang dibuat sejak 2009 dan saya tidak menyadari bahwa v 3.0a0 baru saja dirilis dan tersedia di situs download. (Sampai saat itu Anda perlu memeriksa kode dan membuat binari sendiri).

Anda harus mencobanya.

Sunting: Saya telah membuat skrip kecil untuk mendemonstrasikan cara menulis file teks UTF-16le "dengan tangan" dengan NSIS 2.46, Anda dapat mencobanya jika string Anda dengan karakter "eksotis" dari kotak teks adalah ditulis dengan benar ke dalam file tes

!include LogicLib.nsh
Name "unicode246"
OutFile unicode246.exe
ShowInstDetails show

Section

    StrCpy $1 "héhé © reçu" ;some "exotic" french chars
    StrLen $2 $1

    System::Call "*(&w${NSIS_MAX_STRLEN} r1)i.s"    ;allocate a buffer and write in wide char
    Pop $0  ;get the buffer address

    FileOpen $9 $EXEDIR\test.txt w ;Opens a file for writing

    ;write UTF-16LE BOM
    FileWriteByte $9 "255"
    FileWriteByte $9 "254"

    ;compute the buffer byte size
    IntOp $2 $2 * 2
    IntOp $2 $2 - 1

    ;loop on the bytes
    ${forEach} $1 0 $2 + 1
        IntOp $3 $0 + $1    ;compute the address of the nth byte

        System::Call "*$3(&i1 .r4)" ;read the byte in $4
        DetailPrint "address $0 + $1 = $3 = $4"
        FileWriteByte $9 $4
    ${next}
    FileClose $9
    System::Free $0 ;free buffer
SectionEnd
person Seki    schedule 03.07.2013
comment
Saya baru saja mencoba cabang unicode tetapi ternyata WriteINIStr masih hanya melakukan ASCII (menyebalkan sekali) Saya akan segera mencoba saran Anda. - person Matt Seymour; 03.07.2013
comment
apakah Anda secara eksplisit mengaktifkan unicode? jika alfa 3.0 tidak berfungsi untuk Anda, ada juga garpu unicode 2.46 dari nsis. - person idleberg; 03.07.2013
comment
Saya membuat prototipe untuk membuat file utf16-le dari nsis 2.46, semoga membantu - person Seki; 03.07.2013
comment
Terima kasih @seki, saya akan memberi tahu Anda bagaimana hubungan saya. - person Matt Seymour; 03.07.2013
comment
@idleberg Saya melihat ke dalam garpu unicode, tetapi WriteINIStr masih hanya dalam ascii. - person Matt Seymour; 03.07.2013
comment
@MattWritesCode: btw, apakah Anda mencoba jika Anda menulis sendiri file .ini dengan karakter unicode (misalnya dengan Scintilla / UltraEdit / apa pun) jika berfungsi seperti yang diharapkan oleh program yang membaca file .ini? - person Seki; 03.07.2013

WriteINIStr memanggil WritePrivateProfileString dan meskipun versi Unicode (WritePrivateProfileStringW) juga menulis sebagai ansi secara default, ia akan menulis sebagai UTF16LE jika file .ini memiliki BOM.

Jadi Anda dapat menggunakan fungsi dasar NSIS File* untuk melihat apakah ada BOM, jika tidak Anda dapat menambahkannya sebelum menggunakan perintah ini...

person Anders    schedule 03.07.2013