Windows Launcher: Download and install dependencies
[gpodder.git] / tools / win32-launcher / gpodder.c
blob6c314df4504c07eb141b84c0e43fead0df45d8ed
2 /**
3 * gPodder - A media aggregator and podcast client
4 * Copyright (c) 2005-2011 Thomas Perl and the gPodder Team
6 * gPodder is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
11 * gPodder is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 **/
21 /**
22 * gPodder for Windows
23 * Thomas Perl <thp@gpodder.org>; 2011-11-06
24 **/
27 #include <windows.h>
28 #include <shlobj.h>
30 #include <stdlib.h>
31 #include <shellapi.h>
32 #include <string.h>
34 #define PROGNAME "gPodder"
36 #define BAILOUT(s) { \
37 MessageBox(NULL, s, "Error launching " PROGNAME, MB_OK); \
38 exit(1); \
41 #if defined(GPODDER_GUI)
42 # define MAIN_MODULE "bin\\gpodder"
43 #else
44 # define MAIN_MODULE "bin\\gpo"
45 #endif
47 #define PYTHON_INSTALLER_FILE "python-2.7.2.msi"
48 #define PYTHON_INSTALLER_SIZE 15970304L
49 #define PYGTK_INSTALLER_FILE "pygtk-all-in-one-2.24.0.win32-py2.7.msi"
50 #define PYGTK_INSTALLER_SIZE 33583548L
52 #define PYTHON_INSTALLER_URL \
53 "http://python.org/ftp/python/2.7.2/" \
54 PYTHON_INSTALLER_FILE
56 #define PYGTK_INSTALLER_URL \
57 "http://ftp.gnome.org/pub/GNOME/binaries/win32/pygtk/2.24/" \
58 PYGTK_INSTALLER_FILE
60 #define LOOKUP_FUNCTION(x) {x = GetProcAddress(python_dll, #x); \
61 if(x == NULL) {BAILOUT("Cannot find function: " #x);}}
63 int main(int argc, char** argv)
65 char path_env[MAX_PATH];
66 char current_dir[MAX_PATH];
67 char *endmarker = NULL;
68 int i;
69 void *MainPy;
70 void *GtkModule;
71 int _argc = 1;
72 char *_argv[] = { MAIN_MODULE };
73 TCHAR gPodder_Home[MAX_PATH];
75 HMODULE python_dll;
76 FARPROC Py_Initialize;
77 FARPROC PySys_SetArgvEx;
78 FARPROC PyImport_ImportModule;
79 FARPROC PyFile_FromString;
80 FARPROC PyFile_AsFile;
81 FARPROC PyRun_SimpleFile;
82 FARPROC Py_Finalize;
84 #if defined(GPODDER_CLI)
85 SetConsoleTitle(PROGNAME);
86 #endif
88 if (getenv("GPODDER_HOME") == NULL) {
89 /* Get path to the "My Documents" folder */
90 if (SHGetFolderPath(NULL,
91 CSIDL_PERSONAL | CSIDL_FLAG_CREATE,
92 NULL,
94 gPodder_Home) != S_OK) {
95 BAILOUT("Cannot determine your home directory (SHGetFolderPath).");
98 strncat(gPodder_Home, "\\gPodder", MAX_PATH);
99 if (SetEnvironmentVariable("GPODDER_HOME", gPodder_Home) == 0) {
100 BAILOUT("SetEnvironmentVariable for GPODDER_HOME failed.");
104 /* Set current directory to directory of launcher */
105 strncpy(current_dir, argv[0], MAX_PATH);
106 endmarker = strrchr(current_dir, '\\');
107 if (endmarker == NULL) {
108 endmarker = strrchr(current_dir, '/');
110 if (endmarker != NULL) {
111 *endmarker = '\0';
112 /* We know the folder where the launcher sits - cd into it */
113 if (SetCurrentDirectory(current_dir) == 0) {
114 BAILOUT("Cannot set current directory.");
118 /* Only load the Python DLL after we've set up the environment */
119 python_dll = LoadLibrary("python27.dll");
121 if (python_dll == NULL) {
122 if (MessageBox(NULL,
123 PROGNAME " requires Python 2.7.\n"
124 "Do you want to install it now?",
125 "Python 2.7 installation not found",
126 MB_YESNO | MB_ICONQUESTION) == IDYES) {
127 if (DownloadFile(PYTHON_INSTALLER_FILE,
128 PYTHON_INSTALLER_URL,
129 PYTHON_INSTALLER_SIZE) == PYTHON_INSTALLER_SIZE) {
130 ShellExecute(NULL,
131 "open",
132 PYTHON_INSTALLER_FILE,
133 NULL,
134 NULL,
135 SW_SHOWNORMAL);
139 return 1;
142 LOOKUP_FUNCTION(Py_Initialize);
143 LOOKUP_FUNCTION(PySys_SetArgvEx);
144 LOOKUP_FUNCTION(PyImport_ImportModule);
145 LOOKUP_FUNCTION(PyFile_FromString);
146 LOOKUP_FUNCTION(PyFile_AsFile);
147 LOOKUP_FUNCTION(PyRun_SimpleFile);
148 LOOKUP_FUNCTION(Py_Finalize);
150 Py_Initialize();
151 argv[0] = MAIN_MODULE;
152 PySys_SetArgvEx(argc, argv, 0);
154 #if defined(GPODDER_GUI)
155 /* Check for GTK, but not if we are running the CLI */
156 GtkModule = (void*)PyImport_ImportModule("gtk");
157 if (GtkModule == NULL) {
158 if (MessageBox(NULL,
159 PROGNAME " requires PyGTK.\n"
160 "Do you want to install it now?",
161 "PyGTK installation not found",
162 MB_YESNO | MB_ICONQUESTION) == IDYES) {
163 if (DownloadFile(PYGTK_INSTALLER_FILE,
164 PYGTK_INSTALLER_URL,
165 PYGTK_INSTALLER_SIZE) == PYGTK_INSTALLER_SIZE) {
166 ShellExecute(NULL,
167 "open",
168 PYGTK_INSTALLER_FILE,
169 NULL,
170 NULL,
171 SW_SHOWNORMAL);
175 return 1;
177 // decref GtkModule
178 #endif
180 // XXX: Test for feedparser, mygpoclient, dbus
182 MainPy = (void*)PyFile_FromString(MAIN_MODULE, "r");
183 if (MainPy == NULL) { BAILOUT("Cannot load main file") }
184 if (PyRun_SimpleFile(PyFile_AsFile(MainPy), MAIN_MODULE) != 0) {
185 BAILOUT("There was an error running " MAIN_MODULE " in Python.");
187 // decref MainPy
188 Py_Finalize();
190 return 0;