From b8c3d570f0799ffb035051dddd3895ee2e193e64 Mon Sep 17 00:00:00 2001 From: Alex Alabuzhev Date: Sat, 11 Jun 2016 19:56:02 +0000 Subject: [PATCH] yet another executor fix --- far/changelog | 4 ++++ far/cmdline.cpp | 4 ++-- far/cmdline.hpp | 14 ++++++++------ far/execute.cpp | 49 +++++++++++++++++++++++++++++------------------- far/filelist.cpp | 10 +++------- far/filetype.cpp | 4 ++-- far/usermenu.cpp | 2 +- far/vbuild.m4 | 2 +- 8 files changed, 51 insertions(+), 38 deletions(-) diff --git a/far/changelog b/far/changelog index 8eb2595654..92fb78462d 100644 --- a/far/changelog +++ b/far/changelog @@ -1,3 +1,7 @@ +drkns 11.06.2016 22:55:07 +0200 - build 4702 + +1. Ещё одно уточнение работы запускателя. + drkns 11.06.2016 20:05:25 +0200 - build 4701 1. Рефакторинг. diff --git a/far/cmdline.cpp b/far/cmdline.cpp index 45f4a4f304..8c7dc17261 100644 --- a/far/cmdline.cpp +++ b/far/cmdline.cpp @@ -848,7 +848,7 @@ void CommandLine::ShowViewEditHistory() { execute_info Info; Info.Command = strStr; - Info.WaitMode = Type == HR_EXTERNAL_WAIT? Info.wait_finish : Info.no_wait; + Info.WaitMode = Type == HR_EXTERNAL_WAIT? execute_info::wait_mode::wait_finish : execute_info::wait_mode::no_wait; ExecString(Info); break; @@ -1057,7 +1057,7 @@ void CommandLine::ExecString(execute_info& Info) FarChDir(m_CurDir); - if (Info.ExecMode != Info.direct) + if (Info.ExecMode != execute_info::exec_mode::direct && Info.SourceMode != execute_info::source_mode::known) { if (!Info.Command.empty() && Info.Command[0] == L'@') { diff --git a/far/cmdline.hpp b/far/cmdline.hpp index 79873e1031..a43a91b64b 100644 --- a/far/cmdline.hpp +++ b/far/cmdline.hpp @@ -40,14 +40,16 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. struct execute_info { - enum wait_mode { no_wait, wait_idle, wait_finish }; - enum exec_mode { detect, direct, external }; + enum class wait_mode { no_wait, wait_idle, wait_finish }; + enum class exec_mode { detect, direct, external }; + enum class source_mode { unknown, known }; string Command; - wait_mode WaitMode = no_wait; - bool NewWindow = false; - exec_mode ExecMode = detect; - bool RunAs = false; + wait_mode WaitMode{ wait_mode::no_wait }; + bool NewWindow{}; + exec_mode ExecMode{ exec_mode::detect }; + source_mode SourceMode{ source_mode::unknown }; + bool RunAs{}; }; class execution_context; diff --git a/far/execute.cpp b/far/execute.cpp index bab986ee49..02a08551aa 100644 --- a/far/execute.cpp +++ b/far/execute.cpp @@ -194,7 +194,12 @@ static bool FindObject(const string& Module, string &strDest, bool &Internal) { auto strFullName = Module; const auto ModuleExt = wcsrchr(PointToName(Module), L'.'); - const auto strPathExt = os::env::get_pathext() + L";;"; // ";;" to also try no extension if nothing else matches + auto strPathExt = os::env::get_pathext(); + if (Global->Opt->UseRegisteredTypes) + { + // ";;" to also try no extension if nothing else matches + strPathExt += L";;"; + } const auto PathExtList = split>(strPathExt, STLF_UNIQUE | STLF_ALLOWEMPTY); for (const auto& i: PathExtList) // первый проход - в текущем каталоге @@ -600,7 +605,8 @@ void OpenFolderInShell(const string& Folder) execute_info Info; Info.Command = Folder; Info.NewWindow = true; - Info.ExecMode = Info.direct; + Info.ExecMode = execute_info::exec_mode::direct; + Info.SourceMode = execute_info::source_mode::known; Execute(Info, true, true); } @@ -611,11 +617,15 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio string strNewCmdStr; string strNewCmdPar; - if (!PartCmdLine(Info.Command, strNewCmdStr, strNewCmdPar)) + if (Info.SourceMode == execute_info::source_mode::known) + { + strNewCmdStr = Info.Command; + } + else if (!PartCmdLine(Info.Command, strNewCmdStr, strNewCmdPar)) { // Complex expression (pipe or redirection): fallback to comspec as is strNewCmdStr = Info.Command; - Info.ExecMode = Info.external; + Info.ExecMode = execute_info::exec_mode::external; } bool IsDirectory = false; @@ -642,18 +652,19 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio { strNewCmdStr = Unquoted; ConvertNameToFull(strNewCmdStr, strNewCmdStr); - Info.ExecMode = Info.direct; + Info.ExecMode = execute_info::exec_mode::direct; + Info.SourceMode = execute_info::source_mode::known; FolderRun=true; } } string Verb; - if (FolderRun && Info.ExecMode == Info.direct) + if (FolderRun && Info.ExecMode == execute_info::exec_mode::direct) { AddEndSlash(strNewCmdStr); // НАДА, иначе ShellExecuteEx "возьмет" BAT/CMD/пр.ересь, но не каталог } - else if (Info.ExecMode == Info.detect) + else if (Info.ExecMode == execute_info::exec_mode::detect) { auto GetAssociatedImageType = [&Verb](const string& Str, image_type& ImageType) { @@ -701,18 +712,18 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio auto ImageType = image_type::unknown; - if (FindObject(ModuleName, FoundModuleName, Internal)) + if (Info.SourceMode == execute_info::source_mode::known || FindObject(ModuleName, FoundModuleName, Internal)) { if (Internal) { // Internal comspec command (one of ExcludeCmds): fallback to comspec as is - Info.ExecMode = Info.external; + Info.ExecMode = execute_info::exec_mode::external; strNewCmdStr = Info.Command; } else if (GetImageType(FoundModuleName, ImageType) || GetAssociatedImageType(FoundModuleName, ImageType) || GetImageTypeFallback(ImageType)) { // We can run it directly - Info.ExecMode = Info.direct; + Info.ExecMode = execute_info::exec_mode::direct; strNewCmdStr = FoundModuleName; strNewCmdPar = os::env::expand_strings(strNewCmdPar); @@ -726,12 +737,12 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio else { // Found nothing: fallback to comspec as is - Info.ExecMode = Info.external; + Info.ExecMode = execute_info::exec_mode::external; strNewCmdStr = Info.Command; } } - if (Info.WaitMode == Info.wait_finish) + if (Info.WaitMode == execute_info::wait_mode::wait_finish) { // It's better to show console rather than non-responding panels Silent = false; @@ -775,18 +786,18 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio // ShellExecuteEx Win8.1+ wrongly opens symlinks in a separate console window // Workaround: execute through %comspec% - if (Info.ExecMode == Info.direct && !Info.NewWindow && IsWindows8Point1OrGreater()) + if (Info.ExecMode == execute_info::exec_mode::direct && !Info.NewWindow && IsWindows8Point1OrGreater()) { os::fs::file_status fstatus(strNewCmdStr); if (os::fs::is_file(fstatus) && fstatus.check(FILE_ATTRIBUTE_REPARSE_POINT)) { - Info.ExecMode = Info.external; + Info.ExecMode = execute_info::exec_mode::external; } } string strComspec, ComSpecParams; - if (Info.ExecMode == Info.direct) + if (Info.ExecMode == execute_info::exec_mode::direct) { seInfo.lpFile = strNewCmdStr.data(); if(!strNewCmdPar.empty()) @@ -867,7 +878,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio { if (Process) { - if (Info.WaitMode == Info.wait_finish || !Info.NewWindow) + if (Info.WaitMode == execute_info::wait_mode::wait_finish || !Info.NewWindow) { if (Global->Opt->ConsoleDetachKey.empty()) { @@ -955,7 +966,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio } } } - if(Info.WaitMode == Info.wait_idle) + if(Info.WaitMode == execute_info::wait_mode::wait_idle) { WaitForInputIdle(Process.native_handle(), INFINITE); } @@ -991,7 +1002,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio if (!Result) { std::vector Strings; - if (Info.ExecMode == Info.direct) + if (Info.ExecMode == execute_info::exec_mode::direct) Strings = { MSG(MCannotExecute), strNewCmdStr }; else Strings = { MSG(MCannotInvokeComspec), strComspec, MSG(MCheckComspecVar) }; @@ -1003,7 +1014,7 @@ bool Execute(execute_info& Info, bool FolderRun, bool Silent, const std::functio L"ErrCannotExecute", nullptr, nullptr, - { Info.ExecMode == Info.direct? strNewCmdStr : strComspec }); + { Info.ExecMode == execute_info::exec_mode::direct? strNewCmdStr : strComspec }); } return Result; diff --git a/far/filelist.cpp b/far/filelist.cpp index db84852ff3..3d9b37c69e 100644 --- a/far/filelist.cpp +++ b/far/filelist.cpp @@ -2681,15 +2681,11 @@ void FileList::ProcessEnter(bool EnableExec,bool SeparateWindow,bool EnableAssoc { execute_info Info; Info.Command = strFileName; - Info.WaitMode = PluginMode? Info.wait_finish : Info.no_wait; + Info.WaitMode = PluginMode? execute_info::wait_mode::wait_finish : execute_info::wait_mode::no_wait; Info.NewWindow = SeparateWindow; + Info.SourceMode = execute_info::source_mode::known; Info.RunAs = RunAs; - // Here we definitely know that we're about to launch an actual file, - // (as manually typed commands are processed elsewhere), so launcher shall NOT try to search for it. - // However, we can't simply set ExecMode to 'direct' as we need to know image type anyway - // to launch it silently or in console mode. - // So, to avoid introducing some new additional weird flags, we just use the full file name: ConvertNameToFull(Info.Command, Info.Command); QuoteSpace(Info.Command); @@ -4928,7 +4924,7 @@ bool FileList::ApplyCommand() execute_info Info; Info.Command = strConvertedCommand; - Info.WaitMode = ListFileUsed? Info.wait_idle : Info.no_wait; + Info.WaitMode = ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait; Parent()->GetCmdLine()->ExecString(Info); //if (!(Global->Opt->ExcludeCmdHistory&EXCLUDECMDHISTORY_NOTAPPLYCMD)) diff --git a/far/filetype.cpp b/far/filetype.cpp index 654a129015..0326388d24 100644 --- a/far/filetype.cpp +++ b/far/filetype.cpp @@ -185,7 +185,7 @@ bool ProcessLocalFileTypes(const string& Name, const string& ShortName, FILETYPE execute_info Info; Info.Command = strCommand; - Info.WaitMode = AlwaysWaitFinish? Info.wait_finish : ListFileUsed? Info.wait_idle : Info.no_wait; + Info.WaitMode = AlwaysWaitFinish? execute_info::wait_mode::wait_finish : ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait; Global->CtrlObject->CmdLine()->ExecString(Info); @@ -299,7 +299,7 @@ void ProcessExternal(const string& Command, const string& Name, const string& Sh execute_info Info; Info.Command = strExecStr; - Info.WaitMode = AlwaysWaitFinish? Info.wait_finish : ListFileUsed? Info.wait_idle : Info.no_wait; + Info.WaitMode = AlwaysWaitFinish? execute_info::wait_mode::wait_finish : ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait; Global->CtrlObject->CmdLine()->ExecString(Info); diff --git a/far/usermenu.cpp b/far/usermenu.cpp index a69e595392..12877333eb 100644 --- a/far/usermenu.cpp +++ b/far/usermenu.cpp @@ -801,7 +801,7 @@ int UserMenu::ProcessSingleMenu(std::list& Menu, int MenuPos, std: execute_info Info; Info.Command = strCommand; - Info.WaitMode = ListFileUsed? Info.wait_idle : Info.no_wait; + Info.WaitMode = ListFileUsed? execute_info::wait_mode::wait_idle : execute_info::wait_mode::no_wait; Global->CtrlObject->CmdLine()->ExecString(Info); } diff --git a/far/vbuild.m4 b/far/vbuild.m4 index 49d05c12b3..fb1e68caa4 100644 --- a/far/vbuild.m4 +++ b/far/vbuild.m4 @@ -1 +1 @@ -m4_define(BUILD,4701)m4_dnl +m4_define(BUILD,4702)m4_dnl