Merge pull request #1949 from daxgames/multi-user

Use user_conemu.xml or conemu-%computername%.xml directly if '-c [path]' is used to start cmder.
This commit is contained in:
Dax T Games 2018-11-28 19:04:05 -06:00 committed by GitHub
commit 22aa59bd83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 231 additions and 140 deletions

2
.gitignore vendored
View File

@ -13,6 +13,8 @@ vendor/*/*
config/*
!config/Readme.md
config_user/*
Thumbs.db
*.exe
*.dll

View File

@ -44,6 +44,9 @@ The Cmder's user interface is also designed to be more eye pleasing, and you can
| Argument | Description |
| ------------------- | ----------------------------------------------------------------------- |
| `/C [user_root_path]` | Individual user Cmder root folder. Example: `%userprofile%\cmder_config` |
| `/M` | Use `conemu-%computername%.xml` for ConEmu settings storage instead of `user_conemu.xml` |
| `/REGISTER [ALL, USER]` | Register a Windows Shell Menu shortcut. |
| `/UNREGISTER [ALL, USER]` | Un-register a Windows Shell Menu shortcut. |
| `/SINGLE` | Start Cmder in single mode. |
| `/START [start_path]` | Folder path to start in. |
| `/TASK [task_name]` | Task to start after launch. |

View File

@ -69,7 +69,7 @@ bool FileExists(const wchar_t * filePath)
return false;
}
void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstring taskName = L"", std::wstring cfgRoot = L"")
void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstring taskName = L"", std::wstring cfgRoot = L"", bool use_user_cfg = true)
{
#if USE_TASKBAR_API
wchar_t appId[MAX_PATH] = { 0 };
@ -91,6 +91,8 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
wchar_t userAliasesPath[MAX_PATH] = { 0 };
wchar_t legacyUserAliasesPath[MAX_PATH] = { 0 };
wchar_t args[MAX_PATH * 2 + 256] = { 0 };
wchar_t userConEmuCfgPath[MAX_PATH] = { 0 };
std::wstring cmderStart = path;
std::wstring cmderTask = taskName;
@ -147,7 +149,7 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
}
/*
Was -c [path] specified?
Was /c [path] specified?
*/
if (wcscmp(userConfigDirPath, L"") == 0)
{
@ -216,7 +218,9 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
// Set path to Cmder user ConEmu config file
PathCombine(userCfgPath, userConfigDirPath, L"user-ConEmu.xml");
if (PathFileExists(cpuCfgPath)) // config/ConEmu-%COMPUTERNAME%.xml file exists, use it.
if ( PathFileExists(cpuCfgPath) || use_user_cfg == false ) // config/ConEmu-%COMPUTERNAME%.xml file exists or /m was specified on command line, use machine specific config.
{
if (cfgRoot.length() == 0) // '/c [path]' was NOT specified
{
if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml file exists, copy vendor/conemu-maximus5/ConEmu.xml to config/ConEmu-%COMPUTERNAME%.xml.
{
@ -241,7 +245,27 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
}
}
}
else // '/c [path]' was specified, don't copy anything and use existing conemu-%COMPUTERNAME%.xml to start comemu.
{
if (use_user_cfg == false && PathFileExists(cfgPath) && !PathFileExists(cpuCfgPath)) // vendor/conemu-maximus5/ConEmu.xml file exists, copy vendor/conemu-maximus5/ConEmu.xml to config/ConEmu-%COMPUTERNAME%.xml.
{
if (!CopyFile(cfgPath, cpuCfgPath, FALSE))
{
MessageBox(NULL,
(GetLastError() == ERROR_ACCESS_DENIED)
? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml! Access Denied."
: L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/ConEmu-%COMPUTERNAME%.xml!", MB_TITLE, MB_ICONSTOP);
exit(1);
}
}
PathCombine(userConEmuCfgPath, userConfigDirPath, L"ConEmu-%COMPUTERNAME%.xml");
ExpandEnvironmentStrings(userConEmuCfgPath, userConEmuCfgPath, sizeof(userConEmuCfgPath) / sizeof(userConEmuCfgPath[0]));
}
}
else if (PathFileExists(userCfgPath)) // config/user_conemu.xml exists, use it.
{
if (cfgRoot.length() == 0) // '/c [path]' was NOT specified
{
if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml exists, copy vendor/conemu-maximus5/ConEmu.xml to config/user_conemu.xml.
{
@ -266,6 +290,36 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
}
}
}
else // '/c [path]' was specified, don't copy anything and use existing user_conemu.xml to start comemu.
{
PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml");
}
}
else if (cfgRoot.length() == 0) // '/c [path]' was NOT specified
{
if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml exists, copy vendor/conemu-maximus5/ConEmu.xml to config/user_conemu.xml
{
if (!CopyFile(cfgPath, userCfgPath, FALSE))
{
MessageBox(NULL,
(GetLastError() == ERROR_ACCESS_DENIED)
? L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml! Access Denied."
: L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml!", MB_TITLE, MB_ICONSTOP);
exit(1);
}
else // vendor/ConEmu.xml.default config exists, copy Cmder vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml.
{
if (!CopyFile(defaultCfgPath, cfgPath, FALSE))
{
MessageBox(NULL,
(GetLastError() == ERROR_ACCESS_DENIED)
? L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml! Access Denied."
: L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP);
exit(1);
}
}
}
}
else if (PathFileExists(cfgPath)) // vendor/conemu-maximus5/ConEmu.xml exists, copy vendor/conemu-maximus5/ConEmu.xml to config/user_conemu.xml
{
if (!CopyFile(cfgPath, userCfgPath, FALSE))
@ -276,18 +330,20 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
: L"Failed to copy vendor/conemu-maximus5/ConEmu.xml file to config/user-conemu.xml!", MB_TITLE, MB_ICONSTOP);
exit(1);
}
PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml");
}
else // vendor/ConEmu.xml config exists, copy Cmder vendor/ConEmu.xml file to vendor/conemu-maximus5/ConEmu.xml.
else // '/c [path]' was specified and 'vendor/ConEmu.xml.default' config exists, copy Cmder 'vendor/ConEmu.xml.default' file to '[user specified path]/config/user_ConEmu.xml'.
{
if ( ! CopyFile(defaultCfgPath, cfgPath, FALSE))
if ( ! CopyFile(defaultCfgPath, userCfgPath, FALSE))
{
ShowErrorAndExit(GetLastError(), __WFUNCTION__, __LINE__);
MessageBox(NULL,
(GetLastError() == ERROR_ACCESS_DENIED)
? L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml! Access Denied."
: L"Failed to copy vendor/ConEmu.xml.default file to vendor/conemu-maximus5/ConEmu.xml!", MB_TITLE, MB_ICONSTOP);
? L"Failed to copy vendor/ConEmu.xml.default file to [user specified path]/config/user_ConEmu.xml! Access Denied."
: L"Failed to copy vendor/ConEmu.xml.default file to [user specified path]/config/user_ConEmu.xml!", MB_TITLE, MB_ICONSTOP);
exit(1);
}
PathCombine(userConEmuCfgPath, userConfigDirPath, L"user-ConEmu.xml");
}
SYSTEM_INFO sysInfo;
@ -301,27 +357,26 @@ void StartCmder(std::wstring path = L"", bool is_single_mode = false, std::wstr
PathCombine(conEmuPath, exeDir, L"vendor\\conemu-maximus5\\ConEmu.exe");
}
swprintf_s(args, L"%s /Icon \"%s\" /Title Cmder", args, icoPath);
if (!streqi(cmderStart.c_str(), L""))
{
swprintf_s(args, L"%s /dir \"%s\"", args, cmderStart.c_str());
}
if (is_single_mode)
{
swprintf_s(args, L"%s /single", args);
}
if (!streqi(cmderTask.c_str(), L""))
{
swprintf_s(args, L"%s /single /Icon \"%s\" /Title Cmder /dir \"%s\" /run {%s}", args, icoPath, cmderStart.c_str(), cmderTask.c_str());
swprintf_s(args, L"%s /run {%s}", args, cmderTask.c_str());
}
else
if (cfgRoot.length() != 0)
{
swprintf_s(args, L"%s /single /Icon \"%s\" /Title Cmder /dir \"%s\"", args, icoPath, cmderStart.c_str());
}
}
else
{
if (!streqi(cmderTask.c_str(), L""))
{
swprintf_s(args, L"/Icon \"%s\" /Title Cmder /dir \"%s\" /run {%s}", icoPath, cmderStart.c_str(), cmderTask.c_str());
}
else
{
swprintf_s(args, L"%s /Icon \"%s\" /Title Cmder /dir \"%s\"", args, icoPath, cmderStart.c_str());
}
swprintf_s(args, L"%s -loadcfgfile \"%s\"", args, userConEmuCfgPath);
}
SetEnvironmentVariable(L"CMDER_ROOT", exeDir);
@ -387,8 +442,10 @@ HKEY GetRootKey(std::wstring opt)
return root;
}
void RegisterShellMenu(std::wstring opt, wchar_t* keyBaseName)
void RegisterShellMenu(std::wstring opt, wchar_t* keyBaseName, std::wstring cfgRoot = L"")
{
wchar_t userConfigDirPath[MAX_PATH] = { 0 };
// First, get the paths we will use
wchar_t exePath[MAX_PATH] = { 0 };
@ -397,7 +454,16 @@ void RegisterShellMenu(std::wstring opt, wchar_t* keyBaseName)
GetModuleFileName(NULL, exePath, sizeof(exePath));
wchar_t commandStr[MAX_PATH + 20] = { 0 };
if (cfgRoot.length() == 0) // '/c [path]' was NOT specified
{
swprintf_s(commandStr, L"\"%s\" \"%%V\"", exePath);
}
else {
std::copy(cfgRoot.begin(), cfgRoot.end(), userConfigDirPath);
userConfigDirPath[cfgRoot.length()] = 0;
swprintf_s(commandStr, L"\"%s\" /c \"%s\" \"%%V\"", exePath, userConfigDirPath);
}
// Now that we have `commandStr`, it's OK to change `exePath`...
PathRemoveFileSpec(exePath);
@ -443,6 +509,7 @@ struct cmderOptions
std::wstring cmderTask = L"";
std::wstring cmderRegScope = L"USER";
bool cmderSingle = false;
bool cmderUserCfg = true;
bool registerApp = false;
bool unRegisterApp = false;
bool error = false;
@ -460,6 +527,7 @@ cmderOptions GetOption()
{
// MessageBox(NULL, szArgList[i], L"Arglist contents", MB_OK);
if (cmderOptions.error == false) {
if (_wcsicmp(L"/c", szArgList[i]) == 0)
{
TCHAR userProfile[MAX_PATH];
@ -503,6 +571,10 @@ cmderOptions GetOption()
{
cmderOptions.cmderSingle = true;
}
else if (_wcsicmp(L"/m", szArgList[i]) == 0)
{
cmderOptions.cmderUserCfg = false;
}
else if (_wcsicmp(L"/register", szArgList[i]) == 0)
{
cmderOptions.registerApp = true;
@ -544,15 +616,17 @@ cmderOptions GetOption()
}
else
{
MessageBox(NULL, szArgList[i], L"Folder does not exist!", MB_OK);
MessageBox(NULL, L"Unrecognized parameter.\n\nValid options:\n\n /c [CMDER User Root Path]\n\n /task [ConEmu Task Name]\n\n [/start [Start in Path] | [Start in Path]]\n\n /single\n\n /m\n\nor\n\n /register [USER | ALL]\n\nor\n\n /unregister [USER | ALL]\n", MB_TITLE, MB_OK);
cmderOptions.error = true;
}
}
else
{
MessageBox(NULL, L"Unrecognized parameter.\n\nValid options:\n\n /c [CMDER User Root Path]\n\n /task [ConEmu Task Name]\n\n [/start [Start in Path] | [Start in Path]]\n\n /single\n\nor\n\n /register [USER | ALL]\n\nor\n\n /unregister [USER | ALL]\n", MB_TITLE, MB_OK);
MessageBox(NULL, L"Unrecognized parameter.\n\nValid options:\n\n /c [CMDER User Root Path]\n\n /task [ConEmu Task Name]\n\n [/start [Start in Path] | [Start in Path]]\n\n /single\n\n /m\n\nor\n\n /register [USER | ALL]\n\nor\n\n /unregister [USER | ALL]\n", MB_TITLE, MB_OK);
cmderOptions.error = true;
}
}
}
LocalFree(szArgList);
@ -572,8 +646,8 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
if (cmderOptions.registerApp == true)
{
RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_BACKGROUND);
RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_LISTITEM);
RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_BACKGROUND, cmderOptions.cmderCfgRoot);
RegisterShellMenu(cmderOptions.cmderRegScope, SHELL_MENU_REGISTRY_PATH_LISTITEM, cmderOptions.cmderCfgRoot);
}
else if (cmderOptions.unRegisterApp == true)
{
@ -586,7 +660,7 @@ int APIENTRY _tWinMain(_In_ HINSTANCE hInstance,
}
else
{
StartCmder(cmderOptions.cmderStart, cmderOptions.cmderSingle, cmderOptions.cmderTask, cmderOptions.cmderCfgRoot);
StartCmder(cmderOptions.cmderStart, cmderOptions.cmderSingle, cmderOptions.cmderTask, cmderOptions.cmderCfgRoot, cmderOptions.cmderUserCfg);
}
return 0;

8
vendor/init.bat vendored
View File

@ -1,6 +1,6 @@
@echo off
set cmder_init_start=%time%
set CMDER_INIT_START=%time%
:: Init Script for cmd.exe
:: Created as part of cmder project
@ -346,6 +346,7 @@ if not defined HOME set "HOME=%USERPROFILE%"
set "initialConfig=%CMDER_ROOT%\config\user_profile.cmd"
if exist "%CMDER_ROOT%\config\user_profile.cmd" (
REM Create this file and place your own command in there
%lib_console% debug_output init.bat "Calling - %CMDER_ROOT%\config\user_profile.cmd"
call "%CMDER_ROOT%\config\user_profile.cmd"
)
@ -353,6 +354,7 @@ if defined CMDER_USER_CONFIG (
set "initialConfig=%CMDER_USER_CONFIG%\user_profile.cmd"
if exist "%CMDER_USER_CONFIG%\user_profile.cmd" (
REM Create this file and place your own command in there
%lib_console% debug_output init.bat "Calling - %CMDER_USER_CONFIG%\user_profile.cmd
call "%CMDER_USER_CONFIG%\user_profile.cmd"
)
)
@ -398,9 +400,9 @@ if "%CMDER_ALIASES%" == "1" if exist "%CMDER_ROOT%\bin\alias.bat" if exist "%CMD
set initialConfig=
set CMDER_CONFIGURED=1
set cmder_init_end=%time%
set CMDER_INIT_END=%time%
if %time_init% gtr 0 (
"%cmder_root%\vendor\bin\timer.cmd" %cmder_init_start% %cmder_init_end%
"%cmder_root%\vendor\bin\timer.cmd" %CMDER_INIT_START% %CMDER_INIT_END%
)
exit /b

18
vendor/profile.ps1 vendored
View File

@ -128,20 +128,30 @@ if (-not (test-path "$ENV:CMDER_ROOT\config\profile.d")) {
}
pushd $ENV:CMDER_ROOT\config\profile.d
foreach ($x in Get-ChildItem *.ps1) {
foreach ($x in Get-ChildItem *.psm1) {
# write-host write-host Sourcing $x
Import-Module $x
}
foreach ($x in Get-ChildItem *.ps1) {
# write-host write-host Sourcing $x
. $x
}
popd
# Drop *.ps1 files into "$ENV:CMDER_USER_CONFIG\config\profile.d"
# to source them at startup. Requires using cmder.exe /C [cmder_user_root_path] argument
if ($ENV:CMDER_USER_CONFIG -ne "" -and (test-path "$ENV:CMDER_USER_CONFIG\profile.d")) {
pushd $ENV:CMDER_USER_CONFIG\profile.d
foreach ($x in Get-ChildItem *.ps1) {
foreach ($x in Get-ChildItem *.psm1) {
# write-host write-host Sourcing $x
Import-Module $x
}
foreach ($x in Get-ChildItem *.ps1) {
# write-host write-host Sourcing $x
. $x
}
popd
}
@ -153,7 +163,7 @@ if (test-path "$env:CMDER_ROOT\config\user-profile.ps1") {
$CmderUserProfilePath = Join-Path $env:CMDER_ROOT "config\user_profile.ps1"
if (Test-Path $CmderUserProfilePath) {
# Create this file and place your own command in there.
Import-Module "$CmderUserProfilePath"
. "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module
}
if ($ENV:CMDER_USER_CONFIG) {
@ -166,7 +176,7 @@ if ($ENV:CMDER_USER_CONFIG) {
$CmderUserProfilePath = Join-Path $ENV:CMDER_USER_CONFIG "user_profile.ps1"
if (Test-Path $CmderUserProfilePath) {
Import-Module "$CmderUserProfilePath"
. "$CmderUserProfilePath" # user_profile.ps1 is not a module DO NOT USE import-module
}
}