Hi,
Attached are diffs to provide a basic unattended mode in setup.exe. Let me
know if they need to be in a different format, or if I should be using CVS
(I might need a hint or two though).
I used command-line options as follows:
-q --quiet-mode
Requests unattended mode. Setup will still stop and ask for assistance if
it runs into a problem or if you haven't provided enough information.
-D --download
Downloads packages without installing them.
-L --local-install
Installs from a local directory.
-R directory
Specifies the root installation directory. (The long option is --root but
long string options don't currently work.)
-s site
Specifies the download site. (The long option is --site but long string
options don't currently work.)
-n --no-shortcuts
Disables the creation of the desktop and start menu shortcuts. (Not
actually a new option but the implementation is different. I don't think
the old implementation worked quite right.)
-N --no-startmenu
Disables the creation of the start menu shortcut.
-d --no-desktop
Disables the creation of the desktop shortcut.
There are some limitations:
1) There is no command-line option to set the local package directory. If
Cygwin has already been installed I think the previous value will be
remembered otherwise the current directory will be used. (Such an option
could be added easily enough if anyone needs it.)
2) There are no command-line options to set the internet access
options. To download in unattended mode you need a direct internet
connection. (Again, it wouldn't be too hard for someone to add these options.)
3) The big one: there is no way to specify which packages to install. You
can only install the default set. This won't be quite as easy to fix, I
suspect it will need someone familiar with the package management
system. It will probably also be necessary to extend the command line
options code to support multi-valued options.
I haven't done extensive testing, but it seems to work.
Regards,
Harry.
Index: setup/desktop.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/desktop.cc,v
retrieving revision 2.32
diff -u -p -r2.32 desktop.cc
--- setup/desktop.cc 9 Jul 2002 06:57:41 -0000 2.32
+++ setup/desktop.cc 23 Jul 2002 04:33:10 -0000
@@ -26,6 +26,7 @@ static const char *cvsid =
#include "win32.h"
#include <shlobj.h>
#include "desktop.h"
+#include "propsheet.h"
#include <stdio.h>
#include <stdlib.h>
@@ -55,6 +56,8 @@ static const char *cvsid =
#include "PackageSpecification.h"
static BoolOption NoShortcutsOption (false, 'n', "no-shortcuts", "Disable creation of
desktop and start menu shortcuts");
+static BoolOption NoStartMenuOption (false, 'N', "no-startmenu", "Disable creation of
+start menu shortcut");
+static BoolOption NoDesktopOption (false, 'd', "no-desktop", "Disable creation of
+desktop shortcut");
static OSVERSIONINFO verinfo;
@@ -473,19 +476,38 @@ DesktopSetupPage::OnInit ()
CoInitialize (NULL);
verinfo.dwOSVersionInfoSize = sizeof (verinfo);
GetVersionEx (&verinfo);
- root_desktop =
- check_desktop ("Cygwin", backslash (cygpath ("/cygwin.bat")));
- root_menu =
- check_startmenu ("Cygwin Bash Shell",
- backslash (cygpath ("/cygwin.bat")));
- if (NoShortcutsOption)
- {
- root_desktop=false;
- root_menu=false;
- OnFinish();
+
+ if (NoShortcutsOption)
+ {
+ root_desktop = root_menu = 0;
}
else
- load_dialog (GetHWND ());
+ {
+ if (NoStartMenuOption)
+ {
+ root_menu = 0;
+ MessageBox(NULL, "NoStartMenuOption", "NoStartMenuOption", MB_OK);
+ }
+ else
+ {
+ root_menu =
+ check_startmenu ("Cygwin Bash Shell",
+ backslash (cygpath ("/cygwin.bat")));
+ }
+
+ if (NoDesktopOption)
+ {
+ root_desktop = 0;
+ }
+ else
+ {
+ root_desktop =
+ check_desktop ("Cygwin", backslash (cygpath ("/cygwin.bat")));
+ }
+ }
+
+ load_dialog (GetHWND ());
+
}
long
@@ -505,6 +527,34 @@ DesktopSetupPage::OnFinish ()
do_desktop_setup ();
NEXT (IDD_S_POSTINSTALL);
do_postinstall (GetInstance (), h);
+
+ return true;
+}
+
+long
+DesktopSetupPage::OnUnattended ()
+{
+ Window::PostMessage (WM_APP_UNATTENDED_FINISH);
+ // GetOwner ()->PressButton(PSBTN_FINISH);
+ return -1;
+}
+
+bool
+DesktopSetupPage::OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ switch (uMsg)
+ {
+ case WM_APP_UNATTENDED_FINISH:
+ {
+ GetOwner ()->PressButton(PSBTN_FINISH);
+ break;
+ }
+ default:
+ {
+ // Not handled
+ return false;
+ }
+ }
return true;
}
Index: setup/download.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/download.cc,v
retrieving revision 2.33
diff -u -p -r2.33 download.cc
--- setup/download.cc 15 Jul 2002 14:05:01 -0000 2.33
+++ setup/download.cc 23 Jul 2002 04:33:12 -0000
@@ -310,7 +310,7 @@ do_download_thread (HINSTANCE h, HWND ow
{
if (errors)
exit_msg = IDS_DOWNLOAD_INCOMPLETE;
- else
+ else if (!unattended_mode)
exit_msg = IDS_DOWNLOAD_COMPLETE;
next_dialog = 0;
}
Index: setup/install.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/install.cc,v
retrieving revision 2.51
diff -u -p -r2.51 install.cc
--- setup/install.cc 9 Jul 2002 06:57:41 -0000 2.51
+++ setup/install.cc 23 Jul 2002 04:33:36 -0000
@@ -597,18 +597,18 @@ do_install_thread (HINSTANCE h, HWND own
check_for_old_cygwin ();
if (num_installs == 0 && num_uninstalls == 0)
{
- exit_msg = IDS_NOTHING_INSTALLED;
+ if (!unattended_mode) exit_msg = IDS_NOTHING_INSTALLED;
return;
}
if (num_installs == 0)
{
- exit_msg = IDS_UNINSTALL_COMPLETE;
+ if (!unattended_mode) exit_msg = IDS_UNINSTALL_COMPLETE;
return;
}
if (errors)
exit_msg = IDS_INSTALL_INCOMPLETE;
- else
+ else if (!unattended_mode)
exit_msg = IDS_INSTALL_COMPLETE;
}
Index: setup/main.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/main.cc,v
retrieving revision 2.18
diff -u -p -r2.18 main.cc
--- setup/main.cc 4 May 2002 12:15:56 -0000 2.18
+++ setup/main.cc 23 Jul 2002 04:33:36 -0000
@@ -58,11 +58,14 @@ static const char *cvsid =
#include "desktop.h"
#include "getopt++/GetOption.h"
+#include "getopt++/BoolOption.h"
int next_dialog;
HINSTANCE hinstance;
+static BoolOption UnattendedOption (false, 'q', "quiet-mode", "Unattended setup
+mode");
+
/* Maximum size of a SID on NT/W2K. */
#define MAX_SID_LEN 40
@@ -207,6 +210,8 @@ main (int argc, char **argv)
if (!GetOption::GetInstance().Process (argc,_argv))
theLog.exit(1);
// #endif
+
+ unattended_mode = UnattendedOption;
/* Set the default DACL only on NT/W2K. 9x/ME has no idea of access
control lists and security at all. */
Index: setup/net.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/net.cc,v
retrieving revision 2.11
diff -u -p -r2.11 net.cc
--- setup/net.cc 18 Feb 2002 13:53:06 -0000 2.11
+++ setup/net.cc 23 Jul 2002 04:33:36 -0000
@@ -122,6 +122,12 @@ NetPage::OnNext ()
}
long
+NetPage::OnUnattended()
+{
+ return OnNext ();
+}
+
+long
NetPage::OnBack ()
{
save_dialog (GetHWND ());
Index: setup/proppage.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/proppage.cc,v
retrieving revision 2.3
diff -u -p -r2.3 proppage.cc
--- setup/proppage.cc 3 Jan 2002 11:27:11 -0000 2.3
+++ setup/proppage.cc 23 Jul 2002 04:33:36 -0000
@@ -20,6 +20,9 @@
#include "propsheet.h"
#include "win32.h"
#include "resource.h"
+#include "state.h"
+
+#include "getopt++/BoolOption.h"
bool PropertyPage::DoOnceForSheet = true;
@@ -158,9 +161,42 @@ PropertyPage::DialogProc (UINT message,
OnActivate ();
- // 0 == Accept activation, -1 = Don't accept
- ::SetWindowLong (GetHWND (), DWL_MSGRESULT, 0);
- return TRUE;
+ if (unattended_mode)
+ {
+ // -2 == disable unattended mode, display page
+ // -1 == display page but stay in unattended mode (progress bars)
+ // 0 == skip to next page
+ // IDD_* == skip to specified page
+ long nextwindow = OnUnattended();
+ if (nextwindow == -2)
+ {
+ unattended_mode = false;
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, 0);
+ return TRUE;
+ }
+ else if (nextwindow == -1)
+ {
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, 0);
+ return TRUE;
+ }
+ else if (nextwindow == 0)
+ {
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, -1);
+ return TRUE;
+ }
+ else
+ {
+ SetWindowLong (GetHWND (), DWL_MSGRESULT, nextwindow);
+ return TRUE;
+ }
+ }
+ else
+ {
+ // 0 == Accept activation, -1 = Don't accept
+ ::SetWindowLong (GetHWND (), DWL_MSGRESULT, 0);
+ return TRUE;
+ }
+
}
break;
case PSN_KILLACTIVE:
Index: setup/root.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/root.cc,v
retrieving revision 2.10
diff -u -p -r2.10 root.cc
--- setup/root.cc 18 Feb 2002 13:53:06 -0000 2.10
+++ setup/root.cc 23 Jul 2002 04:33:36 -0000
@@ -36,6 +36,10 @@ static const char *cvsid =
#include "log.h"
#include "root.h"
+#include "getopt++/StringOption.h"
+
+StringOption RootOption ("", 'R', "root", "Root installation directory");
+
static int rb[] = { IDC_ROOT_TEXT, IDC_ROOT_BINARY, 0 };
static int su[] = { IDC_ROOT_SYSTEM, IDC_ROOT_USER, 0 };
@@ -164,6 +168,8 @@ RootPage::Create ()
void
RootPage::OnInit ()
{
+ if (((string)RootOption).size())
+ set_root_dir((string)RootOption);
if (!get_root_dir ().size())
read_mounts ();
load_dialog (GetHWND ());
@@ -203,4 +209,10 @@ RootPage::OnBack ()
save_dialog (h);
NEXT (IDD_SOURCE);
return 0;
+}
+
+long
+RootPage::OnUnattended ()
+{
+ return OnNext();
}
Index: setup/site.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/site.cc,v
retrieving revision 2.22
diff -u -p -r2.22 site.cc
--- setup/site.cc 6 Jul 2002 17:58:22 -0000 2.22
+++ setup/site.cc 23 Jul 2002 04:33:36 -0000
@@ -45,9 +45,13 @@ static const char *cvsid =
#include "threebar.h"
extern ThreeBarProgressPage Progress;
+#include "getopt++/StringOption.h"
+
SiteList site_list;
SiteList all_site_list;
+StringOption SiteOption("", 's', "site", "Download site");
+
void
site_list_type::init (String const &newurl)
{
@@ -221,6 +225,31 @@ get_site_list (HINSTANCE h, HWND owner)
#define NOSAVE3_LEN (sizeof ("ftp://gcc.gnu.org/") - 1)
static void
+register_saved_site (const char * site)
+{
+ site_list_type tempSite(site);
+ SiteList::iterator i = find (all_site_list.begin(),
+ all_site_list.end(), tempSite);
+ if (i == all_site_list.end())
+ {
+ /* Don't default to certain machines ever since they suffer
+ from bandwidth limitations. */
+ if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0
+ || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0
+ || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0)
+ return;
+ SiteList result;
+ merge (all_site_list.begin(), all_site_list.end(),
+ &tempSite, &tempSite + 1,
+ inserter (result, result.begin()));
+ all_site_list = result;
+ site_list.push_back (tempSite);
+ }
+ else
+ site_list.push_back (tempSite);
+}
+
+static void
get_saved_sites ()
{
io_stream *f = io_stream::open ("cygfile:///etc/setup/last-mirror", "rt");
@@ -239,26 +268,8 @@ get_saved_sites ()
if (eos < site)
continue;
- site_list_type tempSite(site);
- SiteList::iterator i = find (all_site_list.begin(),
- all_site_list.end(), tempSite);
- if (i == all_site_list.end())
- {
- /* Don't default to certain machines ever since they suffer
- from bandwidth limitations. */
- if (strnicmp (site, NOSAVE1, NOSAVE1_LEN) == 0
- || strnicmp (site, NOSAVE2, NOSAVE2_LEN) == 0
- || strnicmp (site, NOSAVE3, NOSAVE3_LEN) == 0)
- return;
- SiteList result;
- merge (all_site_list.begin(), all_site_list.end(),
- &tempSite, &tempSite + 1,
- inserter (result, result.begin()));
- all_site_list = result;
- site_list.push_back (tempSite);
- }
- else
- site_list.push_back (tempSite);
+ register_saved_site (site);
+
}
delete f;
@@ -316,7 +327,11 @@ bool SitePage::Create ()
void
SitePage::OnInit ()
{
- get_saved_sites ();
+ string SiteOptionString = SiteOption;
+ if (SiteOptionString.size())
+ register_saved_site (SiteOptionString.c_str());
+ else
+ get_saved_sites ();
}
long
@@ -360,6 +375,15 @@ SitePage::OnActivate ()
// Get the enabled/disabled states of the controls set accordingly.
CheckControlsAndDisableAccordingly ();
+}
+
+long
+SitePage::OnUnattended ()
+{
+ if (SendMessage (GetDlgItem (IDC_URL_LIST), LB_GETSELCOUNT, 0, 0) > 0)
+ return OnNext ();
+ else
+ return -2;
}
void
Index: setup/source.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/source.cc,v
retrieving revision 2.12
diff -u -p -r2.12 source.cc
--- setup/source.cc 18 Feb 2002 13:53:07 -0000 2.12
+++ setup/source.cc 23 Jul 2002 04:33:36 -0000
@@ -33,6 +33,11 @@ static const char *cvsid =
#include "source.h"
+#include "getopt++/BoolOption.h"
+
+static BoolOption DownloadOption (false, 'D', "download", "Download from internet");
+static BoolOption LocalOption (false, 'L', "local-install", "Install from local
+directory");
+
static int rb[] =
{ IDC_SOURCE_NETINST, IDC_SOURCE_DOWNLOAD, IDC_SOURCE_CWD, 0 };
@@ -79,7 +84,15 @@ void
SourcePage::OnActivate ()
{
if (!source)
- source = IDC_SOURCE_NETINST;
+ {
+ if (DownloadOption)
+ source = IDC_SOURCE_DOWNLOAD;
+ else if (LocalOption)
+ source = IDC_SOURCE_CWD;
+ else
+ source = IDC_SOURCE_NETINST;
+ }
+
load_dialog (GetHWND ());
// Check to see if any radio buttons are selected. If not, select a default.
if ((!SendMessage
@@ -121,4 +134,10 @@ SourcePage::OnDeactivate ()
log (LOG_PLAIN, String ("source: ") +
((source == IDC_SOURCE_DOWNLOAD) ? "download" :
(source == IDC_SOURCE_NETINST) ? "network install" : "from cwd"));
+}
+
+long
+SourcePage::OnUnattended ()
+{
+ return OnNext();
}
Index: setup/state.cc
===================================================================
RCS file: /cvs/cygwin-apps/setup/state.cc,v
retrieving revision 2.2
diff -u -p -r2.2 state.cc
--- setup/state.cc 29 Apr 2002 11:07:40 -0000 2.2
+++ setup/state.cc 23 Jul 2002 04:33:36 -0000
@@ -22,6 +22,8 @@ static const char *cvsid =
#include "state.h"
+bool unattended_mode;
+
int source;
String local_dir;
Index: setup/choose.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/choose.h,v
retrieving revision 2.15
diff -u -p -r2.15 choose.h
--- setup/choose.h 12 May 2002 11:28:22 -0000 2.15
+++ setup/choose.h 23 Jul 2002 04:33:36 -0000
@@ -39,6 +39,10 @@ public:
virtual void OnInit ();
virtual long OnNext ();
virtual long OnBack ();
+ virtual long OnUnattended ()
+ {
+ return OnNext ();
+ };
};
#endif /* __cplusplus */
Index: setup/desktop.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/desktop.h,v
retrieving revision 2.4
diff -u -p -r2.4 desktop.h
--- setup/desktop.h 27 Apr 2002 00:00:05 -0000 2.4
+++ setup/desktop.h 23 Jul 2002 04:33:36 -0000
@@ -21,6 +21,9 @@
#include "proppage.h"
+// WM_APP through WM_APP+7: see threebar.h
+#define WM_APP_UNATTENDED_FINISH WM_APP+8
+
class DesktopSetupPage:public PropertyPage
{
public:
@@ -36,6 +39,8 @@ public:
virtual void OnInit ();
virtual bool OnFinish ();
virtual long OnBack ();
+ virtual long OnUnattended ();
+ virtual bool OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam);
};
#endif // CINSTALL_DESKTOP_H
Index: setup/localdir.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/localdir.h,v
retrieving revision 2.2
diff -u -p -r2.2 localdir.h
--- setup/localdir.h 3 Jan 2002 11:27:11 -0000 2.2
+++ setup/localdir.h 23 Jul 2002 04:33:36 -0000
@@ -38,6 +38,10 @@ public:
virtual void OnInit ();
virtual long OnNext ();
virtual long OnBack ();
+ virtual long OnUnattended ()
+ {
+ return OnNext ();
+ };
};
Index: setup/net.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/net.h,v
retrieving revision 2.2
diff -u -p -r2.2 net.h
--- setup/net.h 3 Jan 2002 11:27:11 -0000 2.2
+++ setup/net.h 23 Jul 2002 04:33:36 -0000
@@ -39,6 +39,7 @@ public:
virtual void OnInit ();
virtual long OnNext ();
virtual long OnBack ();
+ virtual long OnUnattended ();
virtual bool OnMessageCmd (int id, HWND hwndctl, UINT code);
};
Index: setup/proppage.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/proppage.h,v
retrieving revision 2.2
diff -u -p -r2.2 proppage.h
--- setup/proppage.h 3 Jan 2002 11:27:11 -0000 2.2
+++ setup/proppage.h 23 Jul 2002 04:33:36 -0000
@@ -107,6 +107,10 @@ public:
{
return true;
};
+ virtual long OnUnattended ()
+ {
+ return -2;
+ };
PropSheet *GetOwner () const
{
Index: setup/root.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/root.h,v
retrieving revision 2.2
diff -u -p -r2.2 root.h
--- setup/root.h 3 Jan 2002 11:27:11 -0000 2.2
+++ setup/root.h 23 Jul 2002 04:33:36 -0000
@@ -18,6 +18,7 @@ public:
virtual void OnInit ();
virtual long OnNext ();
virtual long OnBack ();
+ virtual long OnUnattended ();
};
#endif // CINSTALL_ROOT_H
Index: setup/site.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/site.h,v
retrieving revision 2.7
diff -u -p -r2.7 site.h
--- setup/site.h 5 Jul 2002 05:17:21 -0000 2.7
+++ setup/site.h 23 Jul 2002 04:33:42 -0000
@@ -40,6 +40,7 @@ public:
virtual void OnActivate ();
virtual long OnNext ();
virtual long OnBack ();
+ virtual long OnUnattended ();
virtual bool OnMessageCmd (int id, HWND hwndctl, UINT code);
Index: setup/source.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/source.h,v
retrieving revision 2.2
diff -u -p -r2.2 source.h
--- setup/source.h 3 Jan 2002 11:27:11 -0000 2.2
+++ setup/source.h 23 Jul 2002 04:33:42 -0000
@@ -38,6 +38,7 @@ public:
virtual void OnDeactivate ();
virtual long OnNext ();
virtual long OnBack ();
+ virtual long OnUnattended ();
};
#endif
Index: setup/splash.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/splash.h,v
retrieving revision 2.2
diff -u -p -r2.2 splash.h
--- setup/splash.h 3 Jan 2002 11:27:11 -0000 2.2
+++ setup/splash.h 23 Jul 2002 04:33:42 -0000
@@ -33,6 +33,10 @@ public:
bool Create ();
virtual void OnInit ();
+ long OnUnattended ()
+ {
+ return 0;
+ };
};
#endif // CINSTALL_SPLASH_H
Index: setup/state.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/state.h,v
retrieving revision 2.7
diff -u -p -r2.7 state.h
--- setup/state.h 18 Feb 2002 12:35:23 -0000 2.7
+++ setup/state.h 23 Jul 2002 04:33:43 -0000
@@ -28,6 +28,8 @@
#include "String++.h"
+extern bool unattended_mode;
+
extern int source;
extern String local_dir;
Index: setup/threebar.h
===================================================================
RCS file: /cvs/cygwin-apps/setup/threebar.h,v
retrieving revision 2.3
diff -u -p -r2.3 threebar.h
--- setup/threebar.h 26 Jun 2002 21:35:16 -0000 2.3
+++ setup/threebar.h 23 Jul 2002 04:33:43 -0000
@@ -31,6 +31,7 @@
#define WM_APP_SITE_INFO_DOWNLOAD_COMPLETE WM_APP+5
#define WM_APP_START_SETUP_INI_DOWNLOAD WM_APP+6
#define WM_APP_SETUP_INI_DOWNLOAD_COMPLETE WM_APP+7
+// desktop.h: WM_APP_UNATTENDED_FINISH WM_APP+8
class ThreeBarProgressPage:public PropertyPage
{
@@ -62,6 +63,10 @@ public:
virtual void OnInit ();
virtual void OnActivate ();
virtual bool OnMessageApp (UINT uMsg, WPARAM wParam, LPARAM lParam);
+ virtual long OnUnattended ()
+ {
+ return -1;
+ };
void SetText1 (const TCHAR * t);
void SetText2 (const TCHAR * t);
---
Harry Johnston, http://www.cs.waikato.ac.nz/~harry