Added launching of Visual Studio by double clicking on a script file

This commit is contained in:
Kah Wei 2022-12-31 00:21:00 +08:00
parent 8db5b35f25
commit dcf7a65cac
6 changed files with 108 additions and 23 deletions

View File

@ -14,6 +14,8 @@
#include "Editor/DragDrop/SHDragDrop.hpp" #include "Editor/DragDrop/SHDragDrop.hpp"
#include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h" #include "Editor/EditorWindow/MaterialInspector/SHMaterialInspector.h"
#include "Editor/EditorWindow/SHEditorWindowManager.h" #include "Editor/EditorWindow/SHEditorWindowManager.h"
#include "Scripting/SHVSUtilities.h"
#include "Scripting/SHScriptEngine.h"
namespace SHADE namespace SHADE
{ {
@ -249,6 +251,12 @@ namespace SHADE
matInspector->OpenMaterial(asset->id); matInspector->OpenMaterial(asset->id);
} }
break; break;
case AssetType::SCRIPT:
if(auto scriptEngine = SHSystemManager::GetSystem<SHScriptEngine>())
{
scriptEngine->OpenFile(asset->path);
}
break;
case AssetType::MAX_COUNT: break; case AssetType::MAX_COUNT: break;
default:; default:;
} }

View File

@ -306,22 +306,12 @@ namespace SHADE
void SHScriptEngine::OpenSolution() void SHScriptEngine::OpenSolution()
{ {
// Generate csproj file if it doesn't exist SHVSUtilties::OpenProject(CSPROJ_PATH);
if (!std::filesystem::exists(CSPROJ_PATH)) }
{
GenerateScriptsCsProjFile(CSPROJ_PATH);
}
// Open it void SHScriptEngine::OpenFile(const std::filesystem::path& path)
try {
{ SHVSUtilties::OpenFile(CSPROJ_PATH, path);
SHVSUtilties::OpenFile(CSPROJ_PATH);
}
catch (std::exception& e)
{
SHLOG_ERROR("{}", e.what());
SHLOG_ERROR("[SHScriptEngine] Failed to open project csproj file.");
}
} }
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/

View File

@ -218,9 +218,14 @@ namespace SHADE
/// <param name="path">File path to the generated file.</param> /// <param name="path">File path to the generated file.</param>
void GenerateScriptsCsProjFile(const std::filesystem::path& path = CSPROJ_PATH) const; void GenerateScriptsCsProjFile(const std::filesystem::path& path = CSPROJ_PATH) const;
/// <summary> /// <summary>
/// Opens the script solution in Visual Studio 2019. /// Opens the script solution in Visual Studio.
/// </summary> /// </summary>
void OpenSolution(); void OpenSolution();
/// <summary>
/// Opens the file in Visual Studio.
/// </summary>
/// <param name="path"></param>
void OpenFile(const std::filesystem::path& path);
private: private:
/*-----------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------*/

View File

@ -22,18 +22,82 @@ namespace SHADE
/* Static Data Members */ /* Static Data Members */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
std::filesystem::path SHVSUtilties::devEnvPath; std::filesystem::path SHVSUtilties::devEnvPath;
HANDLE SHVSUtilties::devEnvInst = nullptr;
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
/* Usage Functions */ /* Usage Functions */
/*-----------------------------------------------------------------------------------*/ /*-----------------------------------------------------------------------------------*/
void SHVSUtilties::OpenFile(const std::filesystem::path& path) void SHVSUtilties::OpenProject(const std::filesystem::path& projPath)
try try
{ {
if (devEnvPath.empty()) // Check if there is an instance
bool devEnvActive = false;
if (devEnvInst)
{ {
devEnvPath = SHVSUtilties::getDevEnvPath();
DWORD status;
const auto GET_CODE_STATUS = GetExitCodeProcess(devEnvInst, &status);
devEnvActive = GET_CODE_STATUS && status == STILL_ACTIVE;
}
// Reuse the existing instance if there is one
if (devEnvActive)
{
// No need to reopen one
return;
}
else
{
if (devEnvPath.empty())
{
devEnvPath = SHVSUtilties::getDevEnvPath();
}
auto absProjPath = std::filesystem::canonical(projPath);
auto pi = SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L" " + absProjPath.generic_wstring());
// Cache the process handle
devEnvInst = pi.hProcess;
}
}
catch (std::exception& e)
{
SHLOG_ERROR("{}", e.what());
SHLOG_ERROR("[SHVSUtilities] Failed to launch Visual Studio.");
}
void SHVSUtilties::OpenFile(const std::filesystem::path& projPath, const std::filesystem::path& path)
try
{
// Check if there is an instance
bool devEnvActive = false;
if (devEnvInst)
{
DWORD status;
const auto GET_CODE_STATUS = GetExitCodeProcess(devEnvInst, &status);
devEnvActive = GET_CODE_STATUS && status == STILL_ACTIVE;
}
auto absPath = std::filesystem::canonical(path);
// Reuse the existing instance if there is one
if (devEnvActive)
{
// Edit the file only
SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L" /Edit " + absPath.generic_wstring());
}
else
{
if (devEnvPath.empty())
{
devEnvPath = SHVSUtilties::getDevEnvPath();
}
auto absProjPath = std::filesystem::canonical(projPath);
auto pi = SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), absProjPath.generic_wstring() + L" " + absPath.generic_wstring());
// Cache the process handle
devEnvInst = pi.hProcess;
} }
SHExecUtilties::ExecProcess(devEnvPath.generic_wstring(), L"/Edit " + path.generic_wstring());
} }
catch (std::exception& e) catch (std::exception& e)
{ {
@ -51,7 +115,7 @@ namespace SHADE
#else #else
static constexpr int EXCESS_CHARS_COUNT = 2; static constexpr int EXCESS_CHARS_COUNT = 2;
const auto RESULT = SHExecUtilties::ExecBlockingPowerShellCommand(L"./vswhere -version \"[15.0,19.0]\" -requires Microsoft.NetCore.Component.DevelopmentTools -find Common7\\\\IDE\\\\devenv.exe | Select-Object -last 1", true, true); const auto RESULT = SHExecUtilties::ExecBlockingPowerShellCommand(L"./vswhere -version \"[15.0,19.0]\" -requires Microsoft.NetCore.Component.DevelopmentTools -find Common7\\\\IDE\\\\devenv.exe | Select-Object -first 1", true, true);
if (RESULT.StdOutput.size() < EXCESS_CHARS_COUNT) if (RESULT.StdOutput.size() < EXCESS_CHARS_COUNT)
{ {
SHLOG_ERROR("[SHVSUtilities] Unable to get path to Visual Studio installation. SHVSUtilities will not work."); SHLOG_ERROR("[SHVSUtilities] Unable to get path to Visual Studio installation. SHVSUtilities will not work.");

View File

@ -28,10 +28,18 @@ namespace SHADE
/* Usage Functions */ /* Usage Functions */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/// <summary> /// <summary>
/// Opens the file at the specified path with a new instance of Visual Studio. /// Opens the project at the specified path with a new or existing instance of Visual
/// Studio if it exists.
/// </summary> /// </summary>
/// <param name="projPath">Path to the project file to open.</param>
static void OpenProject(const std::filesystem::path& projPath);
/// <summary>
/// Opens the file at the specified path with a new or existing instance of Visual
/// Studio if it exists.
/// </summary>
/// <param name="projPath">Path to the project file to open.</param>
/// <param name="path">Path to the file to open.</param> /// <param name="path">Path to the file to open.</param>
static void OpenFile(const std::filesystem::path& path); static void OpenFile(const std::filesystem::path& projPath, const std::filesystem::path& path);
private: private:
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
@ -43,6 +51,7 @@ namespace SHADE
/* Static Data Members */ /* Static Data Members */
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
static std::filesystem::path devEnvPath; static std::filesystem::path devEnvPath;
static HANDLE devEnvInst;
/*---------------------------------------------------------------------------------*/ /*---------------------------------------------------------------------------------*/
/* Helper Functions */ /* Helper Functions */

View File

@ -22,8 +22,17 @@ namespace SHADE
/// </summary> /// </summary>
struct SH_API ExecResult final struct SH_API ExecResult final
{ {
/// <summary>
/// Exit code of the process.
/// </summary>
DWORD Code; DWORD Code;
/// <summary>
/// Stored text output from the process.
/// </summary>
std::wstring StdOutput; std::wstring StdOutput;
/// <summary>
/// Stored error text output from the process.
/// </summary>
std::wstring StdErrOutput; std::wstring StdErrOutput;
}; };