You can, when you know the codepage. You can't tell programmatically right now. Some languages use two scripts and have two different language files. The NLF files can be read and the codepage gotten but not the NSH files. It would require that we add something in the NSH files to store the codepage. Maybe a special comment?
Also, no the console is not Unicode by default but outputs to the console through the stdlib will convert them to ANSI before displaying them on the console. Hence, you really want to use the makensisw.exe to see the Unicode characters.
All new scripts for the Unicode only NSIS should be UTF-16LE but we can make makensis.exe read ANSI scripts and 1. convert them to Unicode using the system codepage or 2. provide a parameter that provides the codepage to use to convert to Unicode.
Unicode
573 posts
But there are also scripts that contain strings with different code pages. This is impossible to convert to Unicode.
Yes. I was looking at some just today. They cannot be automatically converted.
There is nothing that can't be done. It's complicated, I'll give you that. But at the very minimum, we could have two string tables - ANSI and Unicode. Those strings that can't be translated could be saved in the ANSI table.
Okay, we are talking about the automation of the conversion of a script into Unicode. There isn't a language that ANSI supports that Unicode cannot which I know you know but someone can misread your statement and think that.
The complication comes in when a script has multiple ANSI codepage strings. The strings themselves do not tell you what codepage they are encoded in. But it may be possible if the script always explicitly uses the $LANGUAGE variable that we can deduce the codepage for conversion in makensis itself. If someone just encodes a string in their native codepage and never says in the script what language it is in, then you really can't do anything except assume things like that it's the system default codepage which can be wrong.
Where as the Unicode to ANSI conversion can be done if the ANSI codepage that supports the language exists, because the script is inherently implied in the Unicode codepoint. So it's much safer to store the scripts as Unicode and then convert them to ANSI if desired and possible.
So just to be clear:
Unicode can encode a superset of the scripts that are supported by ANSI codepages. Each codepoint implies a script. Therefore, for any shared subset of scripts, a Unicode string can be converted to the ANSI codepage encoding.
An ANSI codepage string does not imply any codepage / script. So unless hints are given, we cannot automatically convert to Unicode.
The complication comes in when a script has multiple ANSI codepage strings. The strings themselves do not tell you what codepage they are encoded in. But it may be possible if the script always explicitly uses the $LANGUAGE variable that we can deduce the codepage for conversion in makensis itself. If someone just encodes a string in their native codepage and never says in the script what language it is in, then you really can't do anything except assume things like that it's the system default codepage which can be wrong.
Where as the Unicode to ANSI conversion can be done if the ANSI codepage that supports the language exists, because the script is inherently implied in the Unicode codepoint. So it's much safer to store the scripts as Unicode and then convert them to ANSI if desired and possible.
So just to be clear:
Unicode can encode a superset of the scripts that are supported by ANSI codepages. Each codepoint implies a script. Therefore, for any shared subset of scripts, a Unicode string can be converted to the ANSI codepage encoding.
An ANSI codepage string does not imply any codepage / script. So unless hints are given, we cannot automatically convert to Unicode.
Of course. And so the very minimum we can do is have two tables and have the ANSI table act as it does now. This way, you could still build these old scripts.
Most language files already provide codepage identifiers and some string paths can give you a good enough hint on the codepage for the ANSI string. But as a first very basic solution, two tables is enough.
Most language files already provide codepage identifiers and some string paths can give you a good enough hint on the codepage for the ANSI string. But as a first very basic solution, two tables is enough.
Can you clarify what you mean by two tables? Do you mean that the installer executable will have two tables? Then yes, I think that was the proposal -- two exeheads that accesses two different string tables.
So we have this path:
ANSI script generates:
1. best guess at Unicode string tables.
2. ANSI string tables.
Unicode script generates:
1. Unicode string tables (of course).
2. ANSI string tables. (Multiple languages in the Unicode script will not work if they are meant to be shown together. Not a big surprise because ANSI NSIS can't do this either.)
So we have this path:
ANSI script generates:
1. best guess at Unicode string tables.
2. ANSI string tables.
Unicode script generates:
1. Unicode string tables (of course).
2. ANSI string tables. (Multiple languages in the Unicode script will not work if they are meant to be shown together. Not a big surprise because ANSI NSIS can't do this either.)
I do mean two string tables in the installer executable. But there's no need for two different exeheads/stubs for the job. The ANSI table could simply be empty for installers generated from Unicode scripts.
And all variables will also be in ANSI when an ANSI script is compiled? Otherwise it won't be backwards compatible anyway.
NSIS 2.38
NSIS 2.38 released.
What about Unicode version of NSIS 2.38? 😉
NSIS 2.38 released.
What about Unicode version of NSIS 2.38? 😉
vcoder, I'm on vacation right now. So I won't be on it for a few weeks. 🙂 But I'm sure you can survive in the interim.
Originally posted by jimparkThank you for your response.
vcoder, I'm on vacation right now. So I won't be on it for a few weeks. 🙂 But I'm sure you can survive in the interim.
Have a good vacation! 👍
Bug in FileWrite?
This script work well on ANSI version of NSIS and failed on Unicode version:
ANSI: !define Version "3.4.0.96"
Unicode: !def
This script work well on ANSI version of NSIS and failed on Unicode version:
OutFile "GetVersion.exe"
!define File "Resources.dll"
RequestExecutionLevel user
Function .onInit
GetDllVersion "${File}" $R0 $R1
IntOp $R2 $R0 / 0x00010000
IntOp $R3 $R0 & 0x0000FFFF
IntOp $R4 $R1 / 0x00010000
IntOp $R5 $R1 & 0x0000FFFF
StrCpy $R1 "$R2.$R3.$R4.$R5"
FileOpen $0 "$EXEDIR\Version.txt" w
FileWrite $0 '!define Version "$R1"$\n'
FileClose $0
; MessageBox MB_OK "$R1"
Abort
FunctionEnd
Section
SectionEnd Result file:ANSI: !define Version "3.4.0.96"
Unicode: !def
I'll look into it when I get back from vacation.
I am back from vacation today.
Just released Unicode NSIS 2.38. Fixed vcoder's FileWrite bug as well. And modified the Unicode Mongolian translation to use some characters that do not exist in the ANSI Cyrillic codepage as per request by the OpenOffice project.
Just released Unicode NSIS 2.38. Fixed vcoder's FileWrite bug as well. And modified the Unicode Mongolian translation to use some characters that do not exist in the ANSI Cyrillic codepage as per request by the OpenOffice project.
Just modified the System plugin so that the 't' type specifier acts like a TCHAR*, that is, it will be an ANSI string in the ANSI version of NSIS, but will act as a wide-char string (Unicode string) in the Unicode NSIS.
I introduced an 'm' type specifier to specify an ANSI string. Why 'm'? Well, I can't do 'a' or 's'. So 'm' stands for multi-byte string which ANSI strings can be (although, usually not). Also 'm' looks like an upside down 'w' which stands for wide-char string. 🙂
This means that the conversion from your ANSI NSI script to the Unicode one will be mostly straightforward file conversion unless you were naughty and used the ANSI Windows API specifically, such as MessageBoxA. Some Windows API like GetProcAddress only take ANSI strings, so you should still look at your System calls carefully.
The new version is dubbed 2.38.1. You know where to get it.
I've also added an FAQ page (http://www.scratchpaper.com/unicodensisfaq). If there are any missing topics you'd like to see or there's some erroneous info, please e-mail me.
I introduced an 'm' type specifier to specify an ANSI string. Why 'm'? Well, I can't do 'a' or 's'. So 'm' stands for multi-byte string which ANSI strings can be (although, usually not). Also 'm' looks like an upside down 'w' which stands for wide-char string. 🙂
This means that the conversion from your ANSI NSI script to the Unicode one will be mostly straightforward file conversion unless you were naughty and used the ANSI Windows API specifically, such as MessageBoxA. Some Windows API like GetProcAddress only take ANSI strings, so you should still look at your System calls carefully.
The new version is dubbed 2.38.1. You know where to get it.
I've also added an FAQ page (http://www.scratchpaper.com/unicodensisfaq). If there are any missing topics you'd like to see or there's some erroneous info, please e-mail me.
there was already a feature request for this (http://sourceforge.net/tracker/index...49&atid=373088) would be great if you could submit a patch so the system plugin stays in sync
I didn't know there was already a feature request. The feature request mentions 'z' as the potential type specifier. I did consider that but favored 'm'. Can we settle with 'm'?
BTW, I can't add the modified source to the feature request. I can only submit comments. (Permissions issue?) Or do I have to submit a new patch request?
yeah, go with 'm', and you would have to submit it as a patch, not sure why its not possible to attach files
2.39
We a waiting for Unicode version of NSIS 2.39... 😉
We a waiting for Unicode version of NSIS 2.39... 😉
I'll probably work on it this weekend.
This code work well on ANSI version of NSIS 2.38 and failed on Unicode 2.38.1 version:
!define HAVE_UPX
!ifdef HAVE_UPX
!packhdr tmpexe.tmp "UPX --best -f -q -v --ultra-brute --all-methods --all-filters --compress-icons=0 tmpexe.tmp"
!endif
!define HAVE_UPX
!ifdef HAVE_UPX
!packhdr tmpexe.tmp "UPX --best -f -q -v --ultra-brute --all-methods --all-filters --compress-icons=0 tmpexe.tmp"
!endif
Have you tried packhdr just on its own to see whether it works on Unicode NSIS generated installers?
I tried using a2u.exe on a Windows 2003 Server (SP1, Standard English) it gives me an error: "This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem."
It works fine on XP Pro. (SP2, German).
It works fine on XP Pro. (SP2, German).
You most likely need a newer verison of the C++ redistributables installed: http://www.microsoft.com/downloads/d...DisplayLang=en
(If that doesn't work, try the 2008 one)
(If that doesn't work, try the 2008 one)
Well, if it is because of the redistributable, then it's a silly mistake on my part. I tried rebuilding the project. Can you try downloading a2u.zip and trying the executable inside it again?
As for the Unicode NSIS update, I don't think it's happening this week. I've got way too much other work to do. Hopefully, next week some time.
As for the Unicode NSIS update, I don't think it's happening this week. I've got way too much other work to do. Hopefully, next week some time.
It works now,thanks a lot!
Have you tried packhdr just on its own to see whether it works on Unicode NSIS generated installers?This code I found in ansi-NSIS help file. I converted my ansi script file to unicode by a2u.exe and tried to compile it by unicode-NSIS. Result is error when part of code with UPX is processing.
Okay, so can you try calling UPX itself to see if it works on Unicode NSIS installers? What does the errors say? I just don't have a lot of time to work on Unicode NSIS these days, so you're going to have to help me find the problem a bit.
- Jim
- Jim