ActiveState Community

Windows

Bundling images and libraries with TclApp

OS: Windows | Product: Tcl Dev Kit | tags: bundle image library tclapp wrap
Question: 

Do you have an easy-to-follow example of how to bundle images and libraries using TclApp?

Answer: 

A question that is frequently asked is how to bundle images and dependent libraries with TclApp, such that the whole application can be distributed as a single .exe on Windows platforms. It's a great question -- it's easy to turn off users with complex installers or applications that bomb because they can't find splash.gif.

Suppose we wanted to make a simple application that displays a pretty picture and generates a UUID (Universally Unique IDentifier). UUIDs aren't terribly useful to humans, but webservers and other programs use them fairly frequently.

First, let's grab a pretty picture. It should be a reasonably standard picture format -- GIF, JPEG, PNG, TIFF, PostScript... Any of these will do. For a full list of supported formats, see the documentation on the Img package for Tk. I'll use a GIF in this example, because it's what I have sitting around. For the purposes of this demo, we'll call the image file mylogo.gif.

The second step is to write our Tcl/Tk source file. I've attached the version I'm using, and we'll take it apart line by line.

package require Tk
package require Tcl
package require uuid


proc MyUUID {} {
	return [::uuid::uuid generate]
}


proc Main {} {
        image create photo foo -file [file join [file dirname [info script]] mylogo.gif]
#        image create photo foo -file "lib/application/Documents and Settings/activetest/Desktop/myapp/aslogo.gif"
        label .l1 -image foo -bd 1 -relief sunken800
        pack .l1 -side top
	label .l2 -text [MyUUID]
	pack .l2 -side bottom
        label .l3 -text [file dirname [info script]]
        pack .l3 -side bottom
}

Main

The first few lines are fairly standard boilerplate:

package require Tk
package require Tcl
package require uuid

These bring in the Tk, Tcl, and uuid libraries respectively. uuid is part of Tcllib, which ships as part of ActiveTcl. If you're not using ActiveTcl, you can get Tcllib from their Sourceforge project page.

proc MyUUID {} {
    return [::uuid::uuid generate]
}

Here we define a procedure that returns a UUID. This code does not have to go in a procedure, of course -- it could be written in-line.

proc Main {} {
    image create photo foo -file [file join [file dirname [info script]] mylogo.gif]
    label .l1 -image foo -bd 1 -relief sunken
    pack .l1 -side top

Next, we define the Main procedure. This isn't strictly necessary to do, but I define a Main procedure so nothing executes without it being called specifically. I find it handy for debugging purposes, but your mileage may vary.

First up in Main is to load the image. We'll call the image foo, for lack of a better name. Notice the file specification -- there is a bit of a song and dance going on there that needs a little explanation. The easiest way to read it is from the inside out. [info script] returns the full pathname of the script. [file dirname] returns the directory name of its argument, and [file join] composes a pathname from its arguments, inserting the appropriate path separator.

So why all the song and dance? When you're packing an image inside your executable, it's not always obvious as to how to find it. One thing you can usually rely on is for [info script] to return the proper path to the script that's running, and from there you can simply chop off the script name and add on the image name, as we have done above. This works for any kind of file.

The label command puts the image on a label, which can be packed into a window. In this case, we're using the toplevel window. Next, we pack the label, so it is visible.

    label .l2 -text [MyUUID]
    pack .l2 -side bottom
    label .l3 -text [file dirname [info script]]
    pack .l3 -side bottom
}

Main

Now it's time to add the UUID. Because MyUUID returns the text of the UUID, we can use the -text option to add it directly to the label.

For a finishing touch, we add the directory name as it is seen by the script, executing inside the wrapper.

Finally, we call Main -- and that's the end of the Tcl file.

The next step is to use TclApp to create the executable. Open TclApp, and you will be presented with a screen that looks like (click to view larger image):

.

Click the button with the document on it, and select the files you would like to wrap. In this case, we'll just wrap the Tcl file and the image. Next, we choose the packages we would like to wrap in the package. Click on the button with the yellow box, and select tcllib-1.8. You will see an entry for the package appear. Now hit the "Scan" button, and it should find the rest of the packages you need for you:

To make TclApp generate an executable file, we need to set the prefix file. Because we're using Tk, we'll choose base-tk-thread-win32-ix86.exe:

Don't forget to set your output file, as it's no fun to go hunting for your new application.

Last, we click over to the "Run" tab, and click the "Wrap" button. This wraps our application and shows any problems that might occur

Now you can run your application. Try renaming your image file -- the application still works, as it's using the wrapped image. You can even install your application on another machine that doesn't have ActiveTcl or the TDK installed, and there is no problem.

Of course this is a fairly trivial example. Things can get hairy when you're wrapping larger, more complex applications. If you run into any problems, try signing onto the TDK mailing list and asking around. There are great people there.

Restoring the native Perl debugger

OS: Windows | Product: Perl Dev Kit | tags: debugger
Question: 

How do I switch back to using the native Perl command line debugger?

Answer: 

When the Perl Dev Kit is installed, the PDK's Graphical Debugger becomes the default debugger, replacing the console debugger included with your Perl distribution.

To disable the Graphical Debugger included with the Perl Dev Kit and use the console debugger instead, perform the following steps:

  1. Ensure that the Graphical Debugger is set to remote mode.
    • On the command line, enter pdkdebug --query to view the current mode.
    • If necessary, enter pdkdebug --remote to set the debug listener to local mode.
  2. Set the debugger to the console debugger included with Perl 5.x. On the command line, enter:
        set PERLDB_OPTS=

To disable the Graphical Debugger permanently, remove the PERL5DB key from HKEY_LOCAL_MACHINE\SOFTWARE\Perl and remove the PERLDB_OPTS system environment variable.

Distributing PerlRt.dll with your PerlNet component

OS: Windows | Product: Perl Dev Kit | tags: perlnet perlrt.dll
Question: 

What do I need to deploy with my PerlNET component?

Answer: 

PerlNET components built with the --freestanding option are not completely freestanding; you also need to deploy perl56.dll (or perl58.dll), perlnh.dll and perlrt.dll.

PerlNH60.dll can be found in the PDK bin directory (usually C:\Perl\bin directory or C:\Program Files\ActiveState Perl Dev Kit 6.0\bin.

PerlRT60.dll is more difficult to find because it is moved to the .NET Global Assembly Cache during installation of the PDK. Copy it out of the GAC by opening a DOS prompt and changing to the PerlRT60 directory:

  c:\> cd c:\WINDOWS\assembly\GAC\PerlRT60\

This directory should contain only one subfolder. Use 'dir' to find the name. For example:

  6.0.2.6772__cea8284aa6739163

Copy the .dll from this folder like this:

  C:\WINDOWS\assembly\GAC\PerlRT>copy 6.0.2.6772__cea8284aa6739163\perlrt60.dll
  c:\tmp

Note: On Windows 2000 and NT systems, the WINDOWS directory will be called WINNT. With previous versions of the PDK, the DLL filenames do not contain a version numbers (i.e. PerlRT.dll and PerlNH.dll)

Suppress console windows when using backticks

OS: Windows | Product: Perl Dev Kit | tags: gui perlapp
Question: 

How do I stop console windows from popping up when i call commands in backticks?

Answer: 

Using perlapp's --gui option should hide normal perl command line output, but system commands called within backticks may still open command line windows. To suppress this, try adding the following block to your script:

BEGIN {
    Win32::SetChildShowWindow(0) if defined &Win32::SetChildShowWindow;
}

This should work using ActivePerl version 632 or later.

Batch file for switching to/from PDK Debugger

OS: Windows | Product: Perl Dev Kit | tags: debugger environment
Question: 

How can I quickly switch between using the PDK Debugger and the command
line debugger?

Answer: 

Here is a batch file for manipulating the relevant environment variables:

@ECHO OFF
SET MODE=%1

IF "%MODE%" == "PDK" GOTO PDK
IF "%MODE%" == "CLI" GOTO CLI
ECHO "no valid input? usage: DBSET "
ECHO "possible modes PDK or CLI"
GOTO END

:PDK
SET PERL5LIB=C:\Program Files\ActiveState Perl Dev Kit 6.0\lib\
SET PERL5DB=
GOTO REPORT

:CLI
SET PERL5LIB=""
SET PERL5DB=BEGIN { require 'perl5db.pl'; }
GOTO REPORT

:REPORT
ECHO Debugger mode set to %MODE%

:END

Copy the code into a file called DBSET.BAT, and move it into a directory in your PATH (e.g. C:\Perl\bin).

To use perl's regular command line debugger:

C:\> DBSET CLI

To use the PDK Debugger:

C:\> DBSET PDK

Double-clicking perl scripts -- console window dissapears immediately.

OS: Windows | Product: ActivePerl
Question: 

When I double-click my perl program, the console window disappears before I can see the output.

Answer: 

If you just double-click on the program file in Windows, the console window it opens for output will close as soon as the script finishes. It is best to run Perl scripts directly from the command-line.

For example, open a console window (DOS prompt) and execute this command:

  perl C:\perl\eg\example.pl

The console window will stay open allowing you to see the output:

  Hello from ActivePerl!

If you're interested in a development environment that allows you to execute scripts in a GUI, check out Komodo:

http://activestate.com/Products/Komodo/

New to Perl. New to programming.

OS: Windows | Product: ActivePerl | tags: newbie windows
Question: 

I've installed ActivePerl. What now?

Answer: 

Go to Start | Run. Enter 'CMD' in the Open field and press Enter. This will open up a DOS command prompt. At the prompt, type:

  C:\>perl -v

You should see version information for ActivePerl.

To evaluate perl code on the command line, you can do this:

  C:\>perl -e "print \"hello world\";"

Note: you must escape double quotes in the code when using -e.

To run a script:

  C:\>perl scriptname.pl

Here are some great online resources targeted at new Perl developers:

http://learn.perl.org/library/beginning_perl/

http://www.steve.gb.com/perl/tutorial.html

If you are looking for an editor / development environment for Perl, you should try ActiveState's Komodo:

http://activestate.com/Products/Komodo/

No sendmail on Windows -- use Mail::Sender

OS: Windows | Product: ActivePerl | tags: sendmail
Question: 

My perl program uses sendmail. How do I run it on a Windows system?

Answer: 

Sendmail is a mail transfer agent used on many UNIX systems. Perl programs (such as FormMail by Matthew Wright) often use it as a pipe for sending messages. Sendmail is not part of ActivePerl, and isn't typically installed on Windows.

The best approach to use when writing Perl scripts that need to send email and also need to work on both UNIX and Windows systems is to use the Mail::Sender modules instead as this is available on Windows and UNIX. You can install Mail::Sender by running:

  ppm install mail-sender

...at a command prompt. Documentation for using Mail::Sender is available here:

http://search.cpan.org/~jenda/Mail-Sender-0.8.10/Sender.pm

Map CGI Extension in IIS

OS: Windows | Product: ActivePerl | tags: CGI IIS
Question: 

How do I get IIS to use ActivePerl for my CGI scripts?

Answer: 

During installation, ActivePerl creates script mappings in IIS for the .pl and .plx extensions but not the .cgi extension. To support the .cgi file extension, you will need to replicate the .pl extension settings.

  1. Go to Control Panel | Administrative Tools
  2. Open Internet Information Services
  3. Right-click the Default web site and select Properties.
  4. In the Properties dialog-box select the 'home Directory' tab.
  5. Click on the configuration button in the Application Configuration dialog.
  6. Click on the 'Add' button.

In the Add/Edit dialog-box, ensure the following settings are correct:

  • for executable, put in C:\Perl\bin\perl.exe "%s" %s ( adjust this if you have installed Perl elsewere)
  • for the extension, enter 'cgi'
  • for Verbs, select 'Limit to:' and put in 'GET,HEAD,POST'
  • select 'Script Engine' and 'Check that file exists'

Click OK to close all of the open dialog-boxes. You should now be able to place the cgi files you want to run into the wwwroot folder (usually c:\inetpub\wwwroot\), or create a virtual web directory in IIS to the location of your cgi files.

Manual Uninstall of ActivePerl

OS: Windows | Product: ActivePerl | tags: uninstall
Question: 

How do I manually uninstall ActivePerl (on Windows)?

Answer: 

To remove ActivePerl manually, delete the \Perl\ directory (including all sub-directories) and the following registry entries:

  1. HKEY_LOCAL_MACHINE/Software/ActiveState/ActivePerl
  2. HKEY_LOCAL_MACHINE/Software/ActiveState/PerlScript
  3. HKEY_LOCAL_MACHINE/Software/Microsoft/Windows/CurrentVersion/Uninstall/ActivePerl