Archive: NSISList: Simple List Plugin


NSISList: Simple List Plugin
Hello :)

I have created a very simple List plugin, namely NSISList.

Well, I know there already is NSISArray, but find it a bit complex to use.
Also coding myself makes more fun than using existing plugins :D

Currently only one instance (one list at a time) is supported.
And it's not documented yet, although the example should be self-explaining.

Bug reports welcome...

Edit (Afrow UK):
Attachment removed. Download from http://nsis.sourceforge.net/NSISList_plug-in#Download.


Why do we need another plugin as there is NSISArray?


As far I can say, this appears pretty different than nsis array, but even if there's not noticeable difference I prefer to have more than one options.


@LoRd_MuldeR

Call it Alpha as long as it isn't feature complete. ;)


Okay, I have added support for multiple lists. You can now create as many lists as you like. Each list is created with a (unique) name and you can use this name to access the list later. Also the missing "Insert" operation has been added, so you can insert items at a specified position now...

Edit (Afrow UK):
Attachment removed. Download from http://nsis.sourceforge.net/NSISList_plug-in#Download.


Sorry, just found a bug in the "Insert" operation. Inserting with an improper index could cause the installer to crash! Now the index will be clipped to the bounds of the list, so inserting with an invalid index won't cause crash anymore.

See the example for details...


That's an absolutely interesting plugin my Lord ;) and it's getting better as I can see.

When I'll have time, I will try to implement it with
Advanced Uninstall Log, it seems it would eliminate the disadvantage of throwing the list several times.

Nice job whatsoever :)


Thanks for your reply :)

1. Added "Index" command to return the index of an item
2. Added "AllRev" command to push all items onto the stack, in reverse order
3. Moved the includes to a separate file
4. Added a "Torture Test" for NSISList


Added "Load" and "Save" to load/save a list directly from a plain text file.
See the example installer...


Right another update: I re-enabled single instance support. So if you don't want to mess around with several lists, you can simply use the "default" list now. This list is identified with an empty string "", it doesn't need to be created and it cannot be destroyed. The default list will be created implicitly when then plugin is loaded and it will be destroyed automatically when the plugin is unloaded.

See the example installer, as always...


I think it should be feature complete now: Added "Set" (change value of existing item), "Exch" (exchange two items by their indexes) and "Move" (move item by it's index). Also some code clean-up was done. In case no major bugs are discovered, I'd call that one finished. Writing some docs now...


First attempt to create some docs ;)


Final version has been released on the Wiki page:
http://nsis.sourceforge.net/NSISList_plug-in

Have fun :)


Nice job LoRd_MuldeR, and the docs too. Would be somehow possible to decrease the dll size?

edit: sorry, I forgot the obvious :) THANKS!


Originally posted by Red Wine
Would be somehow possible to decrease the dll size?
Nope. The DLL is created with Delphi and internally I use a TStringList to store all the strings. This means I need to include the "Classes" Unit, which contains the TStringList type. I tried to copy and paste the TStringList code to my own file, so I don't need to include the entire "Classes" Unit and all of it's dependencies. But TStringList is derived from TStrings which again is derived from some other Object I cannot remember now. Also a lot of other Types are involved at different locations, which I'd need to copy as well. So in the end I'd end up with a copy of "Classes" in my own file. That makes no sens and it makes the code ugly and hard to maintain. Since TStringList is very powerful and my entire plugin depends on it, I think I'll keep it the way it is. You can of course pack the plugin DLL with UPX to make it smaller. But then your installer might actually become bigger, because "packed" files compress worse...

BTW: Is there any way to overcome the 100 KB upload limit?


[EDIT]

If anybody owns a newer (or older) version of Delphi than mine, that is Delphi 7 Professional, he/she could try to compile my sources and see if that makes the DLL any bigger/smaller. Also Lazarus might be worth a try...

Uhm, Lazarus fails at one of the NSIS API functions :cry:

Error message is "project1.lpr(61,25) Error: Illegal qualifier"

function PopString(): string;
var
th: pstack_t;
begin
if integer(g_stacktop^) <> 0 then begin
th := g_stacktop^;
Result := PChar(@th.text); // <- ERROR HERE !!!
g_stacktop^ := th.next;
GlobalFree(HGLOBAL(th));
end;
end;


Any idea how I could fix this?

This is not my own code, it's from the NSIS plugin example code for Delphi...

Okay!
I guess you may overcome the 100 kb limit if you split your package ;)
I'm testing the examples right now... I'd say you should change the name to Advanced List Plugin to get closer ;)


I just tinkered with the code and I actually made it compile with Lazarus. The resulting DLL was more than 1 MB in size! Either my Lazarus compiler settings are completely wrong or it creates even bigger binaries than Delphi. Also the DLL crashed with my example installer. That most probably is because I modified the API code wrongly...


Splitting a 200 KB file :weird:

I'll keep on an external mirror then ;)


Removed the compiled examples from the download, now it's 61 KB in size ;)
http://nsis.sourceforge.net/NSISList_plug-in#Download


NSISList Plugin (2008-07-16)
This update adds Map support to the NSISList plugin :)

The map is implemented in the header file, using only native List functions.
See the "Examples\NSISList\NSISList_Map.nsi" for info!

http://nsis.sourceforge.net/NSISList_plug-in#Download


Just curious - why do you use Lazarus? Isn't Delphi more "windows native"?


Originally posted by pospec
Just curious - why do you use Lazarus? Isn't Delphi more "windows native"?
I don't use Lazarus ;)

In fact I own a copy of Delphi 7 Professional and I use it for all my projects.
One problem with Delphi is, that it creates huge DLL/EXE files, compared to plain C.
Well, Delphi's standard library is really nice, but it's not "lightweight" at all.

I tried Lazarus in the hope it will produce a smaller DLL, but the opposite was the case!
It produced a file bigger than 1 MB, Delphi's DLL was only ~100 KB in size.

On the one hand, 100 KB still is pretty big for such a simple plugin!
On the other hand, we live in the Mircosoft.NET time now :igor:

Okay, if I strip the Lazarus DLL then it's only 150 KB in size :D
Well, that's still bigger than Delphi's DLL so I'll stick to Delphi for compiling!

Nevertheless the sources for Lanczos are included in the download.
Hopefully somebody can fix them to work...

Having an alternative compiler can never be wrong ;)


Hi LoRd_MuldeR again!

Map implemetation is nice. However, I'd like to have more functions (simillar to List object - e.g. Count, First, Last and so on).

Do you think that you'll add these functionalities or should I DIY?


Another question - documentation reads following:
${List.Unload} (...) This function will unload the NSISList plugin, destroy ALL lists including all of their items and release all memory used by NSISList.

Do I have to call List.Destroy then? It seems that calling List.Unload once for an instance is enough.


Thanks for this plugin, the map support is very useful.

I just have a couple of queries/requests.

Firstly, is there a way I can get this plugin to send error messages to a variable instead of displaying a message box.

Secondly, is there a way I can test to see if a map is already created. I create one in a function that needs to be available in other functions, but if a page is returned to it tries to recreate the map which causes an error box to appear.

If there is a way to do the first thing I guess that would solve the second thing as I could just check the error message after calling create.


Originally posted by pospec
Hi LoRd_MuldeR again!

Map implemetation is nice. However, I'd like to have more functions (simillar to List object - e.g. Count, First, Last and so on).

Do you think that you'll add these functionalities or should I DIY?
A map is an unordered data structure. Elements are referenced via their keys. There is no "first" or "last" element.
Internally a map consists of two (ordered) lists, but you should not rely on that (internal) implementation!

Originally posted by pospec
Another question - documentation reads following:
${List.Unload} (...) This function will unload the NSISList plugin, destroy ALL lists including all of their items and release all memory used by NSISList.

Do I have to call List.Destroy then? It seems that calling List.Unload once for an instance is enough.
Calling it once is sufficient. ALL your lists (and maps) will be gone.


Originally posted by mattm591
Thanks for this plugin, the map support is very useful.

I just have a couple of queries/requests.

Firstly, is there a way I can get this plugin to send error messages to a variable instead of displaying a message box.
This is not implemented. But when using the Plugin properly, you should not encounter any error messages.
The error messages are intended to indicate serious problems to NSIS developers...

Originally posted by mattm591
Thanks for this plugin, the map support is very useful.

Secondly, is there a way I can test to see if a map is already created. I create one in a function that needs to be available in other functions, but if a page is returned to it tries to recreate the map which causes an error box to appear.

If there is a way to do the first thing I guess that would solve the second thing as I could just check the error message after calling create.
No you can't. Make sure you create the map only once!

For example use the .onInit function to create all lists/maps that are referenced on the global scope.
You can also use a global var to check whether the map was already created...

NSISList Unicode
Hello,

I created a new NSISList DLL which works with NSIS Unicode. I needed NSISList it for one of my projects but I saw that it doesn't work with Unicode strings.

The attachment contains the source code and DLL. The project is compiled using Delphi 2007 Professional. I didn't change the Lazarus sources.


Thanks for sharing! Could you add it to the wiki page, too?


If LoRd_MuldeR agrees, I will do that. I'm waiting for a PM reply


The wiki is for everyone, please add it. As long as you don't claim credit for the original work, there's no reason not to.


Originally posted by valentin.istrate
If LoRd_MuldeR agrees, I will do that. I'm waiting for a PM reply
Sure. Thanks for making a Unicode version!

I could not make a Unicode version, because I only own a license for Delphi 7.0, which is a lost case for Unicode support (yeah, there is a WideString type, but almost all VCL classes don't support it, so you'd have to re-write the complete VCL).