1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "nsXULAppAPI.h"
6 #include "nsXPCOMGlue.h"
11 #define snprintf _snprintf
12 #define strcasecmp _stricmp
15 #include "nsAppRunner.h"
17 #include "nsIXULAppInstall.h"
20 #include "nsCRTGlue.h"
21 #include "nsStringAPI.h"
22 #include "nsServiceManagerUtils.h"
26 #include "nsINIParser.h"
29 #include "nsWindowsWMain.cpp"
32 #include "BinaryPath.h"
34 #include "nsXPCOMPrivate.h" // for MAXPATHLEN and XPCOM_DLL
36 using namespace mozilla
;
39 * Output a string to the user. This method is really only meant to be used to
40 * output last-ditch error messages designed for developers NOT END USERS.
43 * Pass true to indicate severe errors.
45 * printf-style format string followed by arguments.
47 static void Output(bool isError
, const char *fmt
, ... )
52 #if (defined(XP_WIN) && !MOZ_WINCONSOLE)
54 _vsnwprintf(msg
, sizeof(msg
)/sizeof(msg
[0]), NS_ConvertUTF8toUTF16(fmt
).get(), ap
);
58 flags
|= MB_ICONERROR
;
60 flags
|= MB_ICONINFORMATION
;
62 MessageBoxW(nullptr, msg
, L
"XULRunner", flags
);
64 vfprintf(stderr
, fmt
, ap
);
71 * Return true if |arg| matches the given argument name.
73 static bool IsArg(const char* arg
, const char* s
)
79 return !strcasecmp(arg
, s
);
82 #if defined(XP_WIN) || defined(XP_OS2)
84 return !strcasecmp(++arg
, s
);
91 GetGREVersion(const char *argv0
,
92 nsACString
*aMilestone
,
96 aMilestone
->Assign("<Error>");
98 aVersion
->Assign("<Error>");
100 nsCOMPtr
<nsIFile
> iniFile
;
101 nsresult rv
= BinaryPath::GetFile(argv0
, getter_AddRefs(iniFile
));
105 iniFile
->SetNativeLeafName(NS_LITERAL_CSTRING("platform.ini"));
108 rv
= parser
.Init(iniFile
);
113 rv
= parser
.GetString("Build", "Milestone", *aMilestone
);
118 rv
= parser
.GetString("Build", "BuildID", *aVersion
);
125 static void Usage(const char *argv0
)
127 nsAutoCString milestone
;
128 GetGREVersion(argv0
, &milestone
, nullptr);
130 // display additional information (XXX make localizable?)
132 "Mozilla XULRunner %s\n\n"
133 "Usage: " XULRUNNER_PROGNAME
" [OPTIONS]\n"
134 " " XULRUNNER_PROGNAME
" APP-FILE [APP-OPTIONS...]\n"
137 " --app specify APP-FILE (optional)\n"
138 " -h, --help show this message\n"
139 " -v, --version show version\n"
140 " --gre-version print the GRE version string on stdout\n"
141 " --install-app <application> [<destination> [<directoryname>]]\n"
142 " Install a XUL application.\n"
145 " Application initialization file.\n"
148 " Application specific options.\n",
152 XRE_GetFileFromPathType XRE_GetFileFromPath
;
153 XRE_CreateAppDataType XRE_CreateAppData
;
154 XRE_FreeAppDataType XRE_FreeAppData
;
155 XRE_mainType XRE_main
;
157 static const nsDynamicFunctionLoad kXULFuncs
[] = {
158 { "XRE_GetFileFromPath", (NSFuncPtr
*) &XRE_GetFileFromPath
},
159 { "XRE_CreateAppData", (NSFuncPtr
*) &XRE_CreateAppData
},
160 { "XRE_FreeAppData", (NSFuncPtr
*) &XRE_FreeAppData
},
161 { "XRE_main", (NSFuncPtr
*) &XRE_main
},
166 GetXULRunnerDir(const char *argv0
, nsIFile
* *aResult
)
170 nsCOMPtr
<nsIFile
> appFile
;
171 rv
= BinaryPath::GetFile(argv0
, getter_AddRefs(appFile
));
173 Output(true, "Could not find XULRunner application path.\n");
177 rv
= appFile
->GetParent(aResult
);
179 Output(true, "Could not find XULRunner installation dir.\n");
185 InstallXULApp(nsIFile
* aXULRunnerDir
,
186 const char *aAppLocation
,
187 const char *aInstallTo
,
188 const char *aLeafName
)
190 nsCOMPtr
<nsIFile
> appLocation
;
191 nsCOMPtr
<nsIFile
> installTo
;
194 nsresult rv
= XRE_GetFileFromPath(aAppLocation
, getter_AddRefs(appLocation
));
199 rv
= XRE_GetFileFromPath(aInstallTo
, getter_AddRefs(installTo
));
205 NS_CStringToUTF16(nsDependentCString(aLeafName
),
206 NS_CSTRING_ENCODING_NATIVE_FILESYSTEM
, leafName
);
208 rv
= NS_InitXPCOM2(nullptr, aXULRunnerDir
, nullptr);
213 // Scope our COMPtr to avoid holding XPCOM refs beyond xpcom shutdown
214 nsCOMPtr
<nsIXULAppInstall
> install
215 (do_GetService("@mozilla.org/xulrunner/app-install-service;1"));
217 rv
= NS_ERROR_FAILURE
;
220 rv
= install
->InstallApplication(appLocation
, installTo
, leafName
);
224 NS_ShutdownXPCOM(nullptr);
235 AutoAppData(nsIFile
* aINIFile
) : mAppData(nullptr) {
236 nsresult rv
= XRE_CreateAppData(aINIFile
, &mAppData
);
242 XRE_FreeAppData(mAppData
);
245 operator nsXREAppData
*() const { return mAppData
; }
246 nsXREAppData
* operator -> () const { return mAppData
; }
249 nsXREAppData
* mAppData
;
252 int main(int argc
, char* argv
[])
254 char exePath
[MAXPATHLEN
];
255 nsresult rv
= mozilla::BinaryPath::Get(argv
[0], exePath
);
257 Output(true, "Couldn't calculate the application directory.\n");
261 char *lastSlash
= strrchr(exePath
, XPCOM_FILE_PATH_SEPARATOR
[0]);
262 if (!lastSlash
|| (size_t(lastSlash
- exePath
) > MAXPATHLEN
- sizeof(XPCOM_DLL
) - 1))
265 strcpy(++lastSlash
, XPCOM_DLL
);
267 rv
= XPCOMGlueStartup(exePath
);
269 Output(true, "Couldn't load XPCOM.\n");
273 if (argc
> 1 && (IsArg(argv
[1], "h") ||
274 IsArg(argv
[1], "help") ||
275 IsArg(argv
[1], "?")))
281 if (argc
== 2 && (IsArg(argv
[1], "v") || IsArg(argv
[1], "version")))
283 nsAutoCString milestone
;
284 nsAutoCString version
;
285 GetGREVersion(argv
[0], &milestone
, &version
);
286 Output(false, "Mozilla XULRunner %s - %s\n",
287 milestone
.get(), version
.get());
291 rv
= XPCOMGlueLoadXULFunctions(kXULFuncs
);
293 Output(true, "Couldn't load XRE functions.\n");
298 nsAutoCString milestone
;
299 rv
= GetGREVersion(argv
[0], &milestone
, nullptr);
303 if (IsArg(argv
[1], "gre-version")) {
309 printf("%s\n", milestone
.get());
313 if (IsArg(argv
[1], "install-app")) {
314 if (argc
< 3 || argc
> 5) {
319 char *appLocation
= argv
[2];
321 char *installTo
= nullptr;
324 if (!*installTo
) // left blank?
328 char *leafName
= nullptr;
335 nsCOMPtr
<nsIFile
> regDir
;
336 rv
= GetXULRunnerDir(argv
[0], getter_AddRefs(regDir
));
340 return InstallXULApp(regDir
, appLocation
, installTo
, leafName
);
344 const char *appDataFile
= getenv("XUL_APP_FILE");
346 if (!(appDataFile
&& *appDataFile
)) {
352 if (IsArg(argv
[1], "app")) {
362 appDataFile
= argv
[1];
367 static char kAppEnv
[MAXPATHLEN
];
368 snprintf(kAppEnv
, MAXPATHLEN
, "XUL_APP_FILE=%s", appDataFile
);
372 nsCOMPtr
<nsIFile
> appDataLF
;
373 rv
= XRE_GetFileFromPath(appDataFile
, getter_AddRefs(appDataLF
));
375 Output(true, "Error: unrecognized application.ini path.\n");
379 AutoAppData
appData(appDataLF
);
381 Output(true, "Error: couldn't parse application.ini.\n");
385 return XRE_main(argc
, argv
, appData
, 0);