NSIS 插件开发引发的思考

  支持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排查了好久,感谢老同事的帮忙

解决办法:

  1. 将插件代码中的char改成wchar_t
  2. 在nsi脚本中加入Unicode True。(如果想采用Unicode,而脚本采用了多字节)
  3. 需要将生成的插件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 码。

 

转载于:https://www.cnblogs.com/lizhanzhe/p/11019631.html

猜你喜欢

转载自blog.csdn.net/weixin_34409357/article/details/93199548