Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Multiple entry points (MS Windows)

3 views
Skip to first unread message

Johan Vromans

unread,
Apr 24, 2020, 9:45:03 PM4/24/20
Hi,

I have an application that comes in two forms: as a command line tool, and
as a GUI tool. I want to package these in a single binary, using pp
multi-script feature. So far, so good.

But on Windows it matters whether the program is built with --gui or not.
If I build with --gui invoking the command line version will make all
terminal output disappear. If built without --gui the GUI invokation will
show a nasty terminal window...

Is there an elegant solution?

Oliver Betz

unread,
Apr 25, 2020, 12:30:03 AM4/25/20
Hi Johan,

> I have an application that comes in two forms: as a command line tool, and
> as a GUI tool. I want to package these in a single binary, using pp

which benefit do you expect from packing:

Avoiding "installation", reducing size, or something else?

> multi-script feature. So far, so good.
>
> But on Windows it matters whether the program is built with --gui or not.
> If I build with --gui invoking the command line version will make all
> terminal output disappear. If built without --gui the GUI invokation will
> show a nasty terminal window...

How do you invoke the "plain Perl" versions?

> Is there an elegant solution?


Without par, you could use two separate Perl wrappers.

Oliver

Johan Vromans

unread,
Apr 25, 2020, 2:30:02 AM4/25/20
Hi Oliver,

On Fri, 24 Apr 2020 17:16:37 +0200, Oliver Betz wrote:

> which benefit do you expect from packing:
>
> Avoiding "installation", reducing size, or something else?

Mostly avoiding complexity and unnecessary overhead. The cli version is
fully contained in the gui version.

Reducing installer size. Not 'installed size' since the binary needs to be
copied under two names due to the lack of symlinks.

> How do you invoke the "plain Perl" versions?

Something similar to:

perl cli.pl
wperl gui.pl

> Without par, you could use two separate Perl wrappers.

I'm not sure I understand.

-- Johan

Oliver Betz

unread,
Apr 25, 2020, 3:00:02 AM4/25/20
Hi Johan,

>> which benefit do you expect from packing:
>>
>> Avoiding "installation", reducing size, or something else?
>
> Mostly avoiding complexity and unnecessary overhead. The cli version is
> fully contained in the gui version.

Which kind of complexity and overhead do you mean?

What would be the drawback of using a (subset of a) portable Perl
distribution together with your Perl code, IOW just a bunch of files,
and run it directly?

Oliver

Johan Vromans

unread,
Apr 25, 2020, 3:00:03 AM4/25/20
On Fri, 24 Apr 2020 19:40:58 +0200, Oliver Betz <[email protected]> wrote:

> Which kind of complexity and overhead do you mean?

Having multiple copies of the same code installed may sooner or later cause
confusion.

> What would be the drawback of using a (subset of a) portable Perl
> distribution together with your Perl code, IOW just a bunch of files,
> and run it directly?

It seems non-trivial to put the bunch of files together, distribute
them and have the user put them in the right place(s).
Using pp I can package the runnable code in a single binary, and use
InnoSetup for a point and click install.

Oliver Betz

unread,
Apr 25, 2020, 3:15:02 AM4/25/20
Hi Johan,

>> What would be the drawback of using a (subset of a) portable Perl
>> distribution together with your Perl code, IOW just a bunch of files,
>> and run it directly?
>
> It seems non-trivial to put the bunch of files together, distribute

par is good in doing this selection.

> them and have the user put them in the right place(s).
> Using pp I can package the runnable code in a single binary, and use
> InnoSetup for a point and click install.

If you already use InnoSetup, the user doesn't even have to deal with
the bunch of files.

You know that par under Windows also unpacks Perl plus your code to the
temp directory and runs it there?

InnoSetup can do this unpacking at least as well. Since installation is
decoupled from execution, you can unpack to a folder of your choice,
protected against accidental (or maliciuos) change. And you have no
performance hit at runtime and a clean uninstall (par often doesn't
remove the stuff in the temp directory).

Oliver

Kenneth Ölwing

unread,
Apr 25, 2020, 3:45:02 AM4/25/20

> Reducing installer size. Not 'installed size' since the binary needs to be
> copied under two names due to the lack of symlinks.

What do you mean by 'lack of symlinks'?

Johan Vromans

unread,
Apr 25, 2020, 3:45:03 AM4/25/20
On Fri, 24 Apr 2020 20:21:22 +0200, Kenneth Ölwing <[email protected]>
wrote:

> What do you mean by 'lack of symlinks'?

I must admit I haven't really kept up with Windows lately (and I don't plan
to).

Anyway, the symbolic links are of no real importance to this discussion.

Johan Vromans

unread,
Apr 25, 2020, 4:15:03 AM4/25/20
Hi Oliver,

Thanks for all suggestions.

A bit of background: I am 100% linux user/developer. Since Windows people
want to run some of my applications and since most Windows users are not
capable of installing perl and modules and so on I figured out how to use
PAR (pp) and InnoSetup to produce something that is point and click
installable and runnable. Even though not optimal I'm glad I could get so
far... And users are happy.

On Fri, 24 Apr 2020 20:07:39 +0200, Oliver Betz wrote:

> par is good in doing this selection.

I know (although PAR is still very quiet about missing modules).

> If you already use InnoSetup, the user doesn't even have to deal with
> the bunch of files.

Yes.

> You know that par under Windows also unpacks Perl plus your code to the
> temp directory and runs it there?

Gee, really? You must be joking :)

See e.g. https://johan.vromans.org/extra/perlapp/pres/index.html
and its successor: https://johan.vromans.org/extra/pda2018/pres/index.html

> InnoSetup can do this unpacking at least as well.

Yes, although this would require me a lot of figuring out...

> And you have no performance hit at runtime

I perform an 'initial run' as last step in installation, so the app is
already unpacked and ready to use.

> and a clean uninstall (par often doesn't remove the stuff in the temp directory).

This would be a nice advantage.

Am I the only one trying to do this? Are there other PAR/InnoSetup users
here that have templates and/or examples?

-- Johan

Oliver Betz

unread,
Apr 25, 2020, 7:30:02 AM4/25/20
Hi Johan,

> I, too, have been using pp + innosetup for many years, so that is not the
> problem. BTW my apps are Perl/Wx based.

Seemingly I'm not recognizing the advantage in using pp *in addition* to
InnoSetup.

What is the point to use InnoSetup just to transport *one single exe*?

If you work with the unpacked stuff, you could provide separate Windows
executables calling the Perl interpreter to run the Perl scripts. Such a
wrapper is only tens of KiB. Perl with libs etc, are shared then.

Find the (trivial) sources of such a wrapper at
https://oliverbetz.de/pages/Artikel/Portable-Perl-Applications

Not yet prepared for a gui version but this shouldn't be a problem.

Oliver

Johan Vromans

unread,
Apr 25, 2020, 5:30:03 PM4/25/20
Hi Oliver,

On Sat, 25 Apr 2020 00:07:35 +0200, Oliver Betz wrote:

> Seemingly I'm not recognizing the advantage in using pp *in addition* to
> InnoSetup.
>
> What is the point to use InnoSetup just to transport *one single exe*?

The point is that typical Windows users can download and click a simple tool
that behaves like tools they are aquainted to and makes sure that my
application gets installed correctly. This doesn't imply InnoSetup with a
single, packaged binary but it works.

So lets rephrase the question...

I have a windows box with strawberry perl and wxwidgets and everything. I
can type "wperl myscript.pl" and it runs. Fine.

The end user needs an icon on the desktop that runs the program.

How would *you* do it? I do like your portable perl applications approach
but unless I missed something essential it still seems requires several
manual steps, like assembling the necessary sources (you said par could
be used for that) and building the installer.

Also, is there any protection against users modifying files after unpacking?

Interested,
Johan

Oliver Betz

unread,
Apr 25, 2020, 7:15:02 PM4/25/20
Hi Johan,

[...]

> I have a windows box with strawberry perl and wxwidgets and everything. I
> can type "wperl myscript.pl" and it runs. Fine.
>
> The end user needs an icon on the desktop that runs the program.
>
> How would *you* do it? I do like your portable perl applications approach
> but unless I missed something essential it still seems requires several
> manual steps, like assembling the necessary sources (you said par could
> be used for that) and building the installer.

Most manual steps are only required initially.

An easy approach is to continue using pp to build the required
environment. Extract it immediately afterwards. Look at my ugly hack
"unpar.cmd" to see one way to do it.

Comparing the pp output to the original Perl environment and sources, I
found that XSLoader.pm has been modified by pp. I reverted this and some
more cosmetic optimizations (removed docs).

You don't need to repeat this after small changes not changing your
dependencies.

For ExifTool, I built a static "Perl environment part" without any
ExifTool code. I merge this static part with the ExifTool sources each
time a new version is released. Creating the installer and the ZIP
archive is then just drag and drop of the ExifTool source archive onto a
cmd file.

I have to admit that I don't yet provide a wperl equivalent since I
didn't yet use any Perl GUI software. Do you want to send me a minimal
Perl GUI test program?

> Also, is there any protection against users modifying files after unpacking?

The user can install the application to the dedicated directories like
%ProgramFiles(x86)%. Elevated rights are needed to write there.

Then, during normal use, he can't write these directories.

Another advantage is that AV software is not frightened as if programs
are run from %temp%. Running payload from %temp% is typical malware
behavior and therefore forbidden on many systems.

Oliver

Johan Vromans

unread,
Apr 25, 2020, 10:15:03 PM4/25/20
Hi Oliver,

On Sat, 25 Apr 2020 12:08:31 +0200, Oliver Betz wrote:

> An easy approach is to continue using pp to build the required
> environment. Extract it immediately afterwards. Look at my ugly hack
> "unpar.cmd" to see one way to do it.

I've uploaded a perl GUI program:
https://www.squirrel.nl/pub/xfer/uploads/3C6TeP1OMnL8q7ciPFkyneaA.exe

It is not exactly a trivial program, but all the application stuff is
within a single folder lib/App/Music/ChordPro .

BTW when running unpar.cmd I get an error message "The syntax of the
command is incorrect" on line

ren %PAR_GLOBAL_TEMP%\inc\script\*. *.pl

Note that unpar.cmd does not extract the Wx libraries.

If you copy/clone https://github.com/ChordPro/chordpro/ and checkout the
'dev' branch you should be able to reproduce the binary:

perl Makefile.PL
gmake all test
(to verify all packages)

cd pp\windows
gmake chordpro.exe
(this will build the command line version)

gmake wxchordpro.exe
(this will build the gui version)

gmake iss
(this will build the installer)

> > Also, is there any protection against users modifying files after
> > unpacking?
>
> The user can install the application to the dedicated directories like
> %ProgramFiles(x86)%. Elevated rights are needed to write there.
>
> Then, during normal use, he can't write these directories.

Hmm. If he can elevate rights during install, he can elevate rights later
to make modifications...

Now I'm not against users modifying application sources, but occasionally
when it comes to finding hard bugs it is good to be 100% sure the user is
running exactly the code I delivered.

Regards,
Johan

Oliver Betz

unread,
Apr 26, 2020, 4:30:04 AM4/26/20
Hi Johan,
this is made with 64 bit Perl. My launcher currently supports only 32
bit Perl because the 64 bit version was even slower running ExifTool.

> It is not exactly a trivial program, but all the application stuff is
> within a single folder lib/App/Music/ChordPro .
>
> BTW when running unpar.cmd I get an error message "The syntax of the
> command is incorrect" on line
>
> ren %PAR_GLOBAL_TEMP%\inc\script\*. *.pl

I see. This was for ExifTool.

> Note that unpar.cmd does not extract the Wx libraries.

It seems that unpar.cmd can't be used with your project.

I'll have a look at it tomorrow and report my findings.

Oliver

Oliver Betz

unread,
Apr 27, 2020, 12:00:04 AM4/27/20
Hi Johan,
I managed to run this application from the pp created archive contents
after applying a few modifications you might want to revise:

In wxchordpro.pl, I replaced lines 10..12 with a simple static @INC
addition. I didn't investigate why FindBin doesn't work but I wonder why
there is a reference to "$FindBin::Bin/../CPAN".

In ChordPro.pm, I commented "use lib ( grep { defined }
getresource("CPAN") );"

I have to admit that I don't know what "getresource" does but for the pp
mangled package, this reference isn't needed.

I needed to add Tie::Hash::NamedCapture from Strawberry Perl. Don't know
how this works in the pp exe.

After adding perl.exe from 64 bit Strawberry Perl, I ran "perl
wxchordpro.pl" and the application started. I made no further tests.

Please note that I got an "Use of uninitialized value $cfglib in -d at
\inc\lib/App/Music/ChordPro/Wx/Main.pm line 131." error.

If you want to use my wrapper with 64 Bit Perl, you need to compile it
yourself. If you switch to 32 bit Perl, I can support you with special
versions (as I did with ExifTool).

OTOH, perl wxchordpro.pl called from a cmd file works fine. I mainly
provided my wrapper for 100% compatible replacements of pp packed exe files.

Oliver

Johan Vromans

unread,
Apr 27, 2020, 5:15:03 AM4/27/20
On Sun, 26 Apr 2020 17:57:23 +0200, Oliver Betz <[email protected]> wrote:

> it was not so difficult as I thought initially so I compiled a 64 bit
> wrapper including the icon:

Great!

I unpacked the zip and tried to run.

First problem: the .exe files are not executable:

H:\cp> wxchordpro_console.exe
Access is denied

So I changed all .exe to executable.

H:\cp> wxchordpro_console.exe
Failed to load Perl DLL "perl530.dll" code 5

Changed all DLLs to executable, too.

H:\cp> wxchordpro_console.exe
Can't open perl script "H:\cp\wxchordpro_console.pl": No such file or directory

Copied wxchordpro.pl as wxchordpro_console.pl.

I needed a couple of small fixes due to the fact that now we are no longer
running as pp-packaged. This means

- the 'res' directory now needs to be under lib\App\Music\ChordPro
(where it originally is -- it was moved for pp)
- some information is read from module PODs, so PODs must not be stripped.

The above changes also fix the $cfglib error.

While looking at the (modified) source: what is the purpose of

unshift @INC, 'C:\temp\Coordpro_temp\x\inc\lib';

By moving the scripts to a subdirectory scripts, and run as

perl script/wxchordpro.pl

The FindBin stuff also works correctly. In other words, no changes are required
to any of the original sources. (A could be expected!)

Summarizing the workflow becomes:

1. build the application (perl Makefile.PL; make all test).
2. application sources for packaging can be found in blib.
3. construct the perl environment. pp can be helpful with this.
4. create the native wrapper.

Once this has been done:

5. copy the application sources and perl environment to a work directory
6. have InnoSetup package this work directory

Can you pass me the wrapper source and innosetup file?

Nice work,
Johan

Oliver Betz

unread,
Apr 27, 2020, 6:30:03 AM4/27/20
Hi Johan,

> I unpacked the zip and tried to run.
>
> First problem: the .exe files are not executable:

Are you running under real Windows or Wine? This doesn't sound like a
Windows issue.

[...]

> While looking at the (modified) source: what is the purpose of
>
> unshift @INC, 'C:\temp\Coordpro_temp\x\inc\lib';

sorry, I packed the wrong file into the archive. Delete the whole BEGIN
block, Perl automatically adds the lib subdirectory to @INC (if it exists).

Just for the case this doesn't work anymore some day, use something like
this in a BEGIN block:
unshift @INC, ($0 =~ /(.*)[\\\/]/) ? "$1/lib" : './lib';

[...]

> Can you pass me the wrapper source and innosetup file?

There is no InnoSetup file.

The wrapper code is on my web site *) in ppl.zip but configured for
ExifTool. Change pathreplace[] and dllsearch[] to your needs and
"#define ARGS_ADDED 1".

My "standard makefile" is too weird (complex and specific) to be
published. I compiled with -Wall -Wstrict-prototypes -O2 -s
-mms-bitfields -fwrapv $(UNICODE) -mwindows

https://www.mingw.org/wiki/ms_resource_compiler might help to get the
resources built and linked.

Contact me off-list if you need support.

Oliver

*) https://oliverbetz.de/pages/Artikel/Portable-Perl-Applications

Johan Vromans

unread,
Apr 27, 2020, 7:00:03 AM4/27/20
On Sun, 26 Apr 2020 23:16:57 +0200, Oliver Betz <[email protected]> wrote:

> Are you running under real Windows or Wine? This doesn't sound like a
> Windows issue.

I've unzipped the files under Linux on a disk shared with Windows.
On Linux, files like perl.exe and perl530.dll have permissions 0664
(rw-r--r--).

When I try to execute this file under Windows from the share, I get Access
denied. When inspecting the file properties, it says (under Security) only
read access.

When I change the permissions (under Linux) to 0755 (rwxr-xr-x) I can
execute the file under Windows. Inspecting the file properties, it
says (under Security) read & execute access.

No big deal.

> > Can you pass me the wrapper source and innosetup file?
>
> There is no InnoSetup file.
>
> The wrapper code is on my web site *) in ppl.zip but configured for
> ExifTool. Change pathreplace[] and dllsearch[] to your needs and
> "#define ARGS_ADDED 1".

Ok.

> https://www.mingw.org/wiki/ms_resource_compiler might help to get the
> resources built and linked.

I'm not aware I'm using resources (other than my own data).

> Contact me off-list if you need support.

Ok, thanks.
0 new messages