From 4fbf2ceaef1aa835000722ea96827d8b72360b84 Mon Sep 17 00:00:00 2001 From: Maximus5 Date: Sat, 26 Dec 2020 20:35:09 +0100 Subject: [PATCH] Uninstall sources v1.10.11.0 --- Uninstall/src/FarLang.h | 2 + Uninstall/src/Lang.templ | 16 +- Uninstall/src/UnInstall.cpp | 149 +++++++++++++-- Uninstall/src/UnInstall.hpp | 239 ++++++++++++++++-------- Uninstall/src/UnInstall.vcproj | 8 + Uninstall/src/UnInstall_Eng.hlf | 40 +++- Uninstall/src/UnInstall_Eng.lng | 6 +- Uninstall/src/UnInstall_Rus.hlf | 43 ++++- Uninstall/src/UnInstall_Rus.lng | 6 +- Uninstall/src/WhatsNew.Rus.txt | 10 +- Uninstall/src/_lang.cmd | 1 + Uninstall/src/farsdk/ansi/plugin.hpp | 2 +- Uninstall/src/farsdk/unicode/plugin.hpp | 2 +- Uninstall/src/lang.ini | 6 +- Uninstall/src/project.ini | 2 +- 15 files changed, 410 insertions(+), 122 deletions(-) diff --git a/Uninstall/src/FarLang.h b/Uninstall/src/FarLang.h index 0bea425..7775897 100644 --- a/Uninstall/src/FarLang.h +++ b/Uninstall/src/FarLang.h @@ -11,6 +11,7 @@ enum { MEnterWaitCompletion, MUseElevation, MLowPriority, + MForceMsiUse, MEnterAction, MShiftEnterAction, MActionUninstallWait, @@ -38,6 +39,7 @@ enum { MMenuBottomLine1, MMenuBottomLine2, MMenuTopLine, + MMenuTopLineN, MListHKLMx86, MListHKLMx64, MListHKLM, diff --git a/Uninstall/src/Lang.templ b/Uninstall/src/Lang.templ index 34428d8..ea378a1 100644 --- a/Uninstall/src/Lang.templ +++ b/Uninstall/src/Lang.templ @@ -83,6 +83,10 @@ MLowPriority "Запуск с &низким приоритетом" "Start with &low priority" +MForceMsiUse +"&Всегда использовать MsiExec" +"&Force use MsiExec" + MEnterAction "Ente&r: " "Ente&r: " @@ -175,8 +179,8 @@ MInstallDate MBottomLine l:// Menu's top and bottom lines -"[Shift-]Enter: run, F8: del entry, F3: info, Ctrl-R: update" -"[Shift-]Enter: run, F8: del entry, F3: info, Ctrl-R: update" +"[Shift-]Enter: run, F8: del entry, F2: sort, F3: info, Ctrl-R: update" +"[Shift-]Enter: run, F8: del entry, F2: sort, F3: info, Ctrl-R: update" MFilter "Filter: [%s], Entries: [%d/%d]" @@ -187,13 +191,17 @@ MMenuBottomLine1 "{Normal priority} F7" MMenuBottomLine2 -"{Low priority} F7" -"{Low priority} F7" +" {Low priority} F7" +" {Low priority} F7" MMenuTopLine "Выберите действие" "Select action" +MMenuTopLineN +"Действие для %u элементов" +"Action for %u items" + MListHKLMx86 l:// Install location (registry) "Mx86" diff --git a/Uninstall/src/UnInstall.cpp b/Uninstall/src/UnInstall.cpp index 4f9f21f..2332920 100644 --- a/Uninstall/src/UnInstall.cpp +++ b/Uninstall/src/UnInstall.cpp @@ -116,27 +116,70 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) ListSize = 0; int NewPos = -1; - for (int i=0;i= 0 && OldPos < nCount) { - const TCHAR* DispName = p[i].Keys[DisplayName]; - if (strstri(DispName,Filter)) // OEM + if (!*Filter || strstri(p[OldPos].Keys[DisplayName],Filter)) // OEM + NewPos = OldPos; + } + for (int i = 0; i < nCount; i++) + { + const TCHAR* DispName = p[i].Keys[DisplayName], *Find; + if (*Filter) + Find = strstri(DispName,Filter); + else + Find = DispName; + if (Find != nullptr) // OEM { FLI[i].Flags &= ~LIF_HIDDEN; + if (Param2 && (i == OldPos)) + { + if (FLI[i].Flags & LIF_CHECKED) + { + FLI[i].Flags &= ~LIF_CHECKED; + } + else + { + FLI[i].Flags |= LIF_CHECKED; + } + } // - ANSI - if (NewPos == -1 && strstri(DispName,Filter) == DispName) + if (NewPos == -1 && Find == DispName) NewPos = i; ListSize++; } else FLI[i].Flags |= LIF_HIDDEN; } - if (NewPos == -1) NewPos = OldPos; + if (Param1 == 0 && Param2) + { + // (Ins) + if (Param2 == 1) + { + for (int i = (OldPos+1); i < nCount; i++) + { + if (!(FLI[i].Flags & LIF_HIDDEN)) + { + OldPos = i; break; + } + } + NewPos = OldPos; + } + // (RClick) + else if (Param2 == 2) + { + NewPos = OldPos; + } + } + else if (NewPos == -1) + { + NewPos = OldPos; + } Info.SendDlgMessage(hDlg,DM_ENABLEREDRAW,FALSE,0); Info.SendDlgMessage(hDlg,DM_LISTSET,LIST_BOX,reinterpret_cast(&FL)); - FSF.sprintf(spFilter,GetMsg(MFilter),Filter,ListSize,nCount); + StringCchPrintf(spFilter,ARRAYSIZE(spFilter), GetMsg(MFilter),Filter,ListSize,nCount); ListTitle.Title = spFilter; ListTitle.TitleLen = lstrlen(spFilter); Info.SendDlgMessage(hDlg,DM_LISTSETTITLES,LIST_BOX,reinterpret_cast(&ListTitle)); @@ -169,9 +212,11 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) case DN_MOUSECLICK: { - if (Param1 == LIST_BOX) { + if (Param1 == LIST_BOX) + { MOUSE_EVENT_RECORD *mer = (MOUSE_EVENT_RECORD *)Param2; - if (mer->dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) { + if (mer->dwButtonState == FROM_LEFT_1ST_BUTTON_PRESSED) + { // find list on-screen coords (excluding frame and border) SMALL_RECT list_rect; Info.SendDlgMessage(hDlg, DM_GETDLGRECT, 0, reinterpret_cast(&list_rect)); @@ -179,7 +224,8 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) list_rect.Top += 1; list_rect.Right -= 2; list_rect.Bottom -= 1; - if ((mer->dwEventFlags == 0) && (mer->dwMousePosition.X > list_rect.Left) && (mer->dwMousePosition.X < list_rect.Right) && (mer->dwMousePosition.Y > list_rect.Top) && (mer->dwMousePosition.Y < list_rect.Bottom)) { + if ((mer->dwEventFlags == 0) && (mer->dwMousePosition.X > list_rect.Left) && (mer->dwMousePosition.X < list_rect.Right) && (mer->dwMousePosition.Y > list_rect.Top) && (mer->dwMousePosition.Y < list_rect.Bottom)) + { DlgProc(hDlg, DN_KEY, LIST_BOX, KEY_ENTER); return TRUE; } @@ -187,6 +233,11 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) if ((mer->dwMousePosition.X == list_rect.Right) && (mer->dwMousePosition.Y > list_rect.Top) && (mer->dwMousePosition.Y < list_rect.Bottom)) return FALSE; return TRUE; } + else if (mer->dwButtonState == RIGHTMOST_BUTTON_PRESSED) + { + Info.SendDlgMessage(hDlg,DMU_UPDATE,0,2); + return TRUE; + } } } break; @@ -199,7 +250,7 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) if (ListSize) { TCHAR DlgText[MAX_PATH + 200]; - FSF.sprintf(DlgText, GetMsg(MConfirm), p[Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)].Keys[DisplayName]); + StringCchPrintf(DlgText, ARRAYSIZE(DlgText), GetMsg(MConfirm), p[Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)].Keys[DisplayName]); if (EMessage((const TCHAR * const *) DlgText, 0, 2) == 0) { if (!DeleteEntry(static_cast(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)))) @@ -211,6 +262,7 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) return TRUE; case (KEY_F9|KEY_SHIFT|KEY_ALT): + case (KEY_F9): { Configure(0); } @@ -222,19 +274,74 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) } return TRUE; + case KEY_INS: + { + Info.SendDlgMessage(hDlg,DMU_UPDATE,0,1); + } + return TRUE; + case KEY_ENTER: case KEY_SHIFTENTER: { if (ListSize) { int liChanged = 0; - int pos = static_cast(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)); - if (Param2 == KEY_ENTER) - liChanged = ExecuteEntry(pos, Opt.EnterAction, (Opt.RunLowPriority!=0)); - else if (Param2 == KEY_SHIFTENTER) - liChanged = ExecuteEntry(pos, Opt.ShiftEnterAction, (Opt.RunLowPriority!=0)); + int liSelected = 0, liFirst = -1; + + for (int i = 0; i < nCount; i++) + { + if (FLI[i].Flags & LIF_CHECKED) + { + if (liFirst == -1) + liFirst = i; + liSelected++; + } + } + + if (liSelected <= 1) + { + int liAction = (Param2 == KEY_ENTER) ? Opt.EnterAction : Opt.ShiftEnterAction; + int pos = (liFirst == -1) ? static_cast(Info.SendDlgMessage(hDlg,DM_LISTGETCURPOS,LIST_BOX,NULL)) : liFirst; + liChanged = ExecuteEntry(pos, liAction, (Opt.RunLowPriority!=0)); + } + else + { + int liAction = (Param2 == KEY_ENTER) ? Opt.EnterAction : Opt.ShiftEnterAction; + bool LowPriority = (Opt.RunLowPriority!=0); + + // - + if (liAction == Action_Menu) + { + if (EntryMenu(0, liAction, LowPriority, liSelected) < 0) + return TRUE; + } + else if (liAction == Action_Uninstall) + liAction = Action_UninstallWait; + else if (liAction == Action_Modify) + liAction = Action_ModifyWait; + else if (liAction == Action_Repair) + liAction = Action_RepairWait; + + for (int pos = 0; pos < nCount; pos++) + { + if (!(FLI[pos].Flags & LIF_CHECKED)) + continue; + struct FarListPos FLP; + FLP.SelectPos = pos; + FLP.TopPos = -1; + Info.SendDlgMessage(hDlg,DM_LISTSETCURPOS,LIST_BOX,reinterpret_cast(&FLP)); + int li = ExecuteEntry(pos, liAction, LowPriority); + if (li == -1) + break; // + if (li == 1) + liChanged = 1; + } + } + if (liChanged == 1) + { Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); + } } } return TRUE; @@ -273,6 +380,7 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) return TRUE; case KEY_F3: + case KEY_F4: { if (ListSize) { @@ -282,6 +390,13 @@ static LONG_PTR WINAPI DlgProc(HANDLE hDlg,int Msg,int Param1,LONG_PTR Param2) } return TRUE; + case KEY_F2: + { + Opt.SortByDate = !Opt.SortByDate; + Info.SendDlgMessage(hDlg,DMU_UPDATE,1,0); + } + return TRUE; + case KEY_BS: { if (lstrlen(Filter)) @@ -372,12 +487,14 @@ int WINAPI Configure(int ItemNumber) //BOOL bEnterWaitCompletion = (Opt.EnterFunction != 0); BOOL bUseElevation = (Opt.UseElevation != 0); BOOL bLowPriority = (Opt.RunLowPriority != 0); + BOOL bForceMsiUse = (Opt.ForceMsiUse != 0); Config.AddCheckbox(MShowInEditor, &bShowInEditor); Config.AddCheckbox(MShowInViewer, &bShowInViewer); //Config.AddCheckbox(MEnterWaitCompletion, &bEnterWaitCompletion); Config.AddCheckbox(MUseElevation, &bUseElevation); Config.AddCheckbox(MLowPriority, &bUseElevation); + Config.AddCheckbox(MForceMsiUse, &bForceMsiUse); Config.AddSeparator(); @@ -411,12 +528,14 @@ int WINAPI Configure(int ItemNumber) //Opt.EnterFunction = bEnterWaitCompletion; Opt.UseElevation = bUseElevation; Opt.RunLowPriority = bLowPriority; + Opt.ForceMsiUse = bForceMsiUse; SetRegKey(HKCU,_T(""),_T("WhereWork"),(DWORD) Opt.WhereWork); SetRegKey(HKCU,_T(""),_T("EnterAction"),(DWORD) Opt.EnterAction); SetRegKey(HKCU,_T(""),_T("ShiftEnterAction"),(DWORD) Opt.ShiftEnterAction); SetRegKey(HKCU,_T(""),_T("UseElevation"),(DWORD) Opt.UseElevation); SetRegKey(HKCU,_T(""),_T("RunLowPriority"),(DWORD) Opt.RunLowPriority); + SetRegKey(HKCU,_T(""),_T("ForceMsiUse"),(DWORD) Opt.ForceMsiUse); } return FALSE; diff --git a/Uninstall/src/UnInstall.hpp b/Uninstall/src/UnInstall.hpp index 15cc78b..14e5659 100644 --- a/Uninstall/src/UnInstall.hpp +++ b/Uninstall/src/UnInstall.hpp @@ -64,7 +64,8 @@ struct RegKeyPath { { HKEY_CURRENT_USER, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall") }, { HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall") }, }; -int nCount, nRealCount; +int nCount; // +int nRealCount; // FarList FL; FarListItem* FLI = NULL; int ListSize; @@ -78,6 +79,8 @@ struct Options int ShiftEnterAction; // enum ActionEnum int UseElevation; //<- TechInfo int RunLowPriority; + int ForceMsiUse; + bool SortByDate; } Opt; struct KeyInfo @@ -90,6 +93,7 @@ struct KeyInfo RegKeyPath RegKey; FILETIME RegTime; TCHAR InstDate[10]; + DWORD InstDateN; REGSAM RegView; TCHAR SubKeyName[MAX_PATH]; bool WindowsInstaller; @@ -158,8 +162,9 @@ bool FillReg(KeyInfo& key, TCHAR* Buf, RegKeyPath& RegKey, REGSAM RegView) SYSTEMTIME st; FILETIME ft; FileTimeToLocalFileTime(&key.RegTime, &ft); FileTimeToSystemTime(&ft, &st); - wsprintf(sKeyTime, _T(" / %02u.%02u.%04u %u:%02u:%02u"), st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond); - wsprintf(key.InstDate, _T("%02u.%02u.%02u"), st.wDay, st.wMonth, (st.wYear % 100)); + StringCchPrintf(sKeyTime, ARRAYSIZE(sKeyTime), _T(" / %02u.%02u.%04u %u:%02u:%02u"), st.wDay, st.wMonth, st.wYear, st.wHour, st.wMinute, st.wSecond); + StringCchPrintf(key.InstDate, ARRAYSIZE(key.InstDate), _T("%02u.%02u.%02u"), st.wDay, st.wMonth, (st.wYear % 100)); + key.InstDateN = ((st.wYear & 0xFFFF) << 16) | ((st.wMonth & 0xFF) << 8) | (st.wDay & 0xFF); nKeyTimeLen = lstrlen(sKeyTime) + 1; } for (int i=0;i 1) + items[Action_Uninstall].Flags |= MIF_DISABLE; + SETITEM(Action_ModifyWait, MActionModifyWait); + SETITEM(Action_Modify, MActionModify); + if (nChkCount > 1) + items[Action_Modify].Flags |= MIF_DISABLE; + else if (!p[Sel].CanModify) { - #ifdef FARAPI18 - #define SETITEM(i,s) items[i].Text = GetMsg(s) - #else - #define SETITEM(i,s) items[i].Text.TextPtr = GetMsg(s); items[i].Flags |= MIF_USETEXTPTR - #endif - FarMenuItemEx items[6]; memset(items, 0, sizeof(items)); - SETITEM(Action_UninstallWait, MActionUninstallWait); - SETITEM(Action_Uninstall, MActionUninstall); - SETITEM(Action_ModifyWait, MActionModifyWait); - SETITEM(Action_Modify, MActionModify); - if (!p[Sel].CanModify) - { - items[Action_Modify].Flags |= MIF_DISABLE; - items[Action_ModifyWait].Flags |= MIF_DISABLE; - } - SETITEM(Action_RepairWait, MActionRepairWait); - SETITEM(Action_Repair, MActionRepair); - if (!p[Sel].CanRepair) - { - items[Action_Repair].Flags |= MIF_DISABLE; - items[Action_RepairWait].Flags |= MIF_DISABLE; - } - - int iRc; - int BreakCode; - int BreakKeys[2]={VK_F7,0}; + items[Action_Modify].Flags |= MIF_DISABLE; + items[Action_ModifyWait].Flags |= MIF_DISABLE; + } + SETITEM(Action_RepairWait, MActionRepairWait); + SETITEM(Action_Repair, MActionRepair); + if (nChkCount > 1) + items[Action_Repair].Flags |= MIF_DISABLE; + else if (!p[Sel].CanRepair) + { + items[Action_Repair].Flags |= MIF_DISABLE; + items[Action_RepairWait].Flags |= MIF_DISABLE; + } + + int iRc; + int BreakCode; + int BreakKeys[2]={VK_F7,0}; + TCHAR szMenuTitle[MAX_PATH]; + + if (nChkCount > 1) + StringCchPrintf(szMenuTitle, ARRAYSIZE(szMenuTitle), GetMsg(MMenuTopLineN), nChkCount); + else + StringCchCopy(szMenuTitle, ARRAYSIZE(szMenuTitle), GetMsg(MMenuTopLine)); - while (true) + while (true) + { + iRc = Info.Menu(Info.ModuleNumber, -1,-1,0, FMENU_USEEXT|FMENU_WRAPMODE, szMenuTitle, + GetMsg(LowPriority ? MMenuBottomLine2 : MMenuBottomLine1), + _T("ActionMenu"), BreakKeys, &BreakCode, (struct FarMenuItem *)items, ARRAYSIZE(items)); + if (iRc < 0) + return -1; + if (BreakCode == 0) { - iRc = Info.Menu(Info.ModuleNumber, -1,-1,0, FMENU_USEEXT|FMENU_WRAPMODE, GetMsg(MMenuTopLine), - GetMsg(LowPriority ? MMenuBottomLine2 : MMenuBottomLine1), - _T("ActionMenu"), BreakKeys, &BreakCode, (struct FarMenuItem *)items, ARRAYSIZE(items)); - if (iRc < 0) - return -1; - if (BreakCode == 0) + LowPriority = !LowPriority; + for (UINT i = 0; i < ARRAYSIZE(items); i++) { - LowPriority = !LowPriority; - } - else - { - Action = iRc; - break; + if (i == iRc) + items[i].Flags |= MIF_SELECTED; + else + items[i].Flags &= ~MIF_SELECTED; } } + else + { + Action = iRc; + break; + } + } + + if ((Action & 0xFF) == Action_Menu) + return -1; // + + return Action; +} +int ExecuteEntry(int Sel, int Action, bool LowPriority) +{ + if ((Action & 0xFF) == Action_Menu) + { + if (EntryMenu(Sel, Action, LowPriority) < 0) + return -1; if ((Action & 0xFF) == Action_Menu) return -1; // } @@ -600,8 +635,17 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) si.cb = sizeof(si); ZeroMemory(&pi, sizeof(pi)); - TCHAR cmd_line[MAX_PATH*2+1], cmd_file[MAX_PATH+1], cmd_parm[MAX_PATH+1]; - if (p[Sel].WindowsInstaller) + TCHAR cmd_line[MAX_PATH*2+1], cmd_file[MAX_PATH+1], cmd_parm[MAX_PATH*2+1]; + LPCTSTR pszString = p[Sel].Keys[UninstallString]; + if ((Action == Action_ModifyWait) || (Action == Action_Modify)) + pszString = p[Sel].Keys[ModifyPath]; + else if ((Action == Action_RepairWait) || (Action == Action_Repair)) + pszString = NULL; + if (pszString && !*pszString) + pszString = NULL; + + + if (p[Sel].WindowsInstaller && !(!Opt.ForceMsiUse && pszString)) { TCHAR szCode[5]; if ((Action == Action_UninstallWait) || (Action == Action_Uninstall)) @@ -615,39 +659,57 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) StringCchCat(cmd_line, ARRAYSIZE(cmd_line), szCode); StringCchCat(cmd_line, ARRAYSIZE(cmd_line), p[Sel].SubKeyName); // ShellExecuteEx - StringCchCopy(cmd_file, ARRAYSIZE(cmd_file), _T("msiexec")); - StringCchCopy(cmd_parm, ARRAYSIZE(cmd_parm), szCode); - StringCchCat(cmd_parm, ARRAYSIZE(cmd_parm), p[Sel].SubKeyName); + if (LowPriority) + { + StringCchCopy(cmd_file, ARRAYSIZE(cmd_parm), _T("cmd")); + StringCchCopy(cmd_parm, ARRAYSIZE(cmd_parm), _T("/c start /low ")); + StringCchCat(cmd_parm, ARRAYSIZE(cmd_parm), _T("msiexec")); + StringCchCat(cmd_parm, ARRAYSIZE(cmd_parm), szCode); + StringCchCat(cmd_parm, ARRAYSIZE(cmd_parm), p[Sel].SubKeyName); + } + else + { + StringCchCopy(cmd_file, ARRAYSIZE(cmd_file), _T("msiexec")); + StringCchCopy(cmd_parm, ARRAYSIZE(cmd_parm), szCode); + StringCchCat(cmd_parm, ARRAYSIZE(cmd_parm), p[Sel].SubKeyName); + } } else { - LPCTSTR pszString = p[Sel].Keys[UninstallString]; - if ((Action == Action_ModifyWait) || (Action == Action_Modify)) - pszString = p[Sel].Keys[ModifyPath]; - else if ((Action == Action_RepairWait) || (Action == Action_Repair)) - return -1; + if (pszString == NULL) + return 0; // CreateProcess StringCchCopy(cmd_line, ARRAYSIZE(cmd_line), pszString); // ShellExecuteEx - LPCTSTR psNextArg = NULL; - if (FirstArg(pszString, cmd_file, &psNextArg) - && IsFilePath(cmd_file)) + if (LowPriority) { - StringCchCopy(cmd_parm, ARRAYSIZE(cmd_parm), psNextArg); + StringCchCopy(cmd_file, ARRAYSIZE(cmd_parm), _T("cmd")); + StringCchCopy(cmd_parm, ARRAYSIZE(cmd_parm), _T("/c start /low \"\" ")); + StringCchCat(cmd_parm, ARRAYSIZE(cmd_parm), pszString); } else { - StringCchCopy(cmd_file, ARRAYSIZE(cmd_file), pszString); - cmd_parm[0] = 0; + LPCTSTR psNextArg = NULL; + if (FirstArg(pszString, cmd_file, &psNextArg) + && IsFilePath(cmd_file)) + { + StringCchCopy(cmd_parm, ARRAYSIZE(cmd_parm), psNextArg); + } + else + { + StringCchCopy(cmd_file, ARRAYSIZE(cmd_file), pszString); + cmd_parm[0] = 0; + } } } hScreen = Info.SaveScreen(0,0,-1,-1); // , .. - BOOL ifCreate = FALSE, bElevationFailed = false; + BOOL ifCreate = FALSE, bElevationFailed = FALSE, bPriorityChanged = FALSE; + DWORD dwErr = 0; // MSI - if (!p[Sel].WindowsInstaller && Opt.UseElevation) + if (!p[Sel].WindowsInstaller && Opt.UseElevation && !IsUserAdmin()) { // Required elevation SHELLEXECUTEINFO sei = {sizeof(SHELLEXECUTEINFO)}; @@ -655,7 +717,7 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) sei.lpVerb = _T("runas"); sei.lpFile = cmd_file; sei.lpParameters = cmd_parm; - sei.nShow = SW_SHOWNORMAL; + sei.nShow = LowPriority ? SW_MINIMIZE : SW_SHOWNORMAL; ifCreate = ShellExecuteEx(&sei); if (ifCreate) pi.hProcess = sei.hProcess; @@ -673,17 +735,19 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) NULL, // Process handle not inheritable. NULL, // Thread handle not inheritable. FALSE, // Set handle inheritance to FALSE. - 0, // No creation flags. + LowPriority ? IDLE_PRIORITY_CLASS : NORMAL_PRIORITY_CLASS, // Creation flags. NULL, // Use parent's environment block. NULL, // Use parent's starting directory. &si, // Pointer to STARTUPINFO structure. &pi // Pointer to PROCESS_INFORMATION structure. ); + if (ifCreate) + bPriorityChanged = TRUE; } if (!ifCreate) //not Create { - DWORD dwErr = GetLastError(); + dwErr = GetLastError(); if ((dwErr == 0x2E4) && !bElevationFailed) { // Required elevation @@ -692,7 +756,7 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) sei.lpVerb = _T("runas"); sei.lpFile = cmd_file; sei.lpParameters = cmd_parm; - sei.nShow = SW_SHOWNORMAL; + sei.nShow = LowPriority ? SW_MINIMIZE : SW_SHOWNORMAL; ifCreate = ShellExecuteEx(&sei); if (ifCreate) pi.hProcess = sei.hProcess; @@ -706,7 +770,7 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) if (dwErr == 0x000004C7) pszErrInfo = GetMsg(MCancelledByUser); else - wsprintf(szErrCode, _T("ErrorCode=0x%08X"), dwErr); + StringCchPrintf(szErrCode, ARRAYSIZE(szErrCode), _T("ErrorCode=0x%08X"), dwErr); if (hScreen) Info.RestoreScreen(hScreen); DrawMessage(FMSG_WARNING, 1, "%s",GetMsg(MPlugIn),GetMsg(MRunProgErr),cmd_line,pszErrInfo,GetMsg(MBtnOk),NULL); @@ -714,10 +778,12 @@ int ExecuteEntry(int Sel, int Action, bool LowPriority) } } - if (pi.hProcess && LowPriority) - { - SetPriorityClass(pi.hProcess, IDLE_PRIORITY_CLASS); - } + // -- , Elevation, Elevation - CreateProcess + //if (pi.hProcess && LowPriority && !bPriorityChanged) + //{ + // bPriorityChanged = SetPriorityClass(pi.hProcess, IDLE_PRIORITY_CLASS); + // dwErr = GetLastError(); + //} TCHAR SaveTitle[MAX_PATH]; GetConsoleTitle(SaveTitle,ARRAYSIZE(SaveTitle)); @@ -787,6 +853,15 @@ int __cdecl CompareEntries(const void* item1, const void* item2) { return FSF.LStricmp(reinterpret_cast(item1)->Keys[DisplayName], reinterpret_cast(item2)->Keys[DisplayName]); } +// +int __cdecl CompareEntriesDate(const void* item1, const void* item2) +{ + if (reinterpret_cast(item1)->InstDateN < reinterpret_cast(item2)->InstDateN) + return 1; + if (reinterpret_cast(item1)->InstDateN > reinterpret_cast(item2)->InstDateN) + return -1; + return CompareEntries(item1, item2); +} #define JUMPREALLOC 50 void EnumKeys(RegKeyPath& RegKey, REGSAM RegView = 0) { @@ -854,7 +929,10 @@ void UpDateInfo(void) } } p = (KeyInfo *) realloc(p, sizeof(KeyInfo) * nCount); - FSF.qsort(p, nCount, sizeof(KeyInfo), CompareEntries); + if (Opt.SortByDate) + FSF.qsort(p, nCount, sizeof(KeyInfo), CompareEntriesDate); + else + FSF.qsort(p, nCount, sizeof(KeyInfo), CompareEntries); FLI = (FarListItem *) realloc(FLI, sizeof(FarListItem) * nCount); ZeroMemory(FLI, sizeof(FarListItem) * nCount); @@ -961,4 +1039,11 @@ void ReadRegistry() if ((Opt.RunLowPriority<0) || (Opt.RunLowPriority>1)) Opt.RunLowPriority=0; SetRegKey(HKCU,_T(""),_T("RunLowPriority"),(DWORD) Opt.RunLowPriority); + + if (GetRegKey(HKCU,_T(""),_T("ForceMsiUse"),Opt.ForceMsiUse,1)) + if ((Opt.ForceMsiUse<0) || (Opt.ForceMsiUse>1)) + Opt.ForceMsiUse=0; + SetRegKey(HKCU,_T(""),_T("ForceMsiUse"),(DWORD) Opt.ForceMsiUse); + + Opt.SortByDate = false; } diff --git a/Uninstall/src/UnInstall.vcproj b/Uninstall/src/UnInstall.vcproj index 499816c..3ef7de0 100644 --- a/Uninstall/src/UnInstall.vcproj +++ b/Uninstall/src/UnInstall.vcproj @@ -325,6 +325,14 @@ + + + + diff --git a/Uninstall/src/UnInstall_Eng.hlf b/Uninstall/src/UnInstall_Eng.hlf index 278eef2..28e139c 100644 --- a/Uninstall/src/UnInstall_Eng.hlf +++ b/Uninstall/src/UnInstall_Eng.hlf @@ -1,10 +1,23 @@ .Language=English,English .PluginContents=<(NAME)> +.Options CtrlStartPosChar=^ @Contents $^#<(NAME)> <(VER_MAJOR)>.<(VER_MINOR)>.<(VER_PATCH)># $^#Contents# + #Columns# + #1# #2# #3# #4# + Mx86 06.11.10 WMR- Microsoft .NET Framework 4 Multi-Targeting Pack + #Column 1# ^Registry place, where item information was found. + ^In x86 OS it is HKLM or HKCU, x64 OS - Mx86, Mx64, HKCU. + #Column 2# ^Program install date. + #Column 3# ^Flags. «W» - MSI, «M» «Modify» allowed, «R» repair, + ^«-» marks "hidden" elements. + #Column 4# ^Program name. + + + #Controls# To add a symbol to the filter #Symbolical keys# Paste to filter from clipboard #Shift-Ins, Ctrl-V# @@ -19,11 +32,15 @@ $^#Contents# To update the list #Ctrl-R# + Sort items (by name/by date) #F2# + To choose item of a list #Alt-'highlighted letter'# - To start the setup program #Enter or Shift-Enter# - When checkbox '~Enter: wait for completion~@Configuration@' is checked, - #Enter# waits for program completion, #Shift-Enter# do not, and vice versa. + Mark item for batch processing #Ins# or #RClick# + + To start processing #Enter or Shift-Enter# + Actions (Uninstall, Modify, Repair, Menu and Wait/Don't Wait) + are specified in ~Configuration~@Configuration@ Open Configuration dialog #Alt-Shift-F9# @@ -39,12 +56,23 @@ $^#Configuration# #Show in the Editor#, #Show in the Viewer# Allows plugin in Editor or Viewer. Plugin always allowed for panels. - #Enter: wait for completion# - When checked, #Enter# waits for program completion, #Shift-Enter# do not, and vice versa. - #Use elevation# Request elevation (UAC) before starting non Windows Installer setup programs. + #Start with low priority# + Try to start uninstall in process low priority mode. + + #Force use MsiExec# + Has effect for MSI only. When unchecked and command line specified obviuosly +in the registry - this command will be used instead of «msiexec /?{GUID}». + + #Enter# and #Shift-Enter# + You may choose one of the following actions: + * Uninstall (wait), Uninstall - Uninstall program + * Modify (wait), Modify - Modify (may be not available) + * Repair (wait), Repair - Repair (only for MSI) + * Menu - Choose action in run time + ~Contents~@Contents@ @UninstallEntry diff --git a/Uninstall/src/UnInstall_Eng.lng b/Uninstall/src/UnInstall_Eng.lng index 50b0b0f..71f1ba1 100644 --- a/Uninstall/src/UnInstall_Eng.lng +++ b/Uninstall/src/UnInstall_Eng.lng @@ -13,6 +13,7 @@ "Enter: &wait for completion" "&Use elevation" "Start with &low priority" +"&Force use MsiExec" "Ente&r: " "Shif&t-Enter:" "Uninstall (wait)" @@ -38,11 +39,12 @@ "&Version:" "Install &date:" // Menu's top and bottom lines -"[Shift-]Enter: run, F8: del entry, F3: info, Ctrl-R: update" +"[Shift-]Enter: run, F8: del entry, F2: sort, F3: info, Ctrl-R: update" "Filter: [%s], Entries: [%d/%d]" "{Normal priority} F7" -"{Low priority} F7" +" {Low priority} F7" "Select action" +"Action for %u items" // Install location (registry) "Mx86" "Mx64" diff --git a/Uninstall/src/UnInstall_Rus.hlf b/Uninstall/src/UnInstall_Rus.hlf index 7ddb294..33134da 100644 --- a/Uninstall/src/UnInstall_Rus.hlf +++ b/Uninstall/src/UnInstall_Rus.hlf @@ -1,10 +1,24 @@ .Language=Russian,Russian .PluginContents=Удаление программ +.Options CtrlStartPosChar=^ @Contents $^#<(NAME)> <(VER_MAJOR)>.<(VER_MINOR)>.<(VER_PATCH)># $^#Содержание# + #Колонки# + #1# #2# #3# #4# + Mx86 06.11.10 WMR- Microsoft .NET Framework 4 Multi-Targeting Pack + #Колонка 1# ^Место в реестре, где найдена запись о приложении. + ^В x86 ОС здесь может быть HKLM или HKCU, в x64 ОС - Mx86, Mx64, HKCU. + #Колонка 2# ^Дата установки программы. + #Колонка 3# ^Флаги. «W» - MSI, «M» доступно «Измнение», «R» восстановление, + ^«-» помечаются "скрытые" элементы. + #Колонка 4# ^Название программы. + + + #Управление# + Добавить символ к фильтру #Символьные клавиши# Вставить в фильтр из буфера обмена #Shift-Ins, Ctrl-V# @@ -19,13 +33,15 @@ $^#Содержание# Обновить список #Ctrl-R# + Изменить сортировку (по имени/по дате) #F2# + Выбрать пункт списка #Alt-'подсвеченная буква'# + Пометить пункт списка для пакетной обработки #Ins# или #RClick# + Запустить программу-установщик #Enter or Shift-Enter# - Если в ~настройках плагина~@Configuration@ включен флажок - #Enter: ожидать завершения#, то по #Enter# плагин ожидает - завершения программы-установщика, #Shift-Enter# не ожидает, - и наоборот. + Действие (Удаление, Измнение, Восстановление, Меню и ждать/не ждать) + указываются в ~настройке плагина~@Configuration@ Открыть диалог настроек плагина #Alt-Shift-F9# @@ -41,13 +57,24 @@ $^#Настройка плагина# #Показывать в редакторе#, #Показывать в просмотрщике# Разрешает вызов плагина из окна редактора или просмотрщика. Для панелей - разрешено всегда. - #Enter: ожидать завершения# - Если флажок включен, #Enter# ожидает завершения программы-установщика, -#Shift-Enter# не ожидает, и наоборот. - #Повышать полномочия# Запрашивать повышение полномочий (UAC) перед запуском #не# Windows Installer установщиков. + #Запуск с низким приоритетом# + Пытаться запустить Uninstall с низким приоритетом. + + #Всегда использовать MsiExec# + Имеет эффект только для MSI инсталляторов. Если флажок выключен и в реестре +явно указана командная строка запуска, то она будет использована +вместо «msiexec /?{GUID}». + + #Enter# и #Shift-Enter# + Здесь можно выбрать один из следующих вариантов: + * Удаление (ждать), Удаление - выполнить Uninstall + * Изменить (ждать), Изменить - Modify (может быть не доступно для некторых программ) + * Восстановить (ждать), Восстановить - Repair (доступно только для MSI) + * Меню - Выбор действия через меню + ~Содержание~@Contents@ @UninstallEntry diff --git a/Uninstall/src/UnInstall_Rus.lng b/Uninstall/src/UnInstall_Rus.lng index 8e3273c..76dd41d 100644 --- a/Uninstall/src/UnInstall_Rus.lng +++ b/Uninstall/src/UnInstall_Rus.lng @@ -13,6 +13,7 @@ "Enter: &ожидать завершения" "Повышать полномочи&я" "Запуск с &низким приоритетом" +"&Всегда использовать MsiExec" "Ente&r: " "Shif&t-Enter:" "Удаление (ждать)" @@ -38,11 +39,12 @@ "&Версия:" "Д&ата установки:" // Menu's top and bottom lines -"[Shift-]Enter: run, F8: del entry, F3: info, Ctrl-R: update" +"[Shift-]Enter: run, F8: del entry, F2: sort, F3: info, Ctrl-R: update" "Filter: [%s], Entries: [%d/%d]" "{Normal priority} F7" -"{Low priority} F7" +" {Low priority} F7" "Выберите действие" +"Действие для %u элементов" // Install location (registry) "Mx86" "Mx64" diff --git a/Uninstall/src/WhatsNew.Rus.txt b/Uninstall/src/WhatsNew.Rus.txt index 247ac55..6a3f47c 100644 --- a/Uninstall/src/WhatsNew.Rus.txt +++ b/Uninstall/src/WhatsNew.Rus.txt @@ -1,7 +1,13 @@ -v1.10.10 - - в списке 'Entries' для Enter/ShiftEnter можно указать одно из следующих действий: Menu/Uninstall[Wait]/Modify[Wait]/Repair[Wait] +v1.10.11 + - в настройке добавлен флажок '[x] Force use MsiExec', при его отключении и наличия в реестре 'UninstallString/ModifyPath' выполняется команда, указанная в реестре, вместо вызова "msiexec" - в настройке можно указать '[x] Start with low priority' - если выбрано Menu - можно нажать F7 для смены приоритета запускаемого процесса + - при очистке фильтра не прыгаем в начало списка + - возможность пакетного UnInstall: Ins или RClick - пометка элементов + - F2 в списке программ меняет сортировку (по имени/по дате) + +v1.10.10 + - в списке 'Entries' для Enter/ShiftEnter можно указать одно из следующих действий: Menu/Uninstall[Wait]/Modify[Wait]/Repair[Wait] % при включенном '[x] Use elevation' возникала ошибка запуска v1.10.9 diff --git a/Uninstall/src/_lang.cmd b/Uninstall/src/_lang.cmd index 619ec6b..0d73874 100644 --- a/Uninstall/src/_lang.cmd +++ b/Uninstall/src/_lang.cmd @@ -1,3 +1,4 @@ @echo off cd /d "%~dp0" tools\lng.generator.exe -nc -i lang.ini -ol Lang.templ +copy *.lng ..\debug \ No newline at end of file diff --git a/Uninstall/src/farsdk/ansi/plugin.hpp b/Uninstall/src/farsdk/ansi/plugin.hpp index d41c7a2..8593b2a 100644 --- a/Uninstall/src/farsdk/ansi/plugin.hpp +++ b/Uninstall/src/farsdk/ansi/plugin.hpp @@ -1613,7 +1613,7 @@ typedef struct FarStandardFunctions FARSTDITOA itoa; FARSTDITOA64 itoa64; // - FARSTDSPRINTF sprintf; + FARSTDSPRINTF sprintf_; FARSTDSSCANF sscanf; // FARSTDQSORT qsort; diff --git a/Uninstall/src/farsdk/unicode/plugin.hpp b/Uninstall/src/farsdk/unicode/plugin.hpp index f04a432..6e2790c 100644 --- a/Uninstall/src/farsdk/unicode/plugin.hpp +++ b/Uninstall/src/farsdk/unicode/plugin.hpp @@ -1677,7 +1677,7 @@ typedef struct FarStandardFunctions FARSTDITOA itoa; FARSTDITOA64 itoa64; // - FARSTDSPRINTF sprintf; + FARSTDSPRINTF sprintf_; FARSTDSSCANF sscanf; // FARSTDQSORT qsort; diff --git a/Uninstall/src/lang.ini b/Uninstall/src/lang.ini index bb4fe85..7d338f3 100644 --- a/Uninstall/src/lang.ini +++ b/Uninstall/src/lang.ini @@ -1,6 +1,6 @@ [.\UnInstall_Rus.lng] -CRC32=1621171643 +CRC32=923951818 [.\UnInstall_Eng.lng] -CRC32=1234522779 +CRC32=-957510700 [.\FarLang.h] -CRC32=129256637 +CRC32=2016355900 diff --git a/Uninstall/src/project.ini b/Uninstall/src/project.ini index 46b4cef..fd8a6a5 100644 --- a/Uninstall/src/project.ini +++ b/Uninstall/src/project.ini @@ -2,4 +2,4 @@ MODULE = UnInstall VER_MAJOR = 1 VER_MINOR = 10 -VER_PATCH = 10 +VER_PATCH = 11