Implement a Hyperlink into an LangString - nsis

Actually im Trying with NSIS standard-libary to implement a Hyperlink into my LangString. But when I "only" write the Link into the LangString it dont get clickable.
I´m using an own .nsh do Build the LangStrings:
!undef LANG
!define LANG = "English"
!LANG_STRING "myTest" "search on google: https://google.com/"
In my nsis Main the Code-Snippet looks like:
!macro LANG_STRING NAME VALUE
LangString "${NAME}" "${LANG_${LANG}}" "${VALUE}"
!macroend
!macro LANG_LOAD lang
!insertmacro MUI_LANGUAGE "${lang}"
!verbose 1
!include "descriptions\${lang}.nsh"
!verbose 4
!undef LANG
!macroend
#Pages(here i build my pages up)
!insertmacro LANG_LOAD "English"
Is there a handling that i can make it possible and when yes where i must implement it.

There is no built-in support for this. NSIS does not try to detect URLs in strings and Windows controls are rather limited in older versions (before XP).
You can fake it with a RichEdit control but there is no built in WM_NOTIFY handler to launch the URL:
System::Call 'KERNEL32::LoadLibrary(t "MsftEdit")' ; 4.1+, Windows XP SP1 and later
FindWindow $9 "#32770" "" $HWNDPARENT
SendMessage $9 ${WM_GETFONT} 0 0 $8
System::Call 'USER32::CreateWindowExW(i ${WS_EX_TRANSPARENT}, w "RICHEDIT50W", p0, i ${DEFAULT_STYLES}|${WS_TABSTOP}|${ES_MULTILINE}|${ES_READONLY}, i 0, i 0, i 300, i 50, p $9, p 0, p 0, p 0)p.s'
Pop $9
SendMessage $9 ${WM_SETFONT} $8 1
!define /math EM_SETTEXTEX ${WM_USER} + 97
System::Call "USER32::SendMessage(p$9,i${EM_SETTEXTEX},*l0,ts)" '{\rtf1{Hello} {\field{\*\fldinst{HYPERLINK "https://stackoverflow.com/questions/tagged/nsis"}}{\fldrslt{SO link}}} {World}}'
It is possible to handle WM_NOTIFY on a nsDialogs page. On built-in pages you need a custom plug-in. You could perhaps ask the author of the ButtonEvent plug-in to add support for this message. If < XP SP1 support is needed you would have to use a older version of the RichEdit control and the EM_AUTOURLDETECT message instead, this means the URL must be visible in the text. The nsDialogs example in NSIS v3 does this.
Another alternative is the SysLink control but it suffers from the same WM_NOTIFY issue and is also limited to Windows XP and later, ComCtlv6 (XPStyle On) and is Unicode only. A different internal implementation exists on Windows 2000 but I'm not sure if it is documented.
The final alternative is the Linker plug-in. I have never tried it myself and you must create several labels if you want to mix links and normal text.

Related

NSIS "Bad text encoding" compilation error from _EndSwitch macro

We've been using NSIS 2.50 for some time now and I'm trying to update to the newest 3.0x version. I'm using Unicode true. I've ran into an issue, which I'm failing to understand. We use a switch for mapping native language names to language IDs, more or less like this:
${Switch} "${LANGNAME}"
${Case} "${LANGFILE_ALBANIAN_NAME}"
StrCpy $0 "${LANG_ALBANIAN}"
${Break}
${Case} "${LANGFILE_ARABIC_NAME}"
StrCpy $0 "${LANG_ARABIC}"
${Break}
; Other cases
${EndSwitch}
The error I'm getting from compilation:
Bad text encoding: C:\Users\me\AppData\Local\Temp\nst9352.tmp:9
!include: error in script: "C:\Users\me\AppData\Local\Temp\nst9352.tmp" on line 9
Error in macro _EndSwitch on macroline 9
The temporary file is apparently created by LogicLib, which then tries to include it. The file really doesn't have any valid Unicode encoding (I'm posting just a snippet from the file):
!insertmacro _== `$2` `Shqip` _LogicLib_Label_433 ""
!insertmacro _== `$2` `???????` _LogicLib_Label_434 ""
!insertmacro _== `$2` `Catal�` _LogicLib_Label_441 ""
The strings with invalid UTF-8 characters seem to be encoded in various ANSI encodings (some seem to be Western European, some Central European etc.), while the question marks are saved as real question marks (0x3F). ${LANGFILE_NLFID_NAME} is defined in language files as native name using the LANGFILE macro from LangFile.nsh. I looked at the language files and they are encoded in UTF-8 BOM and look all right. So it looks like the native name is re-encoded to ANSI or something for ${LANGFILE_NLFID_NAME}?
I'm pretty sure I'm making some stupid mistake, but I can't really figure out what it is.
Looks like a bug, it will be fixed in the next release.
Since you are not using the fall-through Switch feature you can just use Select or If/ElseIf instead:
${Select} "${LANGNAME}"
${Case} "${LANGFILE_ALBANIAN_NAME}"
DetailPrint LANG_ALBANIAN
${Case} "${LANGFILE_ARABIC_NAME}"
DetailPrint LANG_ARABIC
${EndSelect}

How do you call to a specific location within a script from another script?

I am trying to call to a specific function with a script from another script. This is just a text based game I am putting together for my kids to show what programming can do. Its cheesy I know and I am using zenity as well, and yes I am aware there are better things out there but this is what I am using. And I am pretty new to linux so be gentle.
--radiolist --column "Pick" --column "Options" True "North." False "South." False "East." False "West." --width=600 --height=400)
case $walking in
"East.") hallway1 ;;
"West.") intersection ;;
"North.") ./maindeck.sh midHallway;;
"South.") ./maindeck.sh midHallway;;
I want to go to the location midHallway on the maindeck.sh from the original script commanddeck.sh instead of to the starting location.
You could define functions in maindeck.sh and just call them as $1,
midHallway() {
echo "here you are"
}
$1

"Hello World" function without using C printf

UPDATED
It's my second day working with NASM. After thoroughly understanding this
section .programFlow
global _start
_start:
mov edx,len
mov ecx,msg
mov ebx,0x1 ;select STDOUT stream
mov eax,0x4 ;select SYS_WRITE call
int 0x80 ;invoke SYS_WRITE
mov ebx,0x0 ;select EXIT_CODE_0
mov eax,0x1 ;select SYS_EXIT call
int 0x80 ;invoke SYS_EXIT
section .programData
msg: db "Hello World!",0xa
len: equ $ - msg
I wanted to wrap this stuff inside an assembly function. All (or most of) the examples on the web are using extern and calling printf function of C (see code below) - and I don't want that. I want to learn to create a "Hello World" function in assembly without using C printf (or even other external function calls).
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
section .data
message: db "Hello, World", 10, 0
Update
I am practicing assembly for Linux, but since I do not own a Linux box, I am running my assembly code here compile_assembly_online.
Assuming you mean in a Windows command prompt environment, writing to standard out:
Since those provide a virtualized version of the old DOS environment, I believe you can use the old DOS interrupts for it:
int 21, function 9 can output a string: Set AH to 9, DS:DX to a string terminated with a $, and trigger the interrupt.
int 21, function 2 can output a single character, so you could use that repeatedly if you need to output $ (or you don't want Ctrl+C and such checking). AH to 2, DL to the ASCII (I expect) character code, and trigger the interrupt.
int 0x80 won't work in Windows or DOS simply because it's a Linux thing. So that's the first thing that has to change.
In terms of doing it under Windows, at some point you're going to need to call a Windows API function, such as (in this case) WriteConsole(). That's bypassing the C library as desired.
It does use the OS to do the heavy lifting in getting output to the "screen" but that's the same as int 0x80 and is probably required whether it's Linux, Windows or DOS.
If it is genuine DOS, your best place to start is the excellent Ralf Brown's Interrupt List, specifically Int21/Fn9.
I want to point out that Nasm "knows" certain section names - ".text", ".data", and ".bss" (a couple others that you don't need yet). The leading '.' is required, and the names are case sensitive. Using other names, as you've done in your first example, may "work" but may not give you the "attributes" you want. For example, section .programDatais going to be read-only. Since you don't try to write to it this isn't going to do any harm... butsection .data` is supposed to be writable.
Trying to learn asm for Linux without being able to try it out must be difficult. Maybe that online site is enough for you. There's a thing called "andlinux" (I think) that will let you run Linux programs in Windows. Or you could run Linux in a "virtual machine". Or you could carve out a parttion on one of your many spare drives and actually install Linux.
For DOS, there's DosBox... or you could install "real DOS" on one of those extra partitions. From there, you can write "direct to screen" at B800h:xxxx. (one byte for "character" and the next for "color"). If you want to do this "without help from the OS", that may be what you want. In a protected mode OS, forget it. They're protected from US!
Maybe you just want to know how to write a subroutine, in general. We could write a subroutine with "msg" and "len" hard coded into it - not very flexible. Or we could write a subroutine that takes two parameters - either in registers or on the stack. Or we could write a subroutine that expects a zero-terminated string (printf does, sys_write does not) and figure out the length to put in edx. If that's what you need help with, we've gotten distracted talking about int 80h vs int 21h vs WriteFile. You may need to ask again...
EDIT: Okay, a subroutine. The non-obvious part of this is that call puts the return address (the address of the instruction right after the call) on the stack, and ret gets the address to return to off the stack, so we don't want to alter where ss:sp points in between. We can change it, but we need to put it back where it was before we hit the ret.
; purpose: to demonstrate a subroutine
; assemble with: nasm -f bin -o myfile.com myfile.asm
; (for DOS)
; Nasm defaults to 16-bit code in "-f bin" mode
; but it won't hurt to make it clear
bits 16
; this does not "cause" our code to be loaded
; at 100h (256 decimal), but informs Nasm that
; this is where DOS will load a .com file
; (needed to calculate the address of "msg", etc.)
org 100h
; we can put our data after the code
; or we can jump over it
; we do not want to execute it!
; this will cause Nasm to move it after the code
section .data
msg db "Hello, World!", 13, 10, "$"
msg2 db "Goodbye cruel world!", 13, 10, "$"
section .text
; execution starts here
mov dx, msg ; address/offset of msg
call myprint
; "ret" comes back here
; no point in a subroutine if we're only going to do it once
mov dx, msg2
call myprint
; when we get back, do something intelligent
exit:
mov ah. 4Ch ; DOS's exit subfunction
int 21h
; ---------------------------------------
; subroutines go here, after the exit
; we don't want to "fall through" into 'em!
myprint:
; expects: address of a $-terminated string in dx
; returns: nothing
push ax ; don't really need to do this
mov ah, 9 ; DOS's print subfunction
int 21h ; do it
pop ax ; restore caller's ax - and our stack!
ret
; end of subroutine
That's untested, but subject to typos and stupid logic errors, it "should" work. We can make it more complicated - pass the parameter on the stack instead of just in dx. We can provide an example for Linux (same general idea). I suggest taking it in small steps...

Retrieving and displaying the Disk Volume Serial number in NSIS

I am using NSIS(HM NISedit 2.0.3 for editor) for building setup(s) of my application.
I am having a requirement for one of my setups to use the Disk volume serial number(in Hexadecimal format).I also need to display the same in a message box.
Can someone please post me the complete piece of script for getting the Disk Volume serial number displaying it in a Message box?
This page describes how to retrieve the serial number in hex format:
http://nsis.sourceforge.net/Get_Disk_Volume_Serial_Number
So to do what you need include this function in your script:
Function ShowDiskVolumeSerialNumber
!define GetVolumeInformation "Kernel32::GetVolumeInformation(t,t,i,*i,*i,*i,t,i) i"
System::Call '${GetVolumeInformation ("$0",,${NSIS_MAX_STRLEN},.r0,,,,${NSIS_MAX_STRLEN})'
IntFmt $0 "%08X" $0
MessageBox MB_OK $0
FunctionEnd
and call it like this:
StrCpy $0 "C:\\"
Call ShowDiskVolumeSerialNumber
Obviously you can replace the drive letter with whatever you like but ensure it has a double trailing backslash .

80x86 Assembly - Very basic I/O program conversion to Linux from Windows

So my first day of Assembly class, and what do you know? My professor teaches everything on her Windows box, using Windows API calls, etc. which is fine except that I'm running Ubuntu on my box..
Basically, I'm hoping I can find either a workaround or some form of common-grounds in order for me to get my assignments done.
Today, our first programming assignment was to input two integers and output the sum. I followed my professor's code as follows:
.386
.model flat
ExitProcess PROTO NEAR32 stdcall, dwExiteCode:DWORD
include io.h
cr EQU 0dh
lf EQU 0ah
.stack 4096
.data
szPrompt1 BYTE "Enter first number: ", 0
szPrompt2 BYTE "Enter second number: ", 0
zLabel1 BYTE cr, lf, "The sum is "
dwNumber1 DWORD ? ; numbers to be added
dwNumber2 DWORD ?
szString BYTE 40 DUP (?) ; input string for numbers
szSum BYTE 12 DUP (0) ; sum in string form
szNewline BYTE cr,lf,0
.code ; start of main program code
_start:
output szPrompt1 ; prompt for ?rst number
input szString,40 ; read ASCII characters
atod szString ; convert to integer
mov dwNumber1,eax ; store in memory
output szPrompt2 ; repeat for second number
input szString,40
atod szString
mov dwNumber2,eax
mov eax,dwNumber1 ; first number to EAX
add eax,dwNumber2 ; add second number
dtoa szSum,eax ; convert to ASCII characters
output szLabel1 ; output label and results
output szSum
output szNewline
INVOKE ExitProcess,0 ; exit with return code 0
PUBLIC _start ; make entry point public
END ; end of source code
Simple and straightforward enough, yeah? So I turned it in today all linked up from the crappy school computers. And I completely understand all the concepts involved, however, I see 2 main issues here for if I actually want to assemble it on my box:
1) .model flat
2) ExitProcess PROTO NEAR32 stdcall, dwExiteCode:DWORD
And
Both of which I've heard are very Windows-specific. So my question is how can I mutate this code to be able to assemble on Linux?
Sorry If I'm missing any details, but I'll let you know if you need.
Thanks!
Assembly code is, generally speaking, almost always platform specific. Indeed, the very syntax varies between assemblers, even within the same hardware and OS platform!
You'll also probably have problems with that io.h there - I would bet it's making a lot of calls into win32 APIs.
I would recommend simply using wine, along with a copy of whatever assembler your professor is using, to run your professor's examples. If it can run things like Microsoft Office and Steam, it can certainly run some trivial example code :)

Resources