forked from qt-creator/qt-creator
WinRT: Enable debugging for local packages.
Change-Id: Ic04f1a471f951caf7a79c69cceecb0ebd5d09919 Reviewed-by: hjk <hjk121@nokiamail.com>
This commit is contained in:
@@ -2699,8 +2699,7 @@ void CdbEngine::parseOutputLine(QByteArray line)
|
||||
m_autoBreakPointCorrection = major > 6 || (major == 6 && minor >= 2 && minor < 10);
|
||||
showMessage(QString::fromLocal8Bit(line), LogMisc);
|
||||
showMessage(QString::fromLatin1("Using ")
|
||||
+ m_autoBreakPointCorrection ? QLatin1String("CDB ")
|
||||
: QLatin1String("codemodel ")
|
||||
+ QLatin1String(m_autoBreakPointCorrection ? "CDB " : "codemodel ")
|
||||
+ QString::fromLatin1("based breakpoint correction."), LogMisc);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -135,18 +135,6 @@ int breakPointIdToCdbId(const BreakpointModelId &id)
|
||||
return cdbBreakPointStartId + id.majorPart() * cdbBreakPointIdMinorPart + id.minorPart();
|
||||
}
|
||||
|
||||
template <class ModelId>
|
||||
inline ModelId cdbIdToBreakpointId(const GdbMi &data)
|
||||
{
|
||||
if (data.isValid()) { // Might not be valid if there is not id
|
||||
bool ok;
|
||||
const int id = data.data().toInt(&ok);
|
||||
if (ok)
|
||||
return cdbIdToBreakpointId<ModelId>(id);
|
||||
}
|
||||
return ModelId();
|
||||
}
|
||||
|
||||
template <class ModelId>
|
||||
inline ModelId cdbIdToBreakpointId(const int &id)
|
||||
{
|
||||
@@ -161,6 +149,18 @@ inline ModelId cdbIdToBreakpointId(const int &id)
|
||||
return ModelId();
|
||||
}
|
||||
|
||||
template <class ModelId>
|
||||
inline ModelId cdbIdToBreakpointId(const GdbMi &data)
|
||||
{
|
||||
if (data.isValid()) { // Might not be valid if there is not id
|
||||
bool ok;
|
||||
const int id = data.data().toInt(&ok);
|
||||
if (ok)
|
||||
return cdbIdToBreakpointId<ModelId>(id);
|
||||
}
|
||||
return ModelId();
|
||||
}
|
||||
|
||||
BreakpointModelId cdbIdToBreakpointModelId(const GdbMi &id)
|
||||
{
|
||||
return cdbIdToBreakpointId<BreakpointModelId>(id);
|
||||
|
||||
@@ -2,6 +2,7 @@ include(../../qtcreatorplugin.pri)
|
||||
|
||||
HEADERS += \
|
||||
winrtconstants.h \
|
||||
winrtdebugsupport.h \
|
||||
winrtdeployconfiguration.h \
|
||||
winrtdevice.h \
|
||||
winrtdevicefactory.h \
|
||||
@@ -14,9 +15,11 @@ HEADERS += \
|
||||
winrtrunconfiguration.h \
|
||||
winrtrunconfigurationwidget.h \
|
||||
winrtruncontrol.h \
|
||||
winrtrunfactories.h
|
||||
winrtrunfactories.h \
|
||||
winrtrunnerhelper.h
|
||||
|
||||
SOURCES += \
|
||||
winrtdebugsupport.cpp \
|
||||
winrtdeployconfiguration.cpp \
|
||||
winrtdevice.cpp \
|
||||
winrtdevicefactory.cpp \
|
||||
@@ -29,7 +32,8 @@ SOURCES += \
|
||||
winrtrunconfiguration.cpp \
|
||||
winrtrunconfigurationwidget.cpp \
|
||||
winrtruncontrol.cpp \
|
||||
winrtrunfactories.cpp
|
||||
winrtrunfactories.cpp \
|
||||
winrtrunnerhelper.cpp
|
||||
|
||||
DEFINES += WINRT_LIBRARY
|
||||
|
||||
|
||||
@@ -7,12 +7,15 @@ QtcPlugin {
|
||||
minimumQtVersion: "5.0"
|
||||
|
||||
Depends { name: "Core" }
|
||||
Depends { name: "Debugger" }
|
||||
Depends { name: "ProjectExplorer" }
|
||||
Depends { name: "QtSupport" }
|
||||
Depends { name: "Qt.gui" }
|
||||
|
||||
files: [
|
||||
"winrtconstants.h",
|
||||
"winrtdebugsupport.cpp",
|
||||
"winrtdebugsupport.h",
|
||||
"winrtdeployconfiguration.cpp",
|
||||
"winrtdeployconfiguration.h",
|
||||
"winrtdevice.cpp",
|
||||
@@ -40,6 +43,8 @@ QtcPlugin {
|
||||
"winrtruncontrol.cpp",
|
||||
"winrtruncontrol.h",
|
||||
"winrtrunfactories.cpp",
|
||||
"winrtrunfactories.h"
|
||||
"winrtrunfactories.h",
|
||||
"winrtrunnerhelper.cpp",
|
||||
"winrtrunnerhelper.h"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
QTC_PLUGIN_NAME = WinRt
|
||||
QTC_PLUGIN_DEPENDS += \
|
||||
coreplugin \
|
||||
debugger \
|
||||
projectexplorer \
|
||||
qtsupport
|
||||
|
||||
141
src/plugins/winrt/winrtdebugsupport.cpp
Normal file
141
src/plugins/winrt/winrtdebugsupport.cpp
Normal file
@@ -0,0 +1,141 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "winrtdebugsupport.h"
|
||||
#include "winrtrunconfiguration.h"
|
||||
#include "winrtrunnerhelper.h"
|
||||
|
||||
#include <debugger/debuggerengine.h>
|
||||
#include <debugger/debuggerkitinformation.h>
|
||||
#include <debugger/debuggerplugin.h>
|
||||
#include <debugger/debuggerrunner.h>
|
||||
#include <debugger/debuggerstartparameters.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
namespace WinRt {
|
||||
namespace Internal {
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
WinRtDebugSupport::WinRtDebugSupport(RunControl *runControl, WinRtRunnerHelper *runner)
|
||||
: QObject(runControl)
|
||||
, m_debugRunControl(runControl)
|
||||
, m_runner(runner)
|
||||
{
|
||||
connect(m_debugRunControl, SIGNAL(finished()), this, SLOT(finish()));
|
||||
}
|
||||
|
||||
void WinRtDebugSupport::finish()
|
||||
{
|
||||
m_runner->stop();
|
||||
}
|
||||
|
||||
RunControl *WinRtDebugSupport::createDebugRunControl(WinRtRunConfiguration *runConfig,
|
||||
RunMode mode,
|
||||
QString *errorMessage)
|
||||
{
|
||||
// FIXME: This is just working for local debugging;
|
||||
using namespace Debugger;
|
||||
DebuggerStartParameters params;
|
||||
params.startMode = AttachExternal;
|
||||
params.languages |= CppLanguage;
|
||||
params.breakOnMain = mode == DebugRunModeWithBreakOnMain;
|
||||
// The first Thread needs to be resumed manually.
|
||||
params.commandsAfterConnect = "~0 m";
|
||||
Kit *kit = runConfig->target()->kit();
|
||||
params.debuggerCommand = DebuggerKitInformation::debuggerCommand(kit).toString();
|
||||
if (ToolChain *tc = ToolChainKitInformation::toolChain(kit))
|
||||
params.toolChainAbi = tc->targetAbi();
|
||||
|
||||
QFileInfo debuggerHelper(QCoreApplication::applicationDirPath()
|
||||
+ QLatin1String("/winrtdebughelper.exe"));
|
||||
if (!debuggerHelper.isExecutable()) {
|
||||
*errorMessage = tr("The WinRT debugging helper is missing from your Qt Creator "
|
||||
"installation. It was assumed to be located at").arg(
|
||||
debuggerHelper.absoluteFilePath());
|
||||
return 0;
|
||||
}
|
||||
|
||||
WinRtRunnerHelper *runner = new WinRtRunnerHelper(runConfig, errorMessage);
|
||||
if (!errorMessage->isEmpty())
|
||||
return 0;
|
||||
|
||||
runner->debug(debuggerHelper.absoluteFilePath());
|
||||
if (!runner->waitForStarted()) {
|
||||
*errorMessage = tr("Cannot start the WinRT Runner Tool.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
QLocalServer server;
|
||||
server.listen(QLatin1String("QtCreatorWinRtDebugPIDPipe"));
|
||||
if (!server.waitForNewConnection(10000)) {
|
||||
*errorMessage = tr("Cannot establish connection to the WinRT debugging helper.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (server.hasPendingConnections()) {
|
||||
QLocalSocket *connection = server.nextPendingConnection();
|
||||
if (connection->waitForReadyRead(1000)) {
|
||||
const QByteArray &output = connection->readAll();
|
||||
QList<QByteArray> arg = output.split(':');
|
||||
if (arg.first() == "PID") {
|
||||
bool ok =false;
|
||||
params.attachPID = arg.last().toInt(&ok);
|
||||
if (!ok) {
|
||||
*errorMessage = tr("Cannot extract the PID from the WinRT debugging helper. "
|
||||
"(output: %1)").arg(QString::fromLocal8Bit(output));
|
||||
return 0;
|
||||
}
|
||||
server.close();
|
||||
Debugger::DebuggerRunControl *debugRunControl
|
||||
= DebuggerPlugin::createDebugger(params, runConfig, errorMessage);
|
||||
runner->setRunControl(debugRunControl);
|
||||
new WinRtDebugSupport(debugRunControl, runner);
|
||||
return debugRunControl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
server.close();
|
||||
|
||||
*errorMessage = tr("Cannot create an appropriate run control for "
|
||||
"the current run configuration.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace WinRt
|
||||
65
src/plugins/winrt/winrtdebugsupport.h
Normal file
65
src/plugins/winrt/winrtdebugsupport.h
Normal file
@@ -0,0 +1,65 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef WINRT_INTERNAL_WINRTDEBUGSUPPORT_H
|
||||
#define WINRT_INTERNAL_WINRTDEBUGSUPPORT_H
|
||||
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
namespace WinRt {
|
||||
namespace Internal {
|
||||
|
||||
class WinRtRunConfiguration;
|
||||
class WinRtRunnerHelper;
|
||||
|
||||
class WinRtDebugSupport : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static ProjectExplorer::RunControl *createDebugRunControl(WinRtRunConfiguration *runConfig,
|
||||
ProjectExplorer::RunMode mode,
|
||||
QString *errorMessage);
|
||||
|
||||
private:
|
||||
WinRtDebugSupport(ProjectExplorer::RunControl *runControl, WinRtRunnerHelper *runner);
|
||||
|
||||
ProjectExplorer::RunControl *m_debugRunControl;
|
||||
WinRtRunnerHelper *m_runner;
|
||||
|
||||
private slots:
|
||||
void finish();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace WinRt
|
||||
|
||||
#endif // WINRT_INTERNAL_WINRTDEBUGSUPPORT_H
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "winrtdevice.h"
|
||||
#include "winrtconstants.h"
|
||||
|
||||
#include <projectexplorer/devicesupport/desktopprocesssignaloperation.h>
|
||||
#include <projectexplorer/devicesupport/devicemanager.h>
|
||||
#include <projectexplorer/devicesupport/deviceprocesslist.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -84,9 +85,16 @@ void WinRtDevice::executeAction(Core::Id actionId, QWidget *parent)
|
||||
Q_UNUSED(parent);
|
||||
}
|
||||
|
||||
ProjectExplorer::DeviceProcessSignalOperation::Ptr WinRtDevice::signalOperation() const
|
||||
DeviceProcessSignalOperation::Ptr WinRtDevice::signalOperation() const
|
||||
{
|
||||
return DeviceProcessSignalOperation::Ptr();
|
||||
class WinRtDesktopSignalOperation : public ProjectExplorer::DesktopProcessSignalOperation
|
||||
{
|
||||
public:
|
||||
WinRtDesktopSignalOperation() {}
|
||||
~WinRtDesktopSignalOperation() {}
|
||||
};
|
||||
|
||||
return DeviceProcessSignalOperation::Ptr(new WinRtDesktopSignalOperation());
|
||||
}
|
||||
|
||||
void WinRtDevice::fromMap(const QVariantMap &map)
|
||||
|
||||
@@ -28,9 +28,10 @@
|
||||
****************************************************************************/
|
||||
|
||||
#include "winrtruncontrol.h"
|
||||
#include "winrtrunconfiguration.h"
|
||||
#include "winrtconstants.h"
|
||||
|
||||
#include "winrtdevice.h"
|
||||
#include "winrtrunconfiguration.h"
|
||||
#include "winrtrunnerhelper.h"
|
||||
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
@@ -41,7 +42,8 @@
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
|
||||
using ProjectExplorer::BuildConfiguration;
|
||||
#include <QTimer>
|
||||
|
||||
using ProjectExplorer::DeviceKitInformation;
|
||||
using ProjectExplorer::IDevice;
|
||||
using ProjectExplorer::RunControl;
|
||||
@@ -54,39 +56,10 @@ namespace Internal {
|
||||
|
||||
WinRtRunControl::WinRtRunControl(WinRtRunConfiguration *runConfiguration, RunMode mode)
|
||||
: RunControl(runConfiguration, mode)
|
||||
, m_runConfiguration(runConfiguration)
|
||||
, m_state(StoppedState)
|
||||
, m_process(0)
|
||||
, m_runner(0)
|
||||
{
|
||||
Target *target = runConfiguration->target();
|
||||
IDevice::ConstPtr device = DeviceKitInformation::device(target->kit());
|
||||
m_device = device.dynamicCast<const WinRtDevice>();
|
||||
|
||||
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target->kit());
|
||||
if (!qt) {
|
||||
appendMessage(tr("The current kit has no Qt version."),
|
||||
Utils::ErrorMessageFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
m_isWinPhone = (qt->type() == QLatin1String(Constants::WINRT_WINPHONEQT));
|
||||
m_runnerFilePath = qt->binPath().toString() + QStringLiteral("/winrtrunner.exe");
|
||||
if (!QFile::exists(m_runnerFilePath)) {
|
||||
appendMessage(tr("Cannot find winrtrunner.exe in \"%1\".").arg(
|
||||
QDir::toNativeSeparators(qt->binPath().toString())),
|
||||
Utils::ErrorMessageFormat);
|
||||
return;
|
||||
}
|
||||
|
||||
const Utils::FileName proFile = Utils::FileName::fromString(
|
||||
target->project()->document()->filePath());
|
||||
m_executableFilePath = target->applicationTargets().targetForProject(proFile).toString()
|
||||
+ QStringLiteral(".exe"); // ### we should not need to append ".exe" here.
|
||||
|
||||
m_arguments = runConfiguration->arguments();
|
||||
m_uninstallAfterStop = runConfiguration->uninstallAfterStop();
|
||||
|
||||
if (BuildConfiguration *bc = target->activeBuildConfiguration())
|
||||
m_environment = bc->environment();
|
||||
}
|
||||
|
||||
void WinRtRunControl::start()
|
||||
@@ -99,13 +72,10 @@ void WinRtRunControl::start()
|
||||
|
||||
RunControl::StopResult WinRtRunControl::stop()
|
||||
{
|
||||
if (m_state != StartedState) {
|
||||
m_state = StoppedState;
|
||||
if (m_state == StoppedState)
|
||||
return StoppedSynchronously;
|
||||
}
|
||||
|
||||
QTC_ASSERT(m_process, return StoppedSynchronously);
|
||||
m_process->interrupt();
|
||||
m_runner->stop();
|
||||
return AsynchronousStop;
|
||||
}
|
||||
|
||||
@@ -126,84 +96,31 @@ void WinRtRunControl::onProcessStarted()
|
||||
emit started();
|
||||
}
|
||||
|
||||
void WinRtRunControl::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
void WinRtRunControl::onProcessFinished()
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
QTC_CHECK(m_state == StartedState);
|
||||
|
||||
if (exitStatus == QProcess::CrashExit) {
|
||||
appendMessage(tr("winrtrunner crashed.") + QLatin1Char('\n'), Utils::ErrorMessageFormat);
|
||||
} else if (exitCode != 0) {
|
||||
appendMessage(tr("winrtrunner returned with exit code %1.").arg(exitCode)
|
||||
+ QLatin1Char('\n'), Utils::ErrorMessageFormat);
|
||||
} else {
|
||||
appendMessage(tr("winrtrunner finished successfully.")
|
||||
+ QLatin1Char('\n'), Utils::NormalMessageFormat);
|
||||
}
|
||||
|
||||
m_process->disconnect();
|
||||
m_process->deleteLater();
|
||||
m_process = 0;
|
||||
m_state = StoppedState;
|
||||
emit finished();
|
||||
onProcessError();
|
||||
}
|
||||
|
||||
void WinRtRunControl::onProcessError()
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
appendMessage(tr("Error while executing winrtrunner: %1\n").arg(m_process->errorString()),
|
||||
Utils::ErrorMessageFormat);
|
||||
m_process->disconnect();
|
||||
m_process->deleteLater();
|
||||
m_process = 0;
|
||||
QTC_ASSERT(m_runner, return);
|
||||
m_runner->disconnect();
|
||||
m_runner->deleteLater();
|
||||
m_runner = 0;
|
||||
m_state = StoppedState;
|
||||
emit finished();
|
||||
}
|
||||
|
||||
void WinRtRunControl::onProcessReadyReadStdOut()
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
appendMessage(QString::fromLocal8Bit(m_process->readAllStandardOutput()), Utils::StdOutFormat);
|
||||
}
|
||||
|
||||
void WinRtRunControl::onProcessReadyReadStdErr()
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
appendMessage(QString::fromLocal8Bit(m_process->readAllStandardError()), Utils::StdErrFormat);
|
||||
}
|
||||
|
||||
bool WinRtRunControl::startWinRtRunner()
|
||||
{
|
||||
QString runnerArgs;
|
||||
QtcProcess::addArg(&runnerArgs, QStringLiteral("--profile"));
|
||||
QtcProcess::addArg(&runnerArgs, m_isWinPhone ? QStringLiteral("xap") : QStringLiteral("appx"));
|
||||
if (m_device) {
|
||||
QtcProcess::addArg(&runnerArgs, QStringLiteral("--device"));
|
||||
QtcProcess::addArg(&runnerArgs, QString::number(m_device->deviceId()));
|
||||
}
|
||||
QtcProcess::addArgs(&runnerArgs, QStringLiteral("--install --start --stop --wait 0"));
|
||||
QtcProcess::addArg(&runnerArgs, m_executableFilePath);
|
||||
if (!m_arguments.isEmpty())
|
||||
QtcProcess::addArgs(&runnerArgs, m_arguments);
|
||||
|
||||
appendMessage(QStringLiteral("winrtrunner ") + runnerArgs + QLatin1Char('\n'),
|
||||
Utils::NormalMessageFormat);
|
||||
|
||||
QTC_ASSERT(!m_process, m_process->deleteLater());
|
||||
m_process = new QtcProcess(this);
|
||||
connect(m_process, SIGNAL(started()), SLOT(onProcessStarted()));
|
||||
connect(m_process, SIGNAL(finished(int,QProcess::ExitStatus)),
|
||||
SLOT(onProcessFinished(int,QProcess::ExitStatus)));
|
||||
connect(m_process, SIGNAL(error(QProcess::ProcessError)), SLOT(onProcessError()));
|
||||
connect(m_process, SIGNAL(readyReadStandardOutput()), SLOT(onProcessReadyReadStdOut()));
|
||||
connect(m_process, SIGNAL(readyReadStandardError()), SLOT(onProcessReadyReadStdErr()));
|
||||
|
||||
QTC_ASSERT(!m_runner, return false);
|
||||
m_runner = new WinRtRunnerHelper(this);
|
||||
connect(m_runner, SIGNAL(started()), SLOT(onProcessStarted()));
|
||||
connect(m_runner, SIGNAL(finished(int,QProcess::ExitStatus)), SLOT(onProcessFinished()));
|
||||
connect(m_runner, SIGNAL(error(QProcess::ProcessError)), SLOT(onProcessError()));
|
||||
m_state = StartingState;
|
||||
m_process->setUseCtrlCStub(true);
|
||||
m_process->setCommand(m_runnerFilePath, runnerArgs);
|
||||
m_process->setEnvironment(m_environment);
|
||||
m_process->setWorkingDirectory(QFileInfo(m_executableFilePath).absolutePath());
|
||||
m_process->start();
|
||||
m_runner->start();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ namespace WinRt {
|
||||
namespace Internal {
|
||||
|
||||
class WinRtRunConfiguration;
|
||||
class WinRtRunnerHelper;
|
||||
|
||||
class WinRtRunControl : public ProjectExplorer::RunControl
|
||||
{
|
||||
@@ -61,24 +62,17 @@ public:
|
||||
|
||||
private slots:
|
||||
void onProcessStarted();
|
||||
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void onProcessFinished();
|
||||
void onProcessError();
|
||||
void onProcessReadyReadStdOut();
|
||||
void onProcessReadyReadStdErr();
|
||||
|
||||
private:
|
||||
enum State { StartingState, StartedState, StoppedState };
|
||||
bool startWinRtRunner();
|
||||
|
||||
WinRtRunConfiguration *m_runConfiguration;
|
||||
State m_state;
|
||||
WinRtDevice::ConstPtr m_device;
|
||||
QString m_runnerFilePath;
|
||||
QString m_executableFilePath;
|
||||
QString m_arguments;
|
||||
bool m_uninstallAfterStop;
|
||||
bool m_isWinPhone;
|
||||
Utils::QtcProcess *m_process;
|
||||
Utils::Environment m_environment;
|
||||
WinRtRunnerHelper *m_runner;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -31,16 +31,24 @@
|
||||
#include "winrtrunconfiguration.h"
|
||||
#include "winrtruncontrol.h"
|
||||
#include "winrtconstants.h"
|
||||
#include "winrtdebugsupport.h"
|
||||
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <projectexplorer/toolchain.h>
|
||||
|
||||
#include <debugger/debuggerkitinformation.h>
|
||||
#include <debugger/debuggerplugin.h>
|
||||
#include <debugger/debuggerrunner.h>
|
||||
#include <debugger/debuggerstartparameters.h>
|
||||
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QLocalServer>
|
||||
#include <QLocalSocket>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
namespace WinRt {
|
||||
@@ -80,7 +88,6 @@ QString WinRtRunConfigurationFactory::displayNameForId(const Core::Id id) const
|
||||
|
||||
bool WinRtRunConfigurationFactory::canCreate(Target *parent, const Core::Id id) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return id == winrtConfigurationIdC && isKitCompatible(parent->kit());
|
||||
}
|
||||
|
||||
@@ -91,7 +98,6 @@ RunConfiguration *WinRtRunConfigurationFactory::doCreate(Target *parent, const C
|
||||
|
||||
bool WinRtRunConfigurationFactory::canRestore(Target *parent, const QVariantMap &map) const
|
||||
{
|
||||
Q_UNUSED(parent);
|
||||
return ProjectExplorer::idFromMap(map) == winrtConfigurationIdC && isKitCompatible(parent->kit());
|
||||
}
|
||||
|
||||
@@ -123,9 +129,23 @@ WinRtRunControlFactory::WinRtRunControlFactory()
|
||||
bool WinRtRunControlFactory::canRun(ProjectExplorer::RunConfiguration *runConfiguration,
|
||||
ProjectExplorer::RunMode mode) const
|
||||
{
|
||||
if (mode != NormalRunMode)
|
||||
if (!runConfiguration)
|
||||
return false;
|
||||
return qobject_cast<WinRtRunConfiguration *>(runConfiguration);
|
||||
IDevice::ConstPtr device = DeviceKitInformation::device(runConfiguration->target()->kit());
|
||||
if (!device)
|
||||
return false;
|
||||
|
||||
switch (mode) {
|
||||
case DebugRunMode:
|
||||
case DebugRunModeWithBreakOnMain:
|
||||
if (device->type() != Constants::WINRT_DEVICE_TYPE_LOCAL)
|
||||
return false;
|
||||
// fall through
|
||||
case NormalRunMode:
|
||||
return qobject_cast<WinRtRunConfiguration *>(runConfiguration);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
ProjectExplorer::RunControl *WinRtRunControlFactory::create(
|
||||
@@ -137,6 +157,9 @@ ProjectExplorer::RunControl *WinRtRunControlFactory::create(
|
||||
switch (mode) {
|
||||
case NormalRunMode:
|
||||
return new WinRtRunControl(rc, mode);
|
||||
case DebugRunMode:
|
||||
case DebugRunModeWithBreakOnMain:
|
||||
return WinRtDebugSupport::createDebugRunControl(rc, mode, errorMessage);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
240
src/plugins/winrt/winrtrunnerhelper.cpp
Normal file
240
src/plugins/winrt/winrtrunnerhelper.cpp
Normal file
@@ -0,0 +1,240 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#include "winrtrunnerhelper.h"
|
||||
|
||||
#include "winrtconstants.h"
|
||||
#include "winrtrunconfiguration.h"
|
||||
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <projectexplorer/buildtargetinfo.h>
|
||||
#include <projectexplorer/devicesupport/idevice.h>
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
#include <projectexplorer/kitinformation.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/runconfiguration.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
#include <qtsupport/qtkitinformation.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QDir>
|
||||
|
||||
using namespace WinRt;
|
||||
using namespace WinRt::Internal;
|
||||
|
||||
WinRtRunnerHelper::WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QString *errormessage)
|
||||
: QObject(runConfiguration)
|
||||
, m_messenger(0)
|
||||
, m_runConfiguration(runConfiguration)
|
||||
, m_process(0)
|
||||
{
|
||||
init(runConfiguration, errormessage);
|
||||
}
|
||||
|
||||
WinRtRunnerHelper::WinRtRunnerHelper(ProjectExplorer::RunControl *runControl)
|
||||
: QObject(runControl)
|
||||
, m_messenger(runControl)
|
||||
, m_runConfiguration(0)
|
||||
, m_process(0)
|
||||
{
|
||||
m_runConfiguration = qobject_cast<WinRtRunConfiguration *>(runControl->runConfiguration());
|
||||
QString errorMessage;
|
||||
if (!init(m_runConfiguration, &errorMessage))
|
||||
runControl->appendMessage(errorMessage, Utils::ErrorMessageFormat);
|
||||
}
|
||||
|
||||
bool WinRtRunnerHelper::init(WinRtRunConfiguration *runConfiguration, QString *errorMessage)
|
||||
{
|
||||
ProjectExplorer::Target *target = runConfiguration->target();
|
||||
m_device = ProjectExplorer::DeviceKitInformation::device(
|
||||
target->kit()).dynamicCast<const WinRtDevice>();
|
||||
|
||||
const QtSupport::BaseQtVersion *qt = QtSupport::QtKitInformation::qtVersion(target->kit());
|
||||
if (!qt) {
|
||||
*errorMessage = tr("The current kit has no Qt version.");
|
||||
return false;
|
||||
}
|
||||
|
||||
m_isWinPhone = (qt->type() == QLatin1String(Constants::WINRT_WINPHONEQT));
|
||||
m_runnerFilePath = qt->binPath().toString() + QStringLiteral("/winrtrunner.exe");
|
||||
if (!QFile::exists(m_runnerFilePath)) {
|
||||
*errorMessage = tr("Cannot find winrtrunner.exe in \"%1\".").arg(
|
||||
QDir::toNativeSeparators(qt->binPath().toString()));
|
||||
return false;
|
||||
}
|
||||
|
||||
const Utils::FileName proFile = Utils::FileName::fromString(
|
||||
target->project()->document()->filePath());
|
||||
m_executableFilePath = target->applicationTargets().targetForProject(proFile).toString()
|
||||
+ QStringLiteral(".exe"); // ### we should not need to append ".exe" here.
|
||||
|
||||
m_arguments = runConfiguration->arguments();
|
||||
m_uninstallAfterStop = runConfiguration->uninstallAfterStop();
|
||||
|
||||
if (ProjectExplorer::BuildConfiguration *bc = target->activeBuildConfiguration())
|
||||
m_environment = bc->environment();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::debug(const QString &debuggerExecutable, const QString &debuggerArguments)
|
||||
{
|
||||
m_debuggerExecutable = debuggerExecutable;
|
||||
m_debuggerArguments = debuggerArguments;
|
||||
startWinRtRunner(Debug);
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::start()
|
||||
{
|
||||
startWinRtRunner(Start);
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::stop()
|
||||
{
|
||||
if (m_process)
|
||||
m_process->interrupt();
|
||||
else
|
||||
startWinRtRunner(Stop);
|
||||
}
|
||||
|
||||
bool WinRtRunnerHelper::waitForStarted(int msecs)
|
||||
{
|
||||
QTC_ASSERT(m_process, return false);
|
||||
return m_process->waitForStarted(msecs);
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::setRunControl(ProjectExplorer::RunControl *runControl)
|
||||
{
|
||||
m_messenger = runControl;
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::onProcessReadyReadStdOut()
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
if (m_messenger) {
|
||||
m_messenger->appendMessage(QString::fromLocal8Bit(
|
||||
m_process->readAllStandardOutput()), Utils::StdOutFormat);
|
||||
}
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::onProcessReadyReadStdErr()
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
if (m_messenger) {
|
||||
m_messenger->appendMessage(QString::fromLocal8Bit(
|
||||
m_process->readAllStandardError()), Utils::StdErrFormat);
|
||||
}
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus)
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
m_process->disconnect();
|
||||
m_process->deleteLater();
|
||||
m_process = 0;
|
||||
emit finished(exitCode, exitStatus);
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::onProcessError(QProcess::ProcessError processError)
|
||||
{
|
||||
QTC_ASSERT(m_process, return);
|
||||
if (m_messenger) {
|
||||
m_messenger->appendMessage(tr("Error while executing the WinRT Runner Tool: %1\n").arg(
|
||||
m_process->errorString()),
|
||||
Utils::ErrorMessageFormat);
|
||||
}
|
||||
m_process->disconnect();
|
||||
m_process->deleteLater();
|
||||
m_process = 0;
|
||||
emit error(processError);
|
||||
}
|
||||
|
||||
void WinRtRunnerHelper::startWinRtRunner(const RunConf &conf)
|
||||
{
|
||||
using namespace Utils;
|
||||
QString runnerArgs;
|
||||
QtcProcess::addArg(&runnerArgs, QStringLiteral("--profile"));
|
||||
QtcProcess::addArg(&runnerArgs, m_isWinPhone ? QStringLiteral("xap") : QStringLiteral("appx"));
|
||||
if (m_device) {
|
||||
QtcProcess::addArg(&runnerArgs, QStringLiteral("--device"));
|
||||
QtcProcess::addArg(&runnerArgs, QString::number(m_device->deviceId()));
|
||||
}
|
||||
|
||||
Utils::QtcProcess *process = 0;
|
||||
bool connectProcess = false;
|
||||
|
||||
switch (conf) {
|
||||
case Debug:
|
||||
Utils::QtcProcess::addArg(&runnerArgs, QStringLiteral("--debug"));
|
||||
Utils::QtcProcess::addArg(&runnerArgs, m_debuggerExecutable);
|
||||
if (!m_debuggerArguments.isEmpty()) {
|
||||
Utils::QtcProcess::addArg(&runnerArgs, QStringLiteral("--debugger-arguments"));
|
||||
Utils::QtcProcess::addArg(&runnerArgs, m_debuggerArguments);
|
||||
}
|
||||
// fall through
|
||||
case Start:
|
||||
QtcProcess::addArgs(&runnerArgs, QStringLiteral("--start --stop --install --wait 0"));
|
||||
connectProcess = true;
|
||||
QTC_ASSERT(!m_process, m_process->deleteLater());
|
||||
m_process = new QtcProcess(this);
|
||||
process = m_process;
|
||||
break;
|
||||
case Stop:
|
||||
Utils::QtcProcess::addArgs(&runnerArgs, QStringLiteral("--stop"));
|
||||
process = new QtcProcess(this);
|
||||
break;
|
||||
}
|
||||
|
||||
QtcProcess::addArg(&runnerArgs, m_executableFilePath);
|
||||
if (!m_arguments.isEmpty())
|
||||
QtcProcess::addArgs(&runnerArgs, m_arguments);
|
||||
|
||||
if (m_messenger) {
|
||||
m_messenger->appendMessage(QStringLiteral("winrtrunner ") + runnerArgs + QLatin1Char('\n'),
|
||||
Utils::NormalMessageFormat);
|
||||
}
|
||||
|
||||
if (connectProcess) {
|
||||
connect(process, SIGNAL(started()), SIGNAL(started()));
|
||||
connect(process, SIGNAL(finished(int, QProcess::ExitStatus)),
|
||||
SLOT(onProcessFinished(int, QProcess::ExitStatus)));
|
||||
connect(process, SIGNAL(error(QProcess::ProcessError)),
|
||||
SLOT(onProcessError(QProcess::ProcessError)));
|
||||
connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onProcessReadyReadStdOut()));
|
||||
connect(process, SIGNAL(readyReadStandardError()), SLOT(onProcessReadyReadStdErr()));
|
||||
}
|
||||
|
||||
process->setUseCtrlCStub(true);
|
||||
process->setCommand(m_runnerFilePath, runnerArgs);
|
||||
process->setEnvironment(m_environment);
|
||||
process->setWorkingDirectory(QFileInfo(m_executableFilePath).absolutePath());
|
||||
process->start();
|
||||
}
|
||||
99
src/plugins/winrt/winrtrunnerhelper.h
Normal file
99
src/plugins/winrt/winrtrunnerhelper.h
Normal file
@@ -0,0 +1,99 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
|
||||
#ifndef WINRTRUNNERHELPER_H
|
||||
#define WINRTRUNNERHELPER_H
|
||||
|
||||
#include "winrtdevice.h"
|
||||
|
||||
#include <utils/environment.h>
|
||||
#include <utils/outputformat.h>
|
||||
|
||||
#include <QObject>
|
||||
#include <QProcess>
|
||||
|
||||
|
||||
namespace Utils { class QtcProcess; }
|
||||
namespace ProjectExplorer { class RunControl; }
|
||||
|
||||
namespace WinRt {
|
||||
namespace Internal {
|
||||
|
||||
class WinRtRunConfiguration;
|
||||
|
||||
class WinRtRunnerHelper : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
WinRtRunnerHelper(ProjectExplorer::RunControl *runControl);
|
||||
WinRtRunnerHelper(WinRtRunConfiguration *runConfiguration, QString *errormessage);
|
||||
|
||||
void debug(const QString &debuggerExecutable, const QString &debuggerArguments = QString());
|
||||
void start();
|
||||
|
||||
void stop();
|
||||
|
||||
bool waitForStarted(int msecs = 10000);
|
||||
void setRunControl(ProjectExplorer::RunControl *runControl);
|
||||
|
||||
signals:
|
||||
void started();
|
||||
void finished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void error(QProcess::ProcessError error);
|
||||
|
||||
private slots:
|
||||
void onProcessReadyReadStdOut();
|
||||
void onProcessReadyReadStdErr();
|
||||
void onProcessFinished(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void onProcessError(QProcess::ProcessError processError);
|
||||
|
||||
private:
|
||||
enum RunConf { Start, Stop, Debug };
|
||||
void startWinRtRunner(const RunConf &conf);
|
||||
bool init(WinRtRunConfiguration *runConfiguration, QString *errorMessage);
|
||||
|
||||
ProjectExplorer::RunControl *m_messenger;
|
||||
WinRtRunConfiguration *m_runConfiguration;
|
||||
WinRtDevice::ConstPtr m_device;
|
||||
Utils::Environment m_environment;
|
||||
QString m_runnerFilePath;
|
||||
QString m_executableFilePath;
|
||||
QString m_debuggerExecutable;
|
||||
QString m_debuggerArguments;
|
||||
QString m_arguments;
|
||||
bool m_uninstallAfterStop;
|
||||
bool m_isWinPhone;
|
||||
Utils::QtcProcess *m_process;
|
||||
};
|
||||
|
||||
} // namespace WinRt
|
||||
} // namespace Internal
|
||||
|
||||
#endif // WINRTRUNNERHELPER_H
|
||||
@@ -9,8 +9,9 @@ SUBDIRS = qtpromaker \
|
||||
buildoutputparser
|
||||
|
||||
win32 {
|
||||
SUBDIRS += qtcdebugger
|
||||
SUBDIRS += wininterrupt
|
||||
SUBDIRS += qtcdebugger \
|
||||
wininterrupt \
|
||||
winrtdebughelper
|
||||
}
|
||||
|
||||
mac {
|
||||
|
||||
@@ -10,6 +10,7 @@ Project {
|
||||
"sdktool/sdktool.qbs",
|
||||
"valgrindfake/valgrindfake.qbs",
|
||||
"3rdparty/iossim/iossim.qbs",
|
||||
"iostool/iostool.qbs"
|
||||
"iostool/iostool.qbs",
|
||||
"winrtdebughelper/winrtdebughelper.qbs"
|
||||
].concat(project.additionalTools)
|
||||
}
|
||||
|
||||
78
src/tools/winrtdebughelper/winrtdebughelper.cpp
Normal file
78
src/tools/winrtdebughelper/winrtdebughelper.cpp
Normal file
@@ -0,0 +1,78 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
|
||||
** Contact: http://www.qt-project.org/legal
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Digia. For licensing terms and
|
||||
** conditions see http://qt.digia.com/licensing. For further information
|
||||
** use the contact form at http://qt.digia.com/contact-us.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** In addition, as a special exception, Digia gives you certain additional
|
||||
** rights. These rights are described in the Digia Qt LGPL Exception
|
||||
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <Windows.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int pid = -1;
|
||||
const size_t maxPipeNameSize = 256;
|
||||
wchar_t pipeName[maxPipeNameSize] = { 0 };
|
||||
|
||||
for (int i = 0; i < argc - 1; ++i) {
|
||||
if (!strcmp(argv[i], "-t")) {
|
||||
++i;
|
||||
if (swprintf(pipeName, maxPipeNameSize, L"%hs", argv[i]) < 0)
|
||||
return 0; // Pipe name too long
|
||||
} else if (!strcmp(argv[i], "-p")) {
|
||||
++i;
|
||||
|
||||
// check if -p is followed by a number
|
||||
const char *pidString = argv[i];
|
||||
char *end;
|
||||
pid = strtoul(pidString, &end, 0);
|
||||
if (*end != 0)
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (pid < 0)
|
||||
return 0;
|
||||
|
||||
if (*pipeName == 0)
|
||||
swprintf(pipeName, maxPipeNameSize, L"\\\\.\\pipe\\QtCreatorWinRtDebugPIDPipe");
|
||||
HANDLE pipe;
|
||||
while (true) {
|
||||
pipe = CreateFile(pipeName, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (pipe != INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
if ((GetLastError() != ERROR_PIPE_BUSY) || (!WaitNamedPipe(pipeName, 10000)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
const size_t msgBufferSize = 15;
|
||||
char pidMessageBuffer[msgBufferSize];
|
||||
int length = sprintf_s(pidMessageBuffer, msgBufferSize, "PID:%d", pid);
|
||||
if (length >= 0)
|
||||
WriteFile(pipe, pidMessageBuffer, length, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
17
src/tools/winrtdebughelper/winrtdebughelper.pro
Normal file
17
src/tools/winrtdebughelper/winrtdebughelper.pro
Normal file
@@ -0,0 +1,17 @@
|
||||
CONFIG += warn_on console
|
||||
CONFIG -= qt app_bundle
|
||||
|
||||
include(../../../qtcreator.pri)
|
||||
|
||||
TEMPLATE = app
|
||||
DESTDIR = $$IDE_LIBEXEC_PATH
|
||||
SOURCES = winrtdebughelper.cpp
|
||||
|
||||
build_all:!build_pass {
|
||||
CONFIG -= build_all
|
||||
CONFIG += release
|
||||
}
|
||||
|
||||
TARGET = winrtdebughelper
|
||||
target.path = $$IDE_LIBEXEC_PATH
|
||||
INSTALLS += target
|
||||
13
src/tools/winrtdebughelper/winrtdebughelper.qbs
Normal file
13
src/tools/winrtdebughelper/winrtdebughelper.qbs
Normal file
@@ -0,0 +1,13 @@
|
||||
import qbs 1.0
|
||||
import QtcTool
|
||||
|
||||
QtcTool {
|
||||
name: "winrtdebughelper"
|
||||
condition: qbs.targetOS.contains("windows")
|
||||
|
||||
Depends { name: "Qt.network" }
|
||||
|
||||
files: [
|
||||
"winrtdebughelper.cpp",
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user