Skip to content

Commit

Permalink
Try Workaround for launching VS and add open with VS (5)
Browse files Browse the repository at this point in the history
  • Loading branch information
arBmind committed Mar 9, 2024
1 parent a4ba7b3 commit a6e4b65
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 34 deletions.
10 changes: 10 additions & 0 deletions src/plugins/coreplugin/editormanager/editormanager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -375,6 +375,7 @@ EditorManagerPrivate::EditorManagerPrivate(QObject *parent) :
m_openGraphicalShellContextAction(new QAction(FileUtils::msgGraphicalShellAction(), this)),
m_showInFileSystemViewContextAction(new QAction(FileUtils::msgFileSystemAction(), this)),
m_openTerminalAction(new QAction(FileUtils::msgTerminalHereAction(), this)),
m_openVisualStudioAction(new QAction(::Core::Tr::tr("Open With Visual Studio"), this)),
m_findInDirectoryAction(new QAction(FileUtils::msgFindInDirectory(), this)),
m_filePropertiesAction(new QAction(::Core::Tr::tr("Properties..."), this)),
m_pinAction(new QAction(::Core::Tr::tr("Pin"), this))
Expand Down Expand Up @@ -549,6 +550,11 @@ void EditorManagerPrivate::init()
FileUtils::showInFileSystemView(m_contextMenuEntry->filePath());
});
connect(m_openTerminalAction, &QAction::triggered, this, &EditorManagerPrivate::openTerminal);
connect(m_openVisualStudioAction, &QAction::triggered, this, [this]() {
if (!d->m_contextMenuEntry || d->m_contextMenuEntry->filePath().isEmpty())
return;
EditorManager::instance()->openWithVisualStudio(d->m_contextMenuEntry->filePath());
});
connect(m_findInDirectoryAction, &QAction::triggered,
this, &EditorManagerPrivate::findInDirectory);
connect(m_filePropertiesAction, &QAction::triggered, this, [this] {
Expand Down Expand Up @@ -2803,11 +2809,15 @@ void EditorManager::addNativeDirAndOpenWithActions(QMenu *contextMenu, DocumentM
d->m_openGraphicalShellContextAction->setEnabled(enabled);
d->m_showInFileSystemViewContextAction->setEnabled(enabled);
d->m_openTerminalAction->setEnabled(enabled);
d->m_openVisualStudioAction->setEnabled(enabled);
d->m_findInDirectoryAction->setEnabled(enabled);
d->m_filePropertiesAction->setEnabled(enabled);
contextMenu->addAction(d->m_openGraphicalShellContextAction);
contextMenu->addAction(d->m_showInFileSystemViewContextAction);
contextMenu->addAction(d->m_openTerminalAction);
if (HostOsInfo::isWindowsHost()) {
contextMenu->addAction(d->m_openVisualStudioAction);
}
contextMenu->addAction(d->m_findInDirectoryAction);
contextMenu->addAction(d->m_filePropertiesAction);
QMenu *openWith = contextMenu->addMenu(::Core::Tr::tr("Open With"));
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/coreplugin/editormanager/editormanager.h
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,8 @@ class CORE_EXPORT EditorManager : public QObject
void autoSaved();
void currentEditorAboutToChange(Core::IEditor *editor);

void openWithVisualStudio(const Utils::FilePath &path);

#ifdef WITH_TESTS
void linkOpened();
#endif
Expand Down
1 change: 1 addition & 0 deletions src/plugins/coreplugin/editormanager/editormanager_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ public slots:
QAction *m_showInFileSystemViewAction = nullptr;
QAction *m_showInFileSystemViewContextAction = nullptr;
QAction *m_openTerminalAction = nullptr;
QAction *m_openVisualStudioAction = nullptr;
QAction *m_findInDirectoryAction = nullptr;
QAction *m_filePropertiesAction = nullptr;
QAction *m_pinAction = nullptr;
Expand Down
104 changes: 70 additions & 34 deletions src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@
#include <utils/utilsicons.h>

#include <QMenu>
#if defined(Q_OS_WIN)
#include <Windows.h>
#endif

using namespace ProjectExplorer;
using namespace Utils;
Expand All @@ -67,6 +70,33 @@ static QbsProject *currentEditorProject()
return doc ? qobject_cast<QbsProject *>(ProjectManager::projectForFile(doc->filePath())) : nullptr;
}

static void windowsStartProcessDetached(FilePath appPath, QStringList args) {
// note: QProcess cannot launch devenv.exe correctly. Default escape codes don't work here
#if defined(Q_OS_WIN)
auto startupInfo = STARTUPINFOW{.cb = sizeof(STARTUPINFOW)};
auto processInfo = PROCESS_INFORMATION{};

auto cmdLine = QString{appPath.fileName() + ' ' + args.join(" ")};

CreateProcessW(reinterpret_cast<const wchar_t *>(appPath.nativePath().utf16()),
reinterpret_cast<wchar_t *>(const_cast<ushort *>(cmdLine.utf16())),
nullptr, // process attributes
nullptr, // thread attributes
false, // inherit handles
DETACHED_PROCESS,
nullptr, // environment
nullptr, // current directory
&startupInfo,
&processInfo);

CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
#else
(void)appPath;
(void)args;
#endif
}

class QbsProjectManagerPluginPrivate
{
public:
Expand Down Expand Up @@ -206,6 +236,19 @@ void QbsProjectManagerPlugin::initialize()
connect(m_reparseQbs, &QAction::triggered,
this, &QbsProjectManagerPlugin::reparseCurrentProject);

connect(Core::EditorManager::instance(), &Core::EditorManager::openWithVisualStudio, this, [this](const Utils::FilePath &path) {
RunConfiguration* rc = ProjectManager::startupRunConfiguration();
if (!rc)
return;

if (const auto envAspect = rc->aspect<EnvironmentAspect>()) {
const auto devEnv = envAspect->environment().searchInPath(QLatin1String("devenv.exe"));
if (devEnv.isEmpty())
return;
windowsStartProcessDetached(devEnv, QStringList{} << "/edit" << QStringLiteral("\"%1\"").arg(path.nativePath()));
}
});

m_reparseQbsCtx = new QAction(Tr::tr("Reparse Qbs"), this);
command = Core::ActionManager::registerAction(m_reparseQbsCtx, Constants::ACTION_REPARSE_QBS_CONTEXT, projectContext);
command->setAttribute(Core::Command::CA_Hide);
Expand Down Expand Up @@ -497,50 +540,43 @@ void QbsProjectManagerPlugin::generateVs2022Project()

void QbsProjectManagerPlugin::debugWithVs2022Project()
{
Project *project = ProjectManager::startupProject();
if (!project)
return;

Target *target = project->activeTarget();
if (!target)
return;

RunConfiguration* rc = target->activeRunConfiguration();
RunConfiguration* rc = ProjectManager::startupRunConfiguration();
if (!rc)
return;

auto commandLine = rc->commandLine();
auto solutionName = commandLine.executable().toString() + ".sln";
auto executable = commandLine.executable();
auto solution = executable.withSuffix(".sln");
{
auto file = QFile(solutionName);
file.open(QFile::WriteOnly);
auto textStream = QTextStream(&file);
textStream
<< "Microsoft Visual Studio Solution File, Format Version 12.00\n"
<< "# Visual Studio 17\n"
<< "Project(\""<< QUuid::createUuid().toString() << "\") = \""
<< rc->buildTargetInfo().displayName << "\", \""
<< commandLine.executable().fileName() <<"\", \""
<< QUuid::createUuid().toString() << "\"\n"
<< "\tProjectSection(DebuggerProjectSystem) = preProject\n"
<< "\t\tExecutable = " << QDir::toNativeSeparators(commandLine.executable().toString()) << "\n"
<< "\t\tArguments = " << commandLine.arguments() << "\n";
if (const auto wdAspect = rc->aspect<WorkingDirectoryAspect>()) {
textStream << "\t\tStartingDirectory = " << QDir::toNativeSeparators(wdAspect->workingDirectory().toString()) << "\n";
}
if (const auto envAspect = rc->aspect<EnvironmentAspect>()) {
textStream << "\t\tEnvironment = " << envAspect->environment().toStringList().join('\t') << "\t\n";
auto buffer = QByteArray{};
{
auto textStream = QTextStream{&buffer, QIODevice::WriteOnly};
textStream
<< "Microsoft Visual Studio Solution File, Format Version 12.00\n"
<< "# Visual Studio 17\n"
<< "Project(\""<< QUuid::createUuid().toString() << "\") = \""
<< rc->buildTargetInfo().displayName << "\", \""
<< executable.fileName() <<"\", \""
<< QUuid::createUuid().toString() << "\"\n"
<< "\tProjectSection(DebuggerProjectSystem) = preProject\n"
<< "\t\tExecutable = " << executable.nativePath() << "\n"
<< "\t\tArguments = " << commandLine.arguments() << "\n";
if (const auto wdAspect = rc->aspect<WorkingDirectoryAspect>()) {
textStream << "\t\tStartingDirectory = " << wdAspect->workingDirectory().nativePath() << "\n";
}
if (const auto envAspect = rc->aspect<EnvironmentAspect>()) {
textStream << "\t\tEnvironment = " << envAspect->environment().toStringList().join('\t') << "\t\n";
}
textStream
<< "\tEndProjectSection\n"
<< "EndProject\n";
}
textStream
<< "\tEndProjectSection\n"
<< "EndProject\n";
solution.writeFileContents(buffer);
}
if (const auto envAspect = rc->aspect<EnvironmentAspect>()) {
const auto devEnv = envAspect->environment().searchInPath(QLatin1String("devenv.exe"));
if (!devEnv.isEmpty()) {
QStringList params;
params << QDir::toNativeSeparators(solutionName);
QProcess::startDetached(devEnv.toString(), params);
windowsStartProcessDetached(devEnv, QStringList{} << QStringLiteral("\"%1\"").arg(solution.nativePath()));
}
}
}
Expand Down

0 comments on commit a6e4b65

Please sign in to comment.