支持NSIS的DLL扩展编程通用语法结构
#include <windows.h> #include <stdio.h> #define FORCE_SWITCH "/FORCE" #define NOSAFE_SWITCH "/NOSAFE" #define MAX_STRLEN 1024 /* NSIS stack structure */ typedef struct _stack_t { struct _stack_t *next; char text[MAX_STRLEN]; } stack_t; stack_t **g_stacktop; char *g_variables; unsigned int g_stringsize; HINSTANCE g_hInstance; #define EXDLL_INIT() \ { \ g_stacktop = stacktop; \ g_variables = variables; \ g_stringsize = string_size; \ } //Function: Removes the element from the top of the NSIS stack and puts it in the buffer int popstring(char *str) { stack_t *th; if (!g_stacktop || !*g_stacktop) return 1; th=(*g_stacktop); lstrcpy(str,th->text); *g_stacktop = th->next; GlobalFree((HGLOBAL)th); return 0; } //Function: Adds an element to the top of the NSIS stack void pushstring(const char *str) { stack_t *th; if (!g_stacktop) return; th=(stack_t*)GlobalAlloc(GPTR, sizeof(stack_t)+g_stringsize); lstrcpyn(th->text,str,g_stringsize); th->next=*g_stacktop; *g_stacktop=th; } void __declspec(dllexport) Decrypt(HWND hwndParent, int string_size, char *variables, stack_t **stacktop) { char string_to_decode [MAX_STRLEN]=""; char string_decoded [MAX_STRLEN]=""; char length [16]=""; EXDLL_INIT(); { popstring (string_to_decode); popstring (length); pushstring (string_decoded); } } BOOL WINAPI DllMain(HANDLE hInst, ULONG ul_reason_for_call, LPVOID lpReserved) { g_hInstance=hInst; return TRUE; }
由于电脑win10 ,NSIS采用UNICODE格式编码,而上面的示例和NSIS所提供的plugin-common.h
中使用的都是char
,而不是wchar_t
因而导致导入传到DLL的参数只能接收到一个字符(FUCK排查了好久,感谢老同事的帮忙)
解决办法:
- 将插件代码中的
char
改成wchar_t
。 - 在nsi脚本中加入
Unicode True
。(如果想采用Unicode,而脚本采用了多字节) - 需要将生成的插件dll放到nsis目录下的
Plugins\x86-unicode
子目录中。(如果脚本采用了Unicode,可能不存在此子目录,视情况而定)
ANSI:最早的时候计算机ASCII码只能表示256个符号(含控制符号),这个字符集表示英文字母足够,其中,我们键盘上可见的符号的编码范围是从32到126(大小写英文字母、数字、英文符号等)。但表示汉字、日语、韩语就不太够用了,汉字常用字有3000多个。
但是中国人也要用电脑打字,于是,中国人就研究出来了最早的中文字符集GB2312(GBK就是后来的扩展),GB2312的做法是,把ASC码取值范围的128~255这个区间挪用了一下,用两个ASC码表示一个汉字,这样可用的编码范围用十六进制表示就是0x8080到0xFFFF,这大概能表示一万多个符号,足够了。[注:实际没用那么多,GBK的范围是8140-FEFE]
那个时候,计算机技术还不发达,各个国家搞自己的,比如台湾,也另搞了一套,叫BIG5(俗称:大五码),跟大陆的也不太一样,但方法是类似的,都是用0x80到0xFF这个区间。
然后日语(有编码JIS)、韩语等等也各搞一套。
这些国家的编码区间都是重叠的,但同一个汉字(比如有一些汉字同时存在于简体、繁体、日语汉字中)有不同的编码,很混乱是不是?但也凑合用了。编码不同导致了很多麻烦,比如一个网页,如果你不知道它是什么编码的,那么你可能很难确定它显示的是什么,一个字符可能是大陆简体/台湾繁体/日本汉字,但又完全是不同的几个字。所以如果用一些很老的软件,可能会听说有中文版/日文版之类的,对应的版本只能在对应的系统上运行。
后来,这个对操作系统的开发实在是太困难了,因为这意味着不同语言的版本,都要重新编码。于是发明了Unicode。Unicode这个东西,就是要把地球上所有的语言的符号,都用统一的字符集来表示,一个编码真正做到了唯一。
UTF-8
互联网的普及,强烈要求出现一种统一的编码方式。UTF-8 就是在互联网上使用最广的一种 Unicode 的实现方式。其他实现方式还包括 UTF-16(字符用两个字节或四个字节表示)和 UTF-32(字符用四个字节表示),不过在互联网上基本不用。重复一遍,这里的关系是,UTF-8 是 Unicode 的实现方式之一。
UTF-8 最大的一个特点,就是它是一种变长的编码方式。它可以使用1~4个字节表示一个符号,根据不同的符号而变化字节长度。
UTF-8 的编码规则很简单,只有二条:
1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。