emacs-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: May I publish a Windows Installer for GNU Emacs?


From: Frank Schmitt
Subject: Re: May I publish a Windows Installer for GNU Emacs?
Date: Sat, 13 Sep 2003 13:10:29 +0200
User-agent: Gnus/5.1003 (Gnus v5.10.3) Emacs/21.3.50 (windows-nt)

"Eli Zaretskii" <address@hidden> writes:

>> From: Frank Schmitt <address@hidden>
>> Date: Fri, 12 Sep 2003 18:20:14 +0200
>> 
>> During the last days, I've created a Windows Installer for GNU
>> Emacs. Here's what it currently does:
>
> You may wish to check out the Emacs installer written as part of the
> "GNU Software for MS-Windows and MS-DOS" CD-ROM, published by the FSF.
> (I can send you the source of the latest version, if you want.)  That
> code, written by Andrew Innes, is under GPL, and I think if someone
> wants to maintain an official GNU installer for NTEmacs, that code
> should be a good starting place, I think.

Yes, I'd of course be interested in the code, however I doubt that a
stand-alone installer written from scratch can be as solid (e.g. in
terms of uninstalling, rolling back changes when an error occurs during
installing etc.) and easy to maintain as an installer produced by a
tool, developed simply for the purpose of building installers.

>> My installer currently installs a CVS snapshot of Emacs' head from
>> 09/09/03 plus the dll's needed to display inline images
>
> With the CVS snapshot, you will need to compile Emacs first, won't
> you?

OK, it installs binaries compiled by me of the CVS snapshot.

>> The installer was created with the help of two free tools: Inno Setup 4
>> (http://www.jrsoftware.org/isinfo.htm OK, I don't really know if the
>> software can really be called free, it's published under a somewhat
>> BSD-like license, see http://www.jrsoftware.org/files/is/license.txt) to
>> create the installer and 7-zip (http://www.7-zip.org/ published under
>> the LGPL) to compress it to the size of 17.2 mb (uncompressed about
>> 93mb).
>
> One advantage of the installer I mentioned is that it is acompletely
> stand-alone, so none of the legal issues you mention even arise.

There are no legal issues, I just use the tools to create the
installer, they aren't part of it.

Just to give you an idea what the difference is: I created the install
by running this script, the rest does Inno Setup for me:

,----
| [Setup]
| AppName=GNU Emacs
| AppVerName=CVS (!) GNU Emacs 09/09/2003 unofficial binary
| AppPublisher=Frank Schmitt
| AppPublisherURL=http://www.geheimdienst.de/emacs/
| AppSupportURL=http://www.geheimdienst.de/emacs/
| AppUpdatesURL=http://www.geheimdienst.de/emacs/
| DefaultDirName={pf}\CVSEmacs
| DefaultGroupName=GNU Emacs
| AllowNoIcons=yes
| SourceDir=c:\Programme\Inno Setup 3\Emacs\
| Compression=none
| InternalCompressLevel=0
| UseSetupLdr=no
| InfoAfterFile=gpl.rtf
| 
| [Tasks]
| Name: "desktopicon"; Description: "Create a &desktop icon"; GroupDescription: 
"Additional icons:"; Flags: unchecked
| Name: "quicklaunchicon"; Description: "Create a &Quick Launch icon"; 
GroupDescription: "Additional icons:"; Flags: unchecked
| 
| [Registry]
| Root: HKLM; Subkey: "Software\GNU"; Flags: uninsdeletekeyifempty; Check: 
IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; Flags: uninsdeletekey; Check: 
IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"emacs_dir"; ValueData: "{app}"; Flags: uninsdeletekey; Check: IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSLOADPATH"; ValueData: 
"%emacs_dir%/site-lisp;%emacs_dir%/../site-lisp;%emacs_dir%/lisp;%emacs_dir%/leim";
 Flags: uninsdeletekey; Check: IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"SHELL"; ValueData: "%emacs_dir%/bin/cmdproxy.exe"; Flags: uninsdeletekey; 
Check: IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSDATA"; ValueData: "%emacs_dir%/etc"; Flags: uninsdeletekey; Check: IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSPATH"; ValueData: "%emacs_dir%/bin"; Flags: uninsdeletekey; Check: IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSDOC"; ValueData: "%emacs_dir%/etc"; Flags: uninsdeletekey; Check: IsAdmin
| Root: HKLM; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"TERM"; ValueData: "cmd"; Flags: uninsdeletekey; Check: IsAdmin
| Root: HKCU; Subkey: "Software\GNU"; Flags: uninsdeletekeyifempty; Check: 
IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; Flags: uninsdeletekey; Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"emacs_dir"; ValueData: "{app}"; Flags: uninsdeletekey; Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSLOADPATH"; ValueData: 
"%emacs_dir%/site-lisp;%emacs_dir%/../site-lisp;%emacs_dir%/lisp;%emacs_dir%/leim";
 Flags: uninsdeletekey; Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"SHELL"; ValueData: "%emacs_dir%/bin/cmdproxy.exe"; Flags: uninsdeletekey; 
Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSDATA"; ValueData: "%emacs_dir%/etc"; Flags: uninsdeletekey; Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSPATH"; ValueData: "%emacs_dir%/bin"; Flags: uninsdeletekey; Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"EMACSDOC"; ValueData: "%emacs_dir%/etc"; Flags: uninsdeletekey; Check: IsUser
| Root: HKCU; Subkey: "Software\GNU\Emacs"; ValueType: expandsz; ValueName: 
"TERM"; ValueData: "cmd"; Flags: uninsdeletekey; Check: IsUser
| 
| 
| [Dirs]
| Name: "{app}\bin"
| Name: "{app}\data"
| Name: "{app}\etc"
| Name: "{app}\info"
| Name: "{app}\leim"
| Name: "{app}\lisp"
| Name: "{app}\lock"
| Name: "{app}\site-lisp"
| 
| [Files]
| Source: "bin\*.*"; DestDir: "{app}\bin\"; Flags: ignoreversion recursesubdirs
| Source: "etc\*.*"; DestDir: "{app}\etc\"; Flags: ignoreversion recursesubdirs
| Source: "info\*.*"; DestDir: "{app}\info\"; Flags: ignoreversion 
recursesubdirs
| Source: "leim\*.*"; DestDir: "{app}\leim\"; Flags: ignoreversion 
recursesubdirs
| Source: "lisp\*.*"; DestDir: "{app}\lisp\"; Flags: ignoreversion 
recursesubdirs
| Source: "site-lisp\subdirs.el"; DestDir: "{app}\site-lisp\"; Flags: 
ignoreversion
| 
| [Icons]
| Name: "{group}\Emacs"; Filename: "{app}\bin\runemacs.exe"
| Name: "{group}\Uninstall Emacs"; Filename: "{uninstallexe}"
| Name: "{userdesktop}\Emacs"; Filename: "{app}\bin\runemacs.exe"; Tasks: 
desktopicon
| Name: "{userappdata}\Microsoft\Internet Explorer\Quick Launch\Emacs"; 
Filename: "{app}\bin\runemacs.exe"; Tasks: quicklaunchicon
| 
| [Run]
| Filename: "{app}\bin\runemacs.exe"; Description: "Launch Emacs"; Flags: 
nowait postinstall skipifsilent
| 
| [Code]
| var
|   HomeDir: String;
|   reboot: boolean;
|   HomeNotSet: boolean;
|   
| function InitializeSetup(): Boolean;
| begin
|   reboot := false;
|   HomeDir := GetEnv('HOME');
|   if (HomeDir='') then HomeNotSet := true else HomeNotSet := false;
|   { Let Setup run }
|   Result := True;
| end;
| 
| function IsAdmin(): Boolean;
| begin
|   result := IsAdminLoggedOn();
| end;
| 
| function IsUser(): Boolean;
| begin
|   result := not isAdmin();
| end;
| 
| function NeedRestart(): boolean;
| begin
|   result := reboot;
| end;
| 
| function CreateHomeDir(Home: String): boolean;
| begin
|   if not (DirExists(Home)) then ForceDirectories(Home);
| end;
| 
| function AddHomeToEnv(Home: String): boolean;
| begin
|   if (UsingWinNT()) then begin
|     result := RegWriteStringValue(HKCU, 'Environment', 'HOME', Home);
|   end else begin
|     if FileCopy(ExpandConstant('{sd}')+'\autoexec.bat', 
ExpandConstant('{sd}')+'\autoexec.old', false) then begin
|       result := SaveStringToFile(ExpandConstant('{sd}')+'\autoexec.bat', #13 
+ #10 + 'set HOME='+Home, true)
|     end else begin
|       result := false;
|     end;
|   end;
| end;
| 
| procedure CurStepChanged(CurStep: Integer);
| begin
|   if (CurStep = csFinished) and (HomeNotSet) and (not (HomeDir='')) then
|   begin
|     AddHomeToEnv(HomeDir);
|     CreateHomeDir(HomeDir);
|   end;
| end;
| 
| function IsCorrectDir(Dir: String): boolean;
| begin
|   if (Length(Dir)<4) then begin
|     result := false
|   end else begin
|     if ((StrGet(HomeDir,2) = ':') and (StrGet(HomeDir,3) = '\')) then begin
|       result := true
|     end else begin
|       if ((StrGet(HomeDir,1) = '\') and (StrGet(HomeDir,2) = '\')) then begin
|         result := true;
|       end;
|     end;
|   end;
| end;
| 
| function ScriptDlgPages(CurPage: Integer; BackClicked: Boolean): Boolean;
| var
|   Next: Boolean;
|   UserName: String;
|   DontSetHome: String;
|   CurSubPage : Integer;
| begin
|   if (HomeNotSet) and ((not BackClicked and (CurPage = wpSelectDir)) or 
(BackClicked and (CurPage = wpReady))) then begin
|     if not BackClicked then
|       CurSubPage := 0
|     else
|       CurSubPage := 1;
|     { Insert a custom wizard page between two non custom pages }
|     { First open the custom wizard page }
|     while (CurSubPage = 0) or (CurSubPage = 1) and not Terminated do begin
|       ScriptDlgPageOpen();
|       { Set some captions }
|       case CurSubPage of
|         0:
|           begin
|             ScriptDlgPageSetCaption('Home Directory');
|             ScriptDlgPageSetSubCaption1('Environment variable HOME 
undefined');
|             ScriptDlgPageSetSubCaption2('Emacs and most other unix-derived 
applications store their configuration files in the directory pointed to by the 
environment variable HOME. Setup can set this environment variable for you if 
you want.');
|             Next := InputOption('Do not set environment variable HOME.', 
DontSetHome);
|           end;
|         1:
|           begin
|             UserName := GetUserNameString();
|             if (Pos(' ', UserName) > 0) then StringChange(UserName, ' ', '');
|             HomeDir := 'C:\Home\'+ UserName;
|             if (DontSetHome='0') then begin
|               reboot := true;
|               ScriptDlgPageSetCaption('Select Home Directory');
|               ScriptDlgPageSetSubCaption1('Please select an appropriate 
directory');
|               ScriptDlgPageSetSubCaption2('Neither the directory name nor the 
path to the directory should contain spaces.');
|               { Ask for a dir until the user has entered one or click Back or 
Cancel }
|               Next := InputDir(UserName, HomeDir);
|               while Next and (not IsCorrectDir(HomeDir)) do begin
|                 MsgBox(SetupMessage(msgInvalidPath), mbError, MB_OK);
|                 Next := InputDir(UserName, HomeDir);
|               end;
|             { See NextButtonClick and BackButtonClick: return True if the 
click should be allowed }
|             end else begin
|               reboot := false;
|             end;
|           end;
|         end;
|       if Next then begin
|         CurSubPage := CurSubPage + 1;
|       end else
|         CurSubPage := CurSubPage - 1;
|     end;
|     if not BackClicked then
|       Result := Next
|     else
|       Result := not Next;
|     { Close the wizard page. Do a FullRestore only if the click (see above) 
is not allowed }
|     ScriptDlgPageClose(not Result);
|   end else begin
|     Result := True;
|   end;
| end;
| 
| function NextButtonClick(CurPage: Integer): Boolean;
| begin
|   Result := ScriptDlgPages(CurPage, False);
| end;
| 
| function BackButtonClick(CurPage: Integer): Boolean;
| begin
|   Result := ScriptDlgPages(CurPage, True);
| end;
`----


-- 
Did you ever realize how much text fits in eighty columns? If you now consider
that a signature usually consists of up to four lines, this gives you enough
space to spread a tremendous amount of information with your messages. So seize
this opportunity and don't waste your signature with bullshit nobody will read.





reply via email to

[Prev in Thread] Current Thread [Next in Thread]