[RAPPS][RAPPS.COM] Introduce a rapps console shim

rapps.com will be launched when running 'rapps' from cmd or
from run, and since it is a console application, explorer/ cmd will
wait for it.
This rapps.com passes the commandline to rapps.exe,
and wait for rapps.exe to exit before closing.

CORE-17281
This commit is contained in:
Mark Jansen 2020-09-20 22:18:08 +02:00
parent 4ffd9fb3a0
commit 964c22c1ca
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B
11 changed files with 127 additions and 41 deletions

View file

@ -30,6 +30,7 @@ add_subdirectory(network)
add_subdirectory(notepad) add_subdirectory(notepad)
add_subdirectory(osk) add_subdirectory(osk)
add_subdirectory(rapps) add_subdirectory(rapps)
add_subdirectory(rapps_com)
add_subdirectory(regedit) add_subdirectory(regedit)
add_subdirectory(regedt32) add_subdirectory(regedt32)
add_subdirectory(sc) add_subdirectory(sc)

View file

@ -41,7 +41,7 @@ add_definitions(
file(GLOB_RECURSE rapps_rc_deps res/*.*) file(GLOB_RECURSE rapps_rc_deps res/*.*)
add_rc_deps(rapps.rc ${rapps_rc_deps}) add_rc_deps(rapps.rc ${rapps_rc_deps})
add_executable(rapps ${SOURCE} rapps.rc) add_executable(rapps ${SOURCE} rapps.rc)
set_module_type(rapps win32cui UNICODE) set_module_type(rapps win32gui UNICODE)
target_link_libraries(rapps conutils ${PSEH_LIB} uuid wine cpprt atl_classes) target_link_libraries(rapps conutils ${PSEH_LIB} uuid wine cpprt atl_classes)
add_importlibs(rapps advapi32 comctl32 gdi32 wininet user32 shell32 shlwapi ole32 setupapi gdiplus msvcrt kernel32 ntdll) add_importlibs(rapps advapi32 comctl32 gdi32 wininet user32 shell32 shlwapi ole32 setupapi gdiplus msvcrt kernel32 ntdll)
add_pch(rapps include/rapps.h SOURCE) add_pch(rapps include/rapps.h SOURCE)

View file

@ -58,8 +58,14 @@ HIMAGELIST CMainToolbar::InitImageList()
return hImageList; return hImageList;
} }
CMainToolbar::CMainToolbar() : m_iToolbarHeight(24) CMainToolbar::CMainToolbar()
: m_iToolbarHeight(24)
, m_dButtonsWidthMax(0)
{ {
memset(szInstallBtn, 0, sizeof(szInstallBtn));
memset(szUninstallBtn, 0, sizeof(szUninstallBtn));
memset(szModifyBtn, 0, sizeof(szModifyBtn));
memset(szSelectAll, 0, sizeof(szSelectAll));
} }
VOID CMainToolbar::OnGetDispInfo(LPTOOLTIPTEXT lpttt) VOID CMainToolbar::OnGetDispInfo(LPTOOLTIPTEXT lpttt)

View file

@ -7,15 +7,13 @@
* Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org) * Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
* Copyright 2020 He Yang (1160386205@qq.com) * Copyright 2020 He Yang (1160386205@qq.com)
*/ */
#include "rapps.h" #include "rapps.h"
#include "available.h" #include "available.h"
#include "misc.h" #include "misc.h"
#include "dialogs.h" #include "dialogs.h"
#include <atlcoll.h>
#include <atlsimpcoll.h>
#include <atlstr.h>
// CAvailableApplicationInfo // CAvailableApplicationInfo
CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW& sFileNameParam, AvailableStrings& AvlbStrings) CAvailableApplicationInfo::CAvailableApplicationInfo(const ATL::CStringW& sFileNameParam, AvailableStrings& AvlbStrings)

View file

@ -5,6 +5,8 @@
#define CMD_KEY_FIND L"FIND" #define CMD_KEY_FIND L"FIND"
#define CMD_KEY_INFO L"INFO" #define CMD_KEY_INFO L"INFO"
#define CMD_KEY_HELP L"?" #define CMD_KEY_HELP L"?"
#define CMD_KEY_HELP_ALT L"HELP"
const WCHAR UsageString[] = L"RAPPS \ const WCHAR UsageString[] = L"RAPPS \
[/" CMD_KEY_HELP L"] \ [/" CMD_KEY_HELP L"] \

View file

@ -20,28 +20,36 @@ BOOL MatchCmdOption(LPWSTR argvOption, LPCWSTR szOptToMacth)
{ {
if (argvOption[0] == FirstCharList[i]) if (argvOption[0] == FirstCharList[i])
{ {
if (StrCmpIW(argvOption + 1, szOptToMacth) == 0) return StrCmpIW(argvOption + 1, szOptToMacth) == 0;
{
return TRUE;
}
else
{
return FALSE;
}
} }
} }
return FALSE; return FALSE;
} }
void InitRappsConsole()
{
// First, try to attach to our parent's console
if (!AttachConsole(ATTACH_PARENT_PROCESS))
{
// Did we already have a console?
if (GetLastError() != ERROR_ACCESS_DENIED)
{
// No, try to open a new one
AllocConsole();
}
}
ConInitStdStreams(); // Initialize the Console Standard Streams
}
BOOL HandleInstallCommand(LPWSTR szCommand, int argcLeft, LPWSTR * argvLeft) BOOL HandleInstallCommand(LPWSTR szCommand, int argcLeft, LPWSTR * argvLeft)
{ {
if (argcLeft == 0) if (argcLeft == 0)
{ {
ConInitStdStreams(); // Initialize the Console Standard Streams InitRappsConsole();
ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_PACKAGE_NAME, szCommand); ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_PACKAGE_NAME, szCommand);
return FALSE; return FALSE;
} }
FreeConsole();
ATL::CSimpleArray<ATL::CStringW> PkgNameList; ATL::CSimpleArray<ATL::CStringW> PkgNameList;
@ -70,11 +78,10 @@ BOOL HandleSetupCommand(LPWSTR szCommand, int argcLeft, LPWSTR * argvLeft)
{ {
if (argcLeft != 1) if (argcLeft != 1)
{ {
ConInitStdStreams(); // Initialize the Console Standard Streams InitRappsConsole();
ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_FILE_NAME, szCommand); ConResMsgPrintf(StdOut, NULL, IDS_CMD_NEED_FILE_NAME, szCommand);
return FALSE; return FALSE;
} }
FreeConsole();
ATL::CSimpleArray<ATL::CStringW> PkgNameList; ATL::CSimpleArray<ATL::CStringW> PkgNameList;
HINF InfHandle = SetupOpenInfFileW(argvLeft[0], NULL, INF_STYLE_WIN4, NULL); HINF InfHandle = SetupOpenInfFileW(argvLeft[0], NULL, INF_STYLE_WIN4, NULL);
@ -218,20 +225,14 @@ BOOL HandleInfoCommand(LPWSTR szCommand, int argcLeft, LPWSTR *argvLeft)
return TRUE; return TRUE;
} }
BOOL HandleHelpCommand(LPWSTR szCommand, int argcLeft, LPWSTR * argvLeft) VOID PrintHelpCommand()
{ {
if (argcLeft != 0)
{
return FALSE;
}
ConPrintf(StdOut, L"\n"); ConPrintf(StdOut, L"\n");
ConResPuts(StdOut, IDS_APPTITLE); ConResPuts(StdOut, IDS_APPTITLE);
ConPrintf(StdOut, L"\n\n"); ConPrintf(StdOut, L"\n\n");
ConResPuts(StdOut, IDS_CMD_USAGE); ConResPuts(StdOut, IDS_CMD_USAGE);
ConPrintf(StdOut, L"%ls\n", UsageString); ConPrintf(StdOut, L"%ls\n", UsageString);
return TRUE;
} }
BOOL ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow) BOOL ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
@ -246,10 +247,6 @@ BOOL ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
if (argc == 1) // RAPPS is launched without options if (argc == 1) // RAPPS is launched without options
{ {
// Close the console, and open MainWindow
FreeConsole();
// Check for if rapps MainWindow is already launched in another process // Check for if rapps MainWindow is already launched in another process
HANDLE hMutex; HANDLE hMutex;
@ -275,7 +272,8 @@ BOOL ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
return TRUE; return TRUE;
} }
else if (MatchCmdOption(argv[1], CMD_KEY_INSTALL))
if (MatchCmdOption(argv[1], CMD_KEY_INSTALL))
{ {
return HandleInstallCommand(argv[1], argc - 2, argv + 2); return HandleInstallCommand(argv[1], argc - 2, argv + 2);
} }
@ -284,8 +282,7 @@ BOOL ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
return HandleSetupCommand(argv[1], argc - 2, argv + 2); return HandleSetupCommand(argv[1], argc - 2, argv + 2);
} }
InitRappsConsole();
ConInitStdStreams(); // Initialize the Console Standard Streams
if (MatchCmdOption(argv[1], CMD_KEY_FIND)) if (MatchCmdOption(argv[1], CMD_KEY_FIND))
{ {
@ -295,14 +292,16 @@ BOOL ParseCmdAndExecute(LPWSTR lpCmdLine, BOOL bIsFirstLaunch, int nCmdShow)
{ {
return HandleInfoCommand(argv[1], argc - 2, argv + 2); return HandleInfoCommand(argv[1], argc - 2, argv + 2);
} }
else if (MatchCmdOption(argv[1], CMD_KEY_HELP)) else if (MatchCmdOption(argv[1], CMD_KEY_HELP) || MatchCmdOption(argv[1], CMD_KEY_HELP_ALT))
{ {
return HandleHelpCommand(argv[1], argc - 2, argv + 2); PrintHelpCommand();
return TRUE;
} }
else else
{ {
// unrecognized/invalid options // unrecognized/invalid options
ConResPuts(StdOut, IDS_CMD_INVALID_OPTION); ConResPuts(StdOut, IDS_CMD_INVALID_OPTION);
PrintHelpCommand();
return FALSE; return FALSE;
} }
} }

View file

@ -7,15 +7,10 @@
* Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org) * Copyright 2017 Alexander Shaposhnikov (sanchaez@reactos.org)
*/ */
#include "rapps.h" #include "rapps.h"
#include "unattended.h" #include "unattended.h"
#include "winmain.h" #include "winmain.h"
#include <atlcom.h> #include <atlcom.h>
#include <gdiplus.h> #include <gdiplus.h>
#include <conutils.h> #include <conutils.h>
LPCWSTR szWindowClass = L"ROSAPPMGR"; LPCWSTR szWindowClass = L"ROSAPPMGR";
@ -63,11 +58,11 @@ VOID InitializeGDIPlus(BOOL bInitialize)
} }
} }
int wmain(int argc, wchar_t *argv[]) INT WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, INT nShowCmd)
{ {
BOOL bIsFirstLaunch; BOOL bIsFirstLaunch;
InitializeAtlModule(GetModuleHandle(NULL), TRUE); InitializeAtlModule(hInstance, TRUE);
InitializeGDIPlus(TRUE); InitializeGDIPlus(TRUE);
if (GetUserDefaultUILanguage() == MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT)) if (GetUserDefaultUILanguage() == MAKELANGID(LANG_HEBREW, SUBLANG_DEFAULT))
@ -75,7 +70,7 @@ int wmain(int argc, wchar_t *argv[])
SetProcessDefaultLayout(LAYOUT_RTL); SetProcessDefaultLayout(LAYOUT_RTL);
} }
hInst = GetModuleHandle(NULL); hInst = hInstance;
bIsFirstLaunch = !LoadSettings(&SettingsInfo); bIsFirstLaunch = !LoadSettings(&SettingsInfo);
if (bIsFirstLaunch) if (bIsFirstLaunch)

View file

@ -0,0 +1,7 @@
project(rapps)
add_executable(rapps.com main.c rapps.rc)
set_module_type(rapps.com win32cui UNICODE)
set_target_properties(rapps.com PROPERTIES SUFFIX "")
add_importlibs(rapps.com msvcrt kernel32 ntdll)
add_cd_file(TARGET rapps.com DESTINATION reactos/system32 FOR all)

View file

@ -0,0 +1,73 @@
/*
* PROJECT: ReactOS Applications Manager Command-Line Launcher (rapps.com)
* LICENSE: GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
* PURPOSE: Allow explorer / cmd to wait for rapps.exe when passing commandline arguments
* COPYRIGHT: Copyright 2020 Mark Jansen (mark.jansen@reactos.org)
*/
#include <windef.h>
#include <winbase.h>
#include <strsafe.h>
int run_rapps(LPWSTR cmdline)
{
STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi = { 0 };
SetLastError(0);
if (!CreateProcessW(NULL, cmdline, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
fprintf(stderr, "Unable to create rapps.exe process...\n");
return -1;
}
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
DWORD dwExit;
GetExitCodeProcess(pi.hProcess, &dwExit);
CloseHandle(pi.hProcess);
return dwExit;
}
int wmain(int argc, wchar_t* argv[])
{
WCHAR RappsExe[MAX_PATH] = { 0 };
GetModuleFileNameW(NULL, RappsExe, ARRAYSIZE(RappsExe));
size_t arglen = wcslen(RappsExe);
if (arglen > 4 && !wcsicmp(RappsExe + arglen - 4, L".com"))
{
wcscpy(RappsExe + arglen - 4, L".exe");
}
else
{
fprintf(stderr, "Unable to build rapps.exe path...\n");
return - 1;
}
arglen += (1 + 2); // nullterminator + 2 quotes
for (int n = 1; n < argc; ++n)
{
arglen += wcslen(argv[n]);
arglen += 3; // Surrounding quotes + space
}
wchar_t* cmdline = LocalAlloc(LMEM_ZEROINIT, arglen * sizeof(WCHAR));
if (cmdline)
{
wchar_t* ptr = cmdline;
size_t cchRemaining = arglen;
StringCchPrintfExW(ptr, cchRemaining, &ptr, &cchRemaining, 0, L"\"%s\"", RappsExe);
for (int n = 1; n < argc; ++n)
{
StringCchPrintfExW(ptr, cchRemaining, &ptr, &cchRemaining, 0, L" \"%s\"", argv[n]);
}
}
int iRet = run_rapps(cmdline);
if (cmdline)
LocalFree(cmdline);
return iRet;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View file

@ -0,0 +1,5 @@
#define REACTOS_STR_FILE_DESCRIPTION "ReactOS Applications Manager console shim"
#define REACTOS_STR_INTERNAL_NAME "rapps"
#define REACTOS_STR_ORIGINAL_FILENAME "rapps.com"
#include <reactos/version.rc>