如何从NSIS中的RCData资源中读取字符串

如何从NSIS中的RCData资源中读取字符串,nsis,Nsis,我在RCData资源中有一个ANSI字符串,我想将该字符串存储在一个变量中。我已经到了可以获取资源指针和数据大小的地步: ; HMODULE GetModuleHandle(LPCSTR lpModuleName); System::Call "kernel32::GetModuleHandle(i 0) i.r0" ; HRSRC FindResource(HMODULE hModule, LPCSTR lpName, LPCSTR lpType); System::Ca

我在RCData资源中有一个ANSI字符串,我想将该字符串存储在一个变量中。我已经到了可以获取资源指针和数据大小的地步:

; HMODULE GetModuleHandle(LPCSTR lpModuleName);
System::Call "kernel32::GetModuleHandle(i 0) i.r0"

; HRSRC FindResource(HMODULE hModule, LPCSTR lpName, LPCSTR lpType);
System::Call "kernel32::FindResource(i 0, t 'DATA', i 10) i.r1"

; HGLOBAL LoadResource(HMODULE hModule, HRSRC hResInfo);
System::Call "kernel32::LoadResource(i r0, p r1) i.r2"

; LPVOID LockResource(HGLOBAL hResData);
System::Call "kernel32::LockResource(i r2) p.r3"

; DWORD SizeofResource(HMODULE hModule, HRSRC hResInfo);
System::Call "kernel32::SizeofResource(i r0, i r1) i.r4"
现在我不知道该怎么办。我对NSIS很陌生,我认为我的问题是我不太了解变量在NSIS中是如何工作的,以及当一个变量被用作不同类型的系统调用的输出时会发生什么(它有什么值)。(我想)我需要的是将
$4
字节从
$3
中存储的地址复制到一个新的缓冲区,并(可能?)以零结束它。我认为这样的方法可以奏效:

System::Alloc ${NSIS_MAX_STRLEN}
Pop $5
System::Copy /$4 $5 $3
但事实并非如此。经过一些实验后,我得出了这样的结论:

System::Call "*$3(&m$4.r5)"

但是我真的不知道为什么会这样,如果这是处理这个任务的正确方法,为什么上面的复制版本不起作用。

在System::Copy code中,$5包含分配的缓冲区的内存地址(作为字符串,就像有人做了
sprintf(reg5,“%I”,address)
)。如果您选择了
MessageBox mb_ok$5
,您将看到此地址。但是,如果您执行
System::Call user32::MessageBoxA(p0,pr5,p0,i0)
您应该会看到您的字符串

调用代码使用指定的类型转换源和/或目标。这是一种非常有效的方法,并且比复制代码的工作量少

如果我们有一些需要类型转换的东西,而不是在您的特定情况下基本上是一个字节副本,那么这可能更容易可视化

想象一下,如果在C中我们有

typedef struct { int foo, bar; } MyS;
MyS*ptr = allocandfill();
在NSIS中,1美元是ptr的价值:

System::Call '*$1(i.r2,i1234)'
我们经常将其称为系统结构语法,*可以被认为是从$1开始取消引用内存,并根据指定的类型将内存解释为结构

在我这里的具体示例中,我们说第一个成员是int,我不想更改值/源(点),但我希望当前值作为输出存储在r2($2)中。这将基本上执行一个
itoa
,其中$2是目的地。第二个成员是另一个int,我用数字1234覆盖它的当前值。在C语言中,这将执行
ptr->bar=atoi(“1234”)

完成任务的第三种方法是调用Windows函数并让它完成工作:

System::Call `kernel32::lstrcpyA(m.r5,pr3)' ; or lstrcpynA if the string is not zero-terminated or you want to chop it to n characters

太棒了,现在很多事情都变得更有意义了,非常感谢你!)也许还有一个问题-
&m$4.r5
是否将终止“\0”添加到
$5
$3
中的字符串不是以null结尾的。由于变量只包含字符串,而且
$5
中的结果字符串似乎显示正确,我想是的,我只是想确保零不是偶然出现的。顺便说一句,将变量视为
char[NSIS\u MAX\u STRLEN]
是否合理?经过一些实验后,
$5
中的结果似乎真的以null结尾,这很好。:)