bug 536972 - Cannot uninstall Fennec from Settings -> Memory Settings/Remove Programs r=blassey a=NPOTB

This commit is contained in:
Alex Pakhotin 2010-02-04 23:44:24 -08:00
Родитель 7be2f0315f
Коммит 7e1c535396
4 изменённых файлов: 140 добавлений и 18 удалений

Просмотреть файл

@ -21,6 +21,7 @@
# Contributor(s):
# John Wolfe <wolfe@lobo.us>
# Vladimir Vukicevic <vladimir@pobox.com>
# Alex Pakhotin <alexp@mozilla.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
@ -37,11 +38,11 @@
# ***** END LICENSE BLOCK *****
################################################################
#
# make-wince-cab.py --- Given a directory, walk it and make an
# make_wince_cab.py --- Given a directory, walk it and make an
# installer based upon the contents of that directory
#
# Usage:
# python make-wince-inf.py [-s] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME
# python make_wince_cab.py [-setupdll] [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME
#
# Walk through the relative directory SOURCE_DIR, parsing filenames
# Checks for duplicate filenames and renames where needed
@ -55,12 +56,15 @@
# Blank lines and '#' comments in the 'install-exceptions' file are
# ignored.
#
# EXAMPLE OF COMMAND LINE:
# python make_wince_inf.py /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/SmartDevices/SDK/SDKTools/cabwiz.exe dist/fennec Fennec fennec-0.11.en-US.wince-arm.cab
#
# ARGS:
# -setupdll - Make a small additional CAB including Setup.dll.
# This is to add Fennec to the system list of installed applications
# available in Settings - System - Remove Programs.
#
# -s - Don't pass /compress to cabwiz (generate CAB compatible with Windows CE)
#
# -faststart - Add FastStart shortcut
#
# CABWIZ_PATH - If specified, will use this cabwiz.exe executable. Otherwise, will attempt
# to find one using $VSINSTALLDIR.
#
@ -72,6 +76,9 @@
#
# CAB_FINAL_NAME - actual final name for the produced CAB file
#
# EXAMPLE OF COMMAND LINE:
# python make_wince_cab.py /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/SmartDevices/SDK/SDKTools/cabwiz.exe dist/fennec Fennec fennec-0.11.en-US.wince-arm.cab
#
# NOTE: In our example, "fennec" is the directory [source_name]
# "fennec.exe" is the application [$(source_name).exe], and
# "Fennec" is the shortcut name [program_name]
@ -87,6 +94,7 @@ import shutil
CompressFlag = "/compress"
FaststartFlag = 0
MakeSetupDllCab = 0
class FileEntry:
def __init__(self, dirpath, dircount, filename, filecount, actual_filename):
@ -309,6 +317,47 @@ def output_inf_file(program_name, app_name):
def output_setup_dll_inf_file(source_dir, program_name, app_name):
inf_name = "%s.inf" % program_name
f = open(inf_name, 'w')
f.write("""; Additional CAB to create Fennec entry in the installed programs list
[Version]
Signature = "$Windows NT$" ; required as-is
Provider = "Mozilla" ; maximum of 30 characters, full app name will be \"<Provider> <AppName>\"
CESignature = "$Windows CE$" ; required as-is
[CEStrings]
AppName = "%s" ; maximum of 40 characters, full app name will be \"<Provider> <AppName>\"\n""" % program_name)
f.write("InstallDir = %CE1%\\%AppName% ; Program Files\Fennec\n\n")
f.write("[SourceDisksNames] ; directory that holds the application's files\n")
f.write('1 = , "%s",,%s\n\n' % (source_dir, source_dir))
f.write("[SourceDisksFiles] ; list of files to be included in .cab\n")
f.write("Setup.dll = 1\n\n")
f.write("""[DefaultInstall] ; operations to be completed during install
CopyFiles = Files.%s
AddReg = RegData
CESetupDLL = "Setup.dll"
\n""" % program_name)
f.write("[DestinationDirs] ; default destination directories for each operation section\n")
f.write("Files.%s = 0, %%InstallDir%%\n\n" % program_name)
f.write("""[Files.%s]
;No files to copy
[RegData]
;No registry entries
""" % program_name)
f.close()
def make_cab_file(cabwiz_path, program_name, cab_final_name):
make_cab_command = "\"%s\" %s %s.inf" % (cabwiz_path, CompressFlag, program_name)
print "INFORMATION: Executing command to make %s CAB file (only works on BASH)" % program_name
@ -322,14 +371,14 @@ def make_cab_file(cabwiz_path, program_name, cab_final_name):
print """***************************************************************************
ERROR: CAB FILE NOT CREATED.
You can try running the command by hand:
%s" % make_cab_comman
%s
----
NOTE: If you see an error like this:
Error: File XXXXXXXXXX.inf contains DirIDs, which are not supported
--
this may mean that your PYTHON is outputting Windows files WITHOUT CR-LF
line endings. Please verify that your INF file has CR-LF line endings.
***************************************************************************"""
***************************************************************************""" % make_cab_command
sys.exit(2)
print "INFORMATION: Executing command to move %s.CAB to %s" % (program_name, cab_final_name)
@ -347,12 +396,17 @@ def purge_copied_files():
def main():
args = sys.argv
if len(args) < 4 or len(args) > 7:
print >> sys.stderr, "Usage: %s [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME" % args[0]
print >> sys.stderr, "Usage: %s [-setupdll] [-s] [-faststart] [CABWIZ_PATH] SOURCE_DIR PROGRAM_NAME CAB_FINAL_NAME" % args[0]
print >> sys.stderr, "Example: %s /c/Program\ Files/Microsoft\ Visual\ Studio\ 9.0/ fennec Fennec fennec-0.11.en-US.wince-arm.cab" % args[0]
sys.exit(1)
args = args[1:]
if args[0] == "-setupdll":
global MakeSetupDllCab
MakeSetupDllCab = 1
args = args[1:]
if args[0] == "-s":
global CompressFlag
CompressFlag = ""
@ -383,12 +437,18 @@ ERROR: CABWIZ_PATH is not a valid file, or cabwiz couldn't be found!
***************************************************************************"""
sys.exit(2)
walk_tree(source_dir, ignored_patterns)
sys.stdout.flush()
output_inf_file(program_name, app_name)
sys.stdout.flush()
make_cab_file(cabwiz_path, program_name, cab_final_name)
purge_copied_files()
if MakeSetupDllCab:
output_setup_dll_inf_file(source_dir, program_name, app_name)
sys.stdout.flush()
make_cab_file(cabwiz_path, program_name, cab_final_name)
os.remove("%s/setup.dll" % source_dir)
else:
walk_tree(source_dir, ignored_patterns)
sys.stdout.flush()
output_inf_file(program_name, app_name)
sys.stdout.flush()
make_cab_file(cabwiz_path, program_name, cab_final_name)
purge_copied_files()
# run main if run directly

Просмотреть файл

@ -55,7 +55,7 @@
const WCHAR c_sInstallPathTemplate[] = L"%s\\%s";
const WCHAR c_sExtractCardPathTemplate[] = L"\\%s%s\\%s";
const WCHAR c_sAppRegKeyTemplate[] = L"Software\\%s";
const WCHAR c_sAppRegKeyTemplate[] = L"Software\\Mozilla\\%s";
const WCHAR c_sFastStartTemplate[] = L"%s\\%sfaststart.exe";
// Message handler for the dialog
@ -294,6 +294,8 @@ BOOL nsInstallerDlg::PostExtract()
RUN_AND_CHECK(SilentFirstRun)
RUN_AND_CHECK(RunSetupCab)
return bResult;
}
@ -420,6 +422,28 @@ BOOL nsInstallerDlg::SilentFirstRun()
return bResult;
}
BOOL nsInstallerDlg::RunSetupCab()
{
BOOL bResult = FALSE;
WCHAR sCabPath[MAX_PATH];
WCHAR sParams[MAX_PATH + 20];
_snwprintf(sCabPath, MAX_PATH, L"%s\\setup.cab", m_sInstallPath);
// Run "wceload.exe /noui Fennec.cab"
_snwprintf(sParams, MAX_PATH, L"/noui \"%s\"", sCabPath);
PROCESS_INFORMATION pi;
bResult = CreateProcess(L"\\Windows\\wceload.exe",
sParams, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
if (bResult)
{
// Wait for it to finish
WaitForSingleObject(pi.hProcess, INFINITE);
}
return bResult;
}
void nsInstallerDlg::AddErrorMsg(WCHAR* sErr)
{
WCHAR sMsg[c_nMaxErrorLen];

Просмотреть файл

@ -65,6 +65,7 @@ private:
BOOL CreateShortcut();
BOOL MoveSetupStrings();
BOOL SilentFirstRun();
BOOL RunSetupCab();
BOOL GetInstallPath(WCHAR *sPath);
BOOL RunUninstall(BOOL *pbCancelled);

Просмотреть файл

@ -44,6 +44,7 @@
#include <windows.h>
#include <aygshell.h>
#include <cfgmgrapi.h>
#include "nsSetupStrings.h"
#include "resource.h"
@ -53,12 +54,17 @@
const WCHAR c_sStringsFile[] = L"setup.ini";
nsSetupStrings Strings;
BOOL g_bRunFromSetupDll = FALSE;
WCHAR g_sInstallPath[MAX_PATH];
WCHAR g_sUninstallPath[MAX_PATH];
HWND g_hDlg = NULL;
const WCHAR c_sAppRegKeyTemplate[] = L"Software\\Mozilla\\%s";
const DWORD c_nTempBufSize = MAX_PATH * 2;
const WCHAR c_sRemoveParam[] = L"[remove]";
const WCHAR c_sSetupParam[] = L"[setup]"; // means executed by Setup.dll
// Retry counter for the file/directory deletion
int nTotalRetries = 0;
@ -88,6 +94,7 @@ BOOL DeleteDirectory(const WCHAR* sPathToDelete);
BOOL DeleteRegistryKey();
BOOL CopyAndLaunch();
BOOL ShutdownFastStartService(const WCHAR *sInstallPath);
BOOL RunSystemUninstall();
BOOL CALLBACK DlgUninstall(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
BOOL OnDialogInit(HWND hDlg);
@ -108,6 +115,7 @@ int WINAPI WinMain(HINSTANCE hInstance,
WCHAR *sCommandLine = GetCommandLine();
WCHAR *sRemoveParam = wcsstr(sCommandLine, c_sRemoveParam);
WCHAR g_bRunFromSetupDll = (wcsstr(sCommandLine, c_sSetupParam) != NULL);
if (sRemoveParam != NULL)
{
// Launched from a temp directory with parameters "[remove] \Program Files\Fennec\"
@ -152,6 +160,9 @@ int Uninstall(HWND hWnd)
DeleteShortcut(hWnd);
DeleteRegistryKey();
if (!g_bRunFromSetupDll)
RunSystemUninstall();
// TODO: May probably handle errors during deletion (such as locked directories)
// and notify user. Right now just return OK.
return ErrOK;
@ -295,7 +306,7 @@ BOOL GetInstallPath(WCHAR *sPath)
{
HKEY hKey;
WCHAR sRegFennecKey[MAX_PATH];
_snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName));
_snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName));
LONG result = RegOpenKeyEx(HKEY_LOCAL_MACHINE, sRegFennecKey, 0, KEY_ALL_ACCESS, &hKey);
if (result == ERROR_SUCCESS)
@ -428,7 +439,8 @@ BOOL DeleteShortcut(HWND hwndParent)
BOOL DeleteRegistryKey()
{
WCHAR sRegFennecKey[MAX_PATH];
_snwprintf(sRegFennecKey, MAX_PATH, L"Software\\%s", Strings.GetString(StrID_AppShortName));
_snwprintf(sRegFennecKey, MAX_PATH, c_sAppRegKeyTemplate, Strings.GetString(StrID_AppShortName));
LONG result = RegDeleteKey(HKEY_LOCAL_MACHINE, sRegFennecKey);
return (result == ERROR_SUCCESS);
}
@ -444,7 +456,10 @@ BOOL CopyAndLaunch()
{
PROCESS_INFORMATION pi;
WCHAR sParam[c_nTempBufSize];
_snwprintf(sParam, c_nTempBufSize, L"%s %s", c_sRemoveParam, g_sUninstallPath);
if (g_bRunFromSetupDll)
_snwprintf(sParam, c_nTempBufSize, L"%s %s %s", c_sSetupParam, c_sRemoveParam, g_sUninstallPath);
else
_snwprintf(sParam, c_nTempBufSize, L"%s %s", c_sRemoveParam, g_sUninstallPath);
// Launch "\Temp\uninstall.exe remove \Program Files\Fennec\"
return CreateProcess(sNewName, sParam, NULL, NULL, FALSE, 0, NULL, NULL, NULL, &pi);
@ -504,3 +519,25 @@ BOOL ShutdownFastStartService(const WCHAR *wsInstallPath)
}
return result;
}
// Remove the part installed from the CAB
BOOL RunSystemUninstall()
{
WCHAR sXML[c_nTempBufSize];
LPWSTR sXMLOut = NULL;
_snwprintf(sXML, c_nTempBufSize,
L"<wap-provisioningdoc>"
L" <characteristic type=\"UnInstall\">"
L" <characteristic type=\"%s\">"
L" <parm name=\"uninstall\" value=\"1\" />"
L" </characteristic>"
L" </characteristic>"
L"</wap-provisioningdoc>",
Strings.GetString(StrID_AppLongName));
HRESULT hr = DMProcessConfigXML(sXML, CFGFLAG_PROCESS, &sXMLOut);
delete[] sXMLOut;
return hr == S_OK;
}