http://www.perlmonks.org?node_id=90834
Category: NT Admin, GUI Programming
Author/Contact Info John McKee ralfthewise@hotmail.com
Description: The is a gui driven registry editor for network admins. It allows admins to create standard registry edits for workstation builds, maintenance, etc.
The code is in three parts. Genericreg.pl, regentry.pm, and reglist.pm. Genericreg.pl
######################################################################
+########
#  John McKee
#  6/01/2001
#
#  GenericReg Edits Version 1
#
#  Files:
#  1. Genericreg.pl
#  2. Regentry.pm
#  3. Reglist.pm
#
#  Standard Registry Edits 
#  1.  Command Prompt from Explorer
#  2.  Personalized Bitmap at Logon
#  3.  Don't Display Last User at Logon
#
#  Build Perl version 5.6.1
#
#  Contents Genericreg.pl:
#  1.  Gui
#  2.  6 Subfunctions for registry edits
#
######################################################################
+########

use Tk;
use Tk::Menubutton;
use Tk::Canvas;
use Win32::Registry;
use regentry;
use reglist;
my ($hkey,$SubKey);

$call_entry = regentry->new();
$call_list = reglist->new();

gui();

######################################################################
+#############
#GUI 
######################################################################
+#############
sub gui
{
    my $top = MainWindow->new();
    $top->title('Generic Registry Edits');

    
    #menubar frame widget
        $menu = $top->Frame(-relief=>"raised", -borderwidth=>2);
    #end menubar


    #pulldowns in menubar
        $menu_pulldown1 = $menu->Menubutton(-text=>"File", -underline=
+>0);
        $menu_pulldown2 = $menu->Menubutton(-text=>"Custom", -underlin
+e=>0);
    #end pulldowns

    
    #pulldown commands for file menu
    #    $menu_pulldown1->command(-label=>"Open", -command=>sub{open_c
+hoice()});
    #    $menu_pulldown1->separator();
        $menu_pulldown1->command(-label =>"Exit", -command=>sub{exit 0
+});
    #end pulldown commands for file menu


    #pulldown commands for the custom menu
        $menu_pulldown2->command(-label=>"Create Custom Edits", -comma
+nd=>sub {$call_entry->Gui()});
        $menu_pulldown2->separator();
        $menu_pulldown2->command(-label=>"List Custom Edits", -command
+=>sub {$call_list->Gui()});
        $menu_pulldown2->separator();
        #$menu_pulldown2->command(-label=>"Commit Changes from List", 
+-command=> sub{commit_changes()});
    #end pulldown commands for custom menu


    #Buttons
        $button1 =$top->Button(-text =>"Command Prompt Open from Explo
+rer", -foreground=>"red", -command =>sub{c_prompt()});
        $button2 =$top->Button(-text =>"Don't Show Last User", -foregr
+ound=>"red", -command => sub{last_user()});
        $button3 =$top->Button(-text =>"Personalized Logon Bitmap", -f
+oreground=>"red", -command =>sub{bitmap()});
        $button_undo_1 =$top->Button(-text =>"Undo Prompt", -foregroun
+d=>"blue", -command=>sub{undo_c_prompt()});
        $button_undo_2 =$top->Button(-text =>"Undo Last User", -foregr
+ound=>"blue", -command=>sub{undo_last_user()});
        $button_undo_3 =$top->Button(-text =>"Undo Bitmap", -foregroun
+d=>"blue", -command=>sub{undo_bitmap()});
    #end Buttons
    
    
    #Label Area
        $label = $top->Label(-text => "Non-Critical Registry Edits", -
+background=>"DarkSlateGray3", -relief=>"groove", -width=>"30", -heigh
+t=>"4", -font=>"{Times New Roman} 12 {normal}");
    #end Label Area
    
        
    #text for info button
        $menu_popup = $menu->Button(-text=>"Help", -underline=>0, -rel
+ief=>"flat",-command => sub
            {
                $newtop = $top->Toplevel();
                $newtop->title('Copyright Info');
                $copyright = $newtop->Button(-text=>"Copyright Info",-
+command =>sub {system "notepad copyright.txt"});#this button opens a 
+notepad file with instructions
                $copyright->pack();
                $help = $newtop->Button(-text=>"Help", -command=> sub 
+{system "notepad front_help.txt"});
                $help->pack();
                $canvas = $newtop->Canvas();
                $canvas->pack();
            });
    #end text for info button
    

    #packs
        $menu->pack(-side=>'top', -fill=>'x');
        $menu_pulldown1->pack(-side,'left');
        $menu_pulldown2->pack(-side,'left');
        $menu_popup->pack(-side,'right');
        $label->pack(-side=>"top",-fill=>"x");
        $frame1 =$top->Frame()->pack(-fill=>"x",-pady=>"2.5p");  #pack
+ frames and pady 2.5 pixels
        $frame2 =$top->Frame()->pack(-fill=>"x",-pady=>"2.5p");  #  "
        $frame3 =$top->Frame()->pack(-fill=>"x",-pady=>"2.5p");  #  "
        $button1 =$frame1->Button(-text =>"Command Prompt Open from Ex
+plorer", -foreground=>"red", -command =>sub{c_prompt()})->pack(-side=
+>"left",-fill=>"x");
        $button_undo_1 =$frame1->Button(-text =>"Undo Prompt", -foregr
+ound=>"blue", -command=>sub{undo_c_prompt()})->pack(-side=>"right",-f
+ill=>"x");
        $button2 =$frame2->Button(-text =>"Don't Show Last User", -for
+eground=>"red", -command => sub{last_user()})->pack(-side=>"left",-fi
+ll=>"x");
        $button_undo_2 =$frame2->Button(-text =>"Undo Last User", -for
+eground=>"blue", -command=>sub{undo_last_user()})->pack(-side=>"right
+",-fill=>"x");
        $button3 =$frame3->Button(-text =>"Personalized Logon Bitmap",
+ -foreground=>"red", -command =>sub{bitmap()})->pack(-side=>"left",-f
+ill=>"x");
        $entry1 = $frame3->Entry(-textvariable => \$location, -backgro
+und=>"DarkSlateGray3", -borderwidth=>4)->pack(-side=>"left");
        $button_undo_3 =$frame3->Button(-text =>"Undo Bitmap", -foregr
+ound=>"blue", -command=>sub{undo_bitmap()})->pack(-side=>"right",-fil
+l=>"x");
    #end packs
    MainLoop;
}
#End Gui
#*********************************************************************
+*************


#    Standard edits, utilizing the Perl module Win32::Registry.
#    The custom edits in regentry.pm create/utilize *.reg files,
#        (Standard formating of *.reg files).


sub c_prompt
{
    ##################################################################
+#################
    #Command Prompt from Windows Explorer Right Click
    ##################################################################
+#################
        my $Register = "Directory\\Shell";
        $HKEY_CLASSES_ROOT->Open($Register,$hkey)|| die $!;
        $hkey->SetValue("CommandPrompt",REG_SZ,"Command Prompt Here");
        $hkey->Close();

        my $Register2 = "Directory\\Shell\\CommandPrompt";
        my $commandp = "cmd.exe /k cd %1";
        $HKEY_CLASSES_ROOT->Open($Register2,$hkey)||die $!;
        $hkey->SetValue("command",REG_SZ,$commandp);
        $hkey->Close();
    #*****************************************************************
+*****************
}

sub last_user
{
    ##################################################################
+#################
    #Don't Display Last User Name
    ##################################################################
+#################
        my $Register3 = "Software\\Microsoft\\Windows NT\\CurrentVersi
+on\\Winlogon";
        undef $garbage;
        $HKEY_LOCAL_MACHINE->Open($Register3,$hkey)||die $!;
        $hkey->SetValueEx("DontDisplayLastUserName",$garbage,REG_SZ,"1
+");
        $hkey->Close();
    #*****************************************************************
+*****************
}

sub bitmap 
{
    ##################################################################
+#################
    #Change Logon Bitmap
    ##################################################################
+#################
        my $Register4 = ".DEFAULT\\Control Panel\\Desktop";
        my $bitmap_path = "$location";                        # replac
+e '?' with path to desired .bmp.  Use entry box.
        my $LogonBitmap = $bitmap_path;        
        $HKEY_USERS->Open($Register4,$hkey)||die $!;
        $hkey->SetValueEx("Wallpaper",$garbage,REG_SZ,$LogonBitmap);
    #*****************************************************************
+*****************
}

sub undo_c_prompt
{
    ##################################################################
+#################
    #Undo Command Prompt from Explorer
    ##################################################################
+#################
        $register6="Directory\\Shell\\CommandPrompt";
        $HKEY_CLASSES_ROOT->Open($register6,$hkey)||die $!;
        $hkey->DeleteKey ("Command");
        $hkey->Close();
        $register6="Directory\\Shell";
        $HKEY_CLASSES_ROOT->Open($register6,$hkey)||die $!;
        $hkey->DeleteKey ("CommandPrompt");
        $hkey->Close();
    #*****************************************************************
+*****************
}

sub undo_last_user
{
    ##################################################################
+#################
    #Undo Show Last User
    ##################################################################
+#################
        $register7="Software\\Microsoft\\Windows NT\\CurrentVersion\\W
+inlogon";
        $HKEY_LOCAL_MACHINE->Open($register7,$hkey)||die $!;
        $hkey->DeleteValue ("DontDisplayLastUserName");
        $hkey->Close();
    #*****************************************************************
+*****************
}

sub undo_bitmap
{
    ##################################################################
+#################
    #Undo Logon Bitmap
    ##################################################################
+#################
        $register8=".DEFAULT\\Control Panel\\Desktop";
        $HKEY_USERS->Open($register8,$hkey)||die $!;
        $hkey->DeleteValue ("Wallpaper");
        $hkey->Close();
    #*****************************************************************
+*****************
}
regentry.pm
######################################################################
+########
#John McKee
#regentry.pm
#
#
#  This is an extension program to genericreg.pl
#  1.   This is a GUI which allows the user to 
#        create a set of custom registry edits
#        and save those edits to a file.
#
#    Unresolved Issues
#    1.  In-Depth Help File
#    2.  Clear all entry boxes when a new radiobutton is pushed
#
######################################################################
+########

package regentry;
use Tk;
use Tk::Menubutton;
use Tk::Canvas;
use Tk::Entry;
use Tk::Radiobutton;

#Constructor
sub new
{
    bless{};
}
#end constructor

sub Gui
{
    #Gui, Title, and Warning Label
    $top = MainWindow->new();
    $top->title('Custom Registry Edits');
    $label = $top->Label(-text => "REALLY!\n  Don't do this unless you
+ know\n what you're doing or willing\n to suffer the chaos that\n can
+ ensue from monkeying\n with the all mighty registry hive!", -backgro
+und=>"DarkSlateGray3", -relief=>"groove", -width=>"32", -height=>"6",
+ -font=>"{Times New Roman} 12 {normal}")->pack();
    #end Gui, Title, and Warning Label

    #RadioButtons for desired registry hive
    $top->Radiobutton (-text => "HKEY_CLASSES_ROOT", -variable=>\$regk
+ey, -value=>"HKEY_CLASSES_ROOT", -activeforeground=>"blue")->pack();
    $top->Radiobutton (-text => "HKEY_CURRENT_USER", -variable=>\$regk
+ey, -value=>"HKEY_CURRENT_USER", -activeforeground=>"blue")->pack();
    $top->Radiobutton (-text => "HKEY_LOCAL_MACHINE", -variable=>\$reg
+key, -value=>"HKEY_LOCAL_MACHINE", -activeforeground=>"blue")->pack()
+;
    $top->Radiobutton (-text => "HKEY_USERS", -variable=>\$regkey, -va
+lue=>"HKEY_USERS", -activeforeground=>"blue")->pack();
    $top->Radiobutton (-text => "HKEY_CURRENT_CONFIG", -variable=>\$re
+gkey, -value=>"HKEY_CURRENT_CONFIG", -activeforeground=>"blue")->pack
+();
    $top->Radiobutton (-text => "HKEY_DYN_DATA", -variable=>\$regkey, 
+-value=>"HKEY_DYN_DATA", -activeforeground=>"blue")->pack();
    #end RadioButtons for desired registry hive


    #Labels for Custom Edits
    $regedit = "Enter the registry hive you wish to edit:";
    $create_key = "Enter name of key to create/edit:";
    $create_value = "Enter name of value to create/edit:";
    $memo ="Name for this change:";
    #end Labels


    #Separate Frames for better look
    $frame4 =$top->Frame()->pack();
    $frame1 =$top->Frame()->pack();
    $frame2 =$top->Frame()->pack();
    $frame3 =$top->Frame()->pack();
    #end Frames
    
    
    #Label and Entry Boxes with packing
    $label1 = $frame1->Label(-textvariable => \$regedit)->pack(-side=>
+"left");
    $entry1 = $frame1->Entry(-textvariable => \$text)->pack(-side=>"le
+ft");
    $label2 = $frame2->Label(-textvariable => \$create_key)->pack(-sid
+e=>"left");
    $entry2 = $frame2->Entry(-textvariable => \$text2)->pack(-side=>"l
+eft");
    $label3 = $frame3->Label(-textvariable => \$create_value)->pack(-s
+ide=>"left");
    $entry3 = $frame3->Entry(-textvariable => \$text3)->pack(-side=>"l
+eft");
    $label4 = $frame4->Label(-textvariable => \$memo)->pack(-side=>"le
+ft");
    $entry4 = $frame4->Entry(-textvariable => \$name)->pack(-side=>"le
+ft");
    #end Label and Entry Boxes

    #Buttons Save, Close, Help
    #Note: Save button also clears entry boxes
    $top->Button(-text=>"Save RegEdits to a File", -foreground=>"blue"
+, -command=>sub{save(),$entry1->delete( 0, 'end' ),$entry2->delete( 0
+, 'end' ),$entry3->delete( 0, 'end' ),$entry4->delete( 0, 'end' )})->
+pack(); #sub to save selections 
    $top->Button(-text=>"Close", -foreground=>"blue", -command=> sub {
+$top->destroy()})->pack();
    $top->Button(-text=>"Help (Don't be afraid to use this)", -foregro
+und=>"white", -background=>"red", -command=>sub {system "notepad rege
+ntry_hlp.txt"})->pack();
    #end Buttons
    
    MainLoop;
}
#End Gui
#*********************************************************************
+********


    ##################################################################
+########
    #Filehandler for the custom edits
    #Creates *.reg files based on the name & values given in the entry
+ gui
    ##################################################################
+########
        sub save ()
        {
            open (FD, ">$name.reg")||die "Unable to open storage file"
+;
            print FD "REGEDIT4\n\n[$regkey\\$text]\n\"$text2\"=\"$text
+3\"\n";
            close (FD);
        }
    #*****************************************************************
+********

    return 1;
and finally reglist.pm
######################################################################
+########
#John McKee
#reglist.pm
#
#
#  This is an extension program to genericreg.pl
#  1.   This creates a listbox from *.reg's in pwd,
#        which were created by the user via
#        custom registy edits.
#  2.    It lists the name of the regstry edits that
#        the user requires and allows that user
#        to select more than one, if so desired.
#        And allow the user to delete edits no
#        longer required
#
######################################################################
+########

package reglist;
use Tk;

#Constructor
sub new
{
    bless{};
}
#end Constructor

sub Gui
{
    undef(@selections);
    my $top = MainWindow->new();
    $top->title('Listing of Custom Registry Edits');

    #Listbox widget
    $listbox = $top->ScrlListbox(-label=>"Custom Edits", -height=>6, -
+selectmode =>"extended", -background=>"DarkSlateGray3");
    #end listbox widget
    
    #Buttons (Exit, Delete, and Select)
    $exitbutton = $top->Button(-text =>"Exit", -command=>sub {$top->de
+stroy()});
    $deletebutton = $top->Button(-text=>"Delete", -command=>\&del_sele
+ction);
    $selectbutton = $top->Button(-text=>"Select", -command=>\&proc_sel
+ection);
    $okbutton = $top->Button(-text=>"Commit Changes", -command=>\&comm
+it_changes);
    #end buttons

    #Sunken Selection Frame    
    $frame = $top->Frame(-relief =>"ridge", -relief=>"raised", -border
+width =>4, -background=>"DarkSlateGray4");
    $label = $frame->Label(-text =>"Selected: ",-background=>"DarkSlat
+eGray3");
    $entry = $frame->Label(-textvariable => \$seltext, -relief=>"sunke
+n", -background=>"white");
    #end Frame

    #packs
    $listbox->pack(-fill=>"both", -expand=>"yes");
    $exitbutton->pack(-side=>"left");
    $selectbutton->pack(-side=>"left");
    $deletebutton->pack(-side=>"right");
    $okbutton->pack(-side=>"right");
    $frame->pack(-side=>"right", -anchor=>"se",-expand=>"yes",-fill=>"
+x");
    $label->pack(-side=>"left");
    $entry->pack(-side=>"left");
    #end packs    
        
    
    ##################################################################
+########
    #  Gets all *.reg files from pwd an insert into listbox
    ##################################################################
+########
        open (FD, "dir /B *.reg |") || die "Unable to read";
        while (<FD>)
        {
            chop;                                        #Cut newline
            $listbox->insert("end","$_");                #pull *.reg's
+ into listbox
        }
        close (FD);
    #*****************************************************************
+********
    
    $seltext=proc_selection();

MainLoop;
}

sub proc_selection
{
    ##################################################################
+########
    #    Store the selections the user makes
    ##################################################################
+########
        $seltext=join(', ',$listbox->Getselected);  
        push (@selections,$listbox->Getselected);    #stored in @selec
+tions
    #*****************************************************************
+********
}

sub del_selection
{
    ##################################################################
+########
    #    Deletes selected Registry edits
    ##################################################################
+########
        $del_choice = $listbox->get('active');        #gets highlighte
+d selection(s)
        $listbox->delete('active');                    #deletes from l
+istbox
        system ("erase $del_choice");                #deletes from dir
+ectory
    #*****************************************************************
+********
}

sub commit_changes
{
    ##################################################################
+########
    #    Reads selection list from the list box and commits those chan
+ges
    #    to the registry after the user hits the commit changes button
    ##################################################################
+########
        foreach (@selections)
        {
            system ($_);                            #uses crackjack $_
+ to run
        }                                            #each *.reg selec
+ted
    #*****************************************************************
+********
}

return 1;