[impl] Delegate update job to child process
This commit is contained in:
parent
fe7c1bb368
commit
4eac37cfae
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,3 +6,5 @@
|
|||||||
/Debug/
|
/Debug/
|
||||||
/libModuleManagerTest/Debug/
|
/libModuleManagerTest/Debug/
|
||||||
/Release/
|
/Release/
|
||||||
|
/CCEngineLoader/Debug/
|
||||||
|
/CCEngineLoader/Release/
|
||||||
|
|||||||
@ -21,9 +21,11 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="src\CCEngine.cpp" />
|
<ClCompile Include="src\CCEngine.cpp" />
|
||||||
<ClCompile Include="src\CCServer.cpp" />
|
<ClCompile Include="src\CCServer.cpp" />
|
||||||
|
<ClCompile Include="src\ProcessUtils.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\CCServer.h" />
|
<ClInclude Include="src\CCServer.h" />
|
||||||
|
<ClInclude Include="src\ProcessUtils.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\libLicenseClient\libLicenseClient.vcxproj">
|
<ProjectReference Include="..\..\libLicenseClient\libLicenseClient.vcxproj">
|
||||||
|
|||||||
@ -17,10 +17,16 @@
|
|||||||
<ClCompile Include="src\CCServer.cpp">
|
<ClCompile Include="src\CCServer.cpp">
|
||||||
<Filter>src</Filter>
|
<Filter>src</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="src\ProcessUtils.cpp">
|
||||||
|
<Filter>src</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="src\CCServer.h">
|
<ClInclude Include="src\CCServer.h">
|
||||||
<Filter>src</Filter>
|
<Filter>src</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="src\ProcessUtils.h">
|
||||||
|
<Filter>src</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
@ -1,9 +1,11 @@
|
|||||||
|
#include "CachedDownloader.h"
|
||||||
#include "SystemParamsProvider_win.h"
|
#include "SystemParamsProvider_win.h"
|
||||||
#include "HTTPClient.h"
|
#include "HTTPClient.h"
|
||||||
#include "LicenseClient.h"
|
#include "LicenseClient.h"
|
||||||
#include "CCServer.h"
|
#include "CCServer.h"
|
||||||
#include "ModuleManager.h"
|
#include "ModuleManager.h"
|
||||||
#include "JSONModuleDatabase.h"
|
#include "JSONModuleDatabase.h"
|
||||||
|
#include "ProcessUtils.h"
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
@ -11,6 +13,11 @@
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
static const std::string updateCacheFolder = ".upd";
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
auto appDir = boost::filesystem::system_complete(argv[0]).parent_path();
|
auto appDir = boost::filesystem::system_complete(argv[0]).parent_path();
|
||||||
@ -69,19 +76,41 @@ int main(int argc, char* argv[])
|
|||||||
std::cin >> what;
|
std::cin >> what;
|
||||||
if (what == 'y')
|
if (what == 'y')
|
||||||
{
|
{
|
||||||
ModuleManager moduleManager(appDir.string(), moduleDatabase, httpClient);
|
|
||||||
for (const auto& update : moduleUpdates)
|
|
||||||
{
|
{
|
||||||
restartRequired = restartRequired || (update.flag & static_cast<uint32_t>(ModuleUpdateFlags::restartRequired));
|
CachedDownloader cachedDownloader(appDir / updateCacheFolder, httpClient);
|
||||||
moduleManager.applyUpdate(update.moduleId, update);
|
for (const auto& update : moduleUpdates)
|
||||||
}
|
{
|
||||||
}
|
cachedDownloader.download(update.updateUri);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (restartRequired)
|
std::ofstream os((appDir / updateCacheFolder / ".updates.json").native());
|
||||||
{
|
::serialize(os, moduleUpdates);
|
||||||
std::cout << "Restart required" << std::endl;
|
}
|
||||||
return 0;
|
|
||||||
|
std::ostringstream command;
|
||||||
|
command << (appDir / "CCEngineLoader.exe") << " " << getCurrentProcessId();
|
||||||
|
|
||||||
|
auto stdOutPipe = createAnonymousPipe(false, true);
|
||||||
|
auto updProcess = createPipedProcess(command.str(), nullptr, std::move(stdOutPipe));
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
auto line = updProcess.readLine();
|
||||||
|
std::cout << line << std::endl;
|
||||||
|
if (line == "RestartRequired")
|
||||||
|
{
|
||||||
|
// Exit the current application to allow updater to continue
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ModuleManager moduleManager(appDir.string(), moduleDatabase, httpClient);
|
||||||
|
// for (const auto& update : moduleUpdates)
|
||||||
|
// {
|
||||||
|
// restartRequired = restartRequired || (update.flag & static_cast<uint32_t>(ModuleUpdateFlags::restartRequired));
|
||||||
|
// moduleManager.applyUpdate(update.moduleId, update);
|
||||||
|
// }
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto docRoot = appDir / "data";
|
auto docRoot = appDir / "data";
|
||||||
|
|||||||
294
CCEngine/src/ProcessUtils.cpp
Normal file
294
CCEngine/src/ProcessUtils.cpp
Normal file
@ -0,0 +1,294 @@
|
|||||||
|
#include "ProcessUtils.h"
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
class AnonymousPipeImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnonymousPipeImpl()
|
||||||
|
{
|
||||||
|
m_secAttr.nLength = sizeof(SECURITY_ATTRIBUTES);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual ~AnonymousPipeImpl()
|
||||||
|
{
|
||||||
|
CloseHandle(m_readEnd);
|
||||||
|
CloseHandle(m_writeEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
HANDLE& readEnd() { return m_readEnd; }
|
||||||
|
HANDLE& writeEnd() { return m_writeEnd; }
|
||||||
|
SECURITY_ATTRIBUTES& secAttr() { return m_secAttr; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t write(const char* data, size_t size)
|
||||||
|
{
|
||||||
|
DWORD written = 0;
|
||||||
|
auto success = WriteFile(m_writeEnd, data, size, &written, NULL);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not write pipe");
|
||||||
|
}
|
||||||
|
return static_cast<size_t>(written);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t read(char* data, size_t size)
|
||||||
|
{
|
||||||
|
DWORD bytesRead = 0;
|
||||||
|
auto success = ReadFile(m_readEnd, data, size, &bytesRead, NULL);
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not read pipe");
|
||||||
|
}
|
||||||
|
return static_cast<size_t>(bytesRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
SECURITY_ATTRIBUTES m_secAttr = { 0 };
|
||||||
|
HANDLE m_readEnd = nullptr;
|
||||||
|
HANDLE m_writeEnd = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<AnonymousPipeImpl> createAnonymousPipe(bool readEndInheritable, bool writeEndInheritable)
|
||||||
|
{
|
||||||
|
auto pipe = std::make_unique<AnonymousPipeImpl>();
|
||||||
|
|
||||||
|
bool inheritable = readEndInheritable || writeEndInheritable;
|
||||||
|
pipe->secAttr().bInheritHandle = inheritable;
|
||||||
|
pipe->secAttr().lpSecurityDescriptor = NULL;
|
||||||
|
|
||||||
|
if (!CreatePipe(&pipe->readEnd(), &pipe->writeEnd(), &pipe->secAttr(), 0))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not create pipe");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inheritable && !readEndInheritable)
|
||||||
|
{
|
||||||
|
if (!SetHandleInformation(pipe->readEnd(), HANDLE_FLAG_INHERIT, 0))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Setting pipe flags failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (inheritable && !writeEndInheritable)
|
||||||
|
{
|
||||||
|
if (!SetHandleInformation(pipe->writeEnd(), HANDLE_FLAG_INHERIT, 0))
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Setting pipe flags failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return pipe;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
class ProcessHandleImpl
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ProcessHandleImpl(HANDLE processHandle, HANDLE threadHandle = nullptr)
|
||||||
|
: m_processHandle(processHandle)
|
||||||
|
, m_threadHandle(threadHandle)
|
||||||
|
{}
|
||||||
|
ProcessHandleImpl(const ProcessHandleImpl&) = delete;
|
||||||
|
ProcessHandleImpl& operator= (const ProcessHandleImpl&) = delete;
|
||||||
|
|
||||||
|
virtual ~ProcessHandleImpl()
|
||||||
|
{
|
||||||
|
CloseHandle(m_processHandle);
|
||||||
|
CloseHandle(m_threadHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool waitForExit(const std::chrono::milliseconds& ms)
|
||||||
|
{
|
||||||
|
DWORD ret = WaitForSingleObject(m_processHandle, static_cast<DWORD>(ms.count()));
|
||||||
|
if (ret == WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (ret == WAIT_TIMEOUT)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
throw std::runtime_error("Wait for exit failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
void waitForExit()
|
||||||
|
{
|
||||||
|
DWORD ret = WaitForSingleObject(m_processHandle, INFINITE);
|
||||||
|
if (ret != WAIT_OBJECT_0)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Inifinite wait for exit failed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isRunning()
|
||||||
|
{
|
||||||
|
return !waitForExit(std::chrono::milliseconds(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
int exitCode()
|
||||||
|
{
|
||||||
|
DWORD exitCode;
|
||||||
|
auto result = GetExitCodeProcess(m_processHandle, &exitCode);
|
||||||
|
if (!result)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not get exit code");
|
||||||
|
}
|
||||||
|
return exitCode;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
HANDLE m_processHandle = nullptr;
|
||||||
|
HANDLE m_threadHandle = nullptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<ProcessHandleImpl> openProcess(DWORD processId)
|
||||||
|
{
|
||||||
|
auto retVal = OpenProcess(SYNCHRONIZE, false, processId);
|
||||||
|
if (retVal == nullptr)
|
||||||
|
{
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<ProcessHandleImpl>(retVal);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Create a child process that uses the previously created pipes for STDIN and STDOUT. */
|
||||||
|
std::unique_ptr<ProcessHandleImpl> createPipedProcess(const std::string& commandLine, HANDLE childPipeReadEnd, HANDLE childPipeWriteEnd)
|
||||||
|
{
|
||||||
|
// Set up members of the STARTUPINFO structure.
|
||||||
|
// This structure specifies the STDIN and STDOUT handles for redirection.
|
||||||
|
PROCESS_INFORMATION piProcInfo = { 0 };
|
||||||
|
STARTUPINFO siStartInfo = { 0 };
|
||||||
|
siStartInfo.cb = sizeof(STARTUPINFO);
|
||||||
|
siStartInfo.hStdError = childPipeWriteEnd;
|
||||||
|
siStartInfo.hStdOutput = childPipeWriteEnd;
|
||||||
|
siStartInfo.hStdInput = childPipeReadEnd;
|
||||||
|
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
|
// Create the child process.
|
||||||
|
|
||||||
|
bool success = CreateProcess(NULL,
|
||||||
|
(LPSTR)commandLine.c_str(), // command line
|
||||||
|
NULL, // process security attributes
|
||||||
|
NULL, // primary thread security attributes
|
||||||
|
TRUE, // handles are inherited
|
||||||
|
0, // creation flags
|
||||||
|
NULL, // use parent's environment
|
||||||
|
NULL, // use parent's current directory
|
||||||
|
&siStartInfo, // STARTUPINFO pointer
|
||||||
|
&piProcInfo); // receives PROCESS_INFORMATION
|
||||||
|
|
||||||
|
// If an error occurs, exit the application.
|
||||||
|
if (!success)
|
||||||
|
{
|
||||||
|
throw std::runtime_error("Could not create process");
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_unique<ProcessHandleImpl>(piProcInfo.hProcess, piProcInfo.hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessHandle::ProcessHandle(std::unique_ptr<detail::ProcessHandleImpl> initVal)
|
||||||
|
: m_impl(std::move(initVal))
|
||||||
|
{}
|
||||||
|
|
||||||
|
ProcessHandle::~ProcessHandle()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ProcessHandle::waitForExit(const std::chrono::milliseconds& ms)
|
||||||
|
{
|
||||||
|
return m_impl->waitForExit(ms);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProcessHandle::waitForExit()
|
||||||
|
{
|
||||||
|
return m_impl->waitForExit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ProcessHandle::exitCode()
|
||||||
|
{
|
||||||
|
return m_impl->exitCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
AnonymousPipe::AnonymousPipe(std::unique_ptr<detail::AnonymousPipeImpl> initVal)
|
||||||
|
: m_impl(std::move(initVal))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
AnonymousPipe::~AnonymousPipe()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AnonymousPipe::write(const char* data, size_t size)
|
||||||
|
{
|
||||||
|
return m_impl->write(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t AnonymousPipe::read(char* data, size_t size)
|
||||||
|
{
|
||||||
|
return m_impl->read(data, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AnonymousPipe> createAnonymousPipe(bool inheritableReadEnd, bool inheritableWriteEnd)
|
||||||
|
{
|
||||||
|
return std::make_unique<AnonymousPipe>(detail::createAnonymousPipe(inheritableReadEnd, inheritableWriteEnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessHandle openProcess(uint32_t processId)
|
||||||
|
{
|
||||||
|
return { detail::openProcess(processId) };
|
||||||
|
}
|
||||||
|
|
||||||
|
PipedProcessHandle createPipedProcess(const std::string & commandLine, std::unique_ptr<AnonymousPipe> stdinPipe, std::unique_ptr<AnonymousPipe> stdoutPipe)
|
||||||
|
{
|
||||||
|
auto hisWriteEnd = stdoutPipe ? stdoutPipe->_impl().writeEnd() : nullptr;
|
||||||
|
auto hisReadEnd = stdinPipe ? stdinPipe->_impl().readEnd() : nullptr;
|
||||||
|
auto processHandle = detail::createPipedProcess(commandLine, hisReadEnd, hisWriteEnd);
|
||||||
|
|
||||||
|
return {
|
||||||
|
std::make_unique<ProcessHandle>(std::move(processHandle)),
|
||||||
|
std::move(stdinPipe),
|
||||||
|
std::move(stdoutPipe)};
|
||||||
|
}
|
||||||
|
|
||||||
|
void PipedProcessHandle::writeLine(const std::string& line)
|
||||||
|
{
|
||||||
|
stdinPipe->write(line.data(), line.size());
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << std::endl;
|
||||||
|
auto tmpstr = ss.str();
|
||||||
|
stdinPipe->write(tmpstr.data(), tmpstr.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string PipedProcessHandle::readLine()
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
char buf[1] = { 0 };
|
||||||
|
stdoutPipe->read(buf, 1);
|
||||||
|
while (buf[0] != '\n')
|
||||||
|
{
|
||||||
|
if (buf[0] != '\r') {
|
||||||
|
ss.write(buf, 1);
|
||||||
|
}
|
||||||
|
stdoutPipe->read(buf, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long getCurrentProcessId()
|
||||||
|
{
|
||||||
|
return static_cast<unsigned long>(GetCurrentProcessId());
|
||||||
|
}
|
||||||
62
CCEngine/src/ProcessUtils.h
Normal file
62
CCEngine/src/ProcessUtils.h
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
class AnonymousPipeImpl;
|
||||||
|
class ProcessHandleImpl;
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnonymousPipe
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AnonymousPipe(std::unique_ptr<detail::AnonymousPipeImpl> initVal);
|
||||||
|
virtual ~AnonymousPipe();
|
||||||
|
|
||||||
|
public:
|
||||||
|
size_t write(const char* data, size_t size);
|
||||||
|
size_t read(char *data, size_t size);
|
||||||
|
|
||||||
|
detail::AnonymousPipeImpl& _impl() { return (*m_impl); };
|
||||||
|
private:
|
||||||
|
std::unique_ptr<detail::AnonymousPipeImpl> m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::unique_ptr<AnonymousPipe> createAnonymousPipe(bool inheritableReadEnd, bool inheritableWriteEnd);
|
||||||
|
|
||||||
|
class ProcessHandle
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ProcessHandle(std::unique_ptr<detail::ProcessHandleImpl> initVal);
|
||||||
|
virtual ~ProcessHandle();
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool waitForExit(const std::chrono::milliseconds& ms);
|
||||||
|
void waitForExit();
|
||||||
|
int exitCode();
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<detail::ProcessHandleImpl> m_impl;
|
||||||
|
};
|
||||||
|
|
||||||
|
ProcessHandle openProcess(uint32_t processId);
|
||||||
|
|
||||||
|
struct PipedProcessHandle
|
||||||
|
{
|
||||||
|
void writeLine(const std::string& line);
|
||||||
|
std::string readLine();
|
||||||
|
|
||||||
|
std::unique_ptr<ProcessHandle> processHandle;
|
||||||
|
std::unique_ptr<AnonymousPipe> stdinPipe;
|
||||||
|
std::unique_ptr<AnonymousPipe> stdoutPipe;
|
||||||
|
};
|
||||||
|
|
||||||
|
PipedProcessHandle createPipedProcess(
|
||||||
|
const std::string& commandLine,
|
||||||
|
std::unique_ptr<AnonymousPipe> stdinPipe,
|
||||||
|
std::unique_ptr<AnonymousPipe> stdoutPipe);
|
||||||
|
|
||||||
|
unsigned long getCurrentProcessId();
|
||||||
Binary file not shown.
@ -30,27 +30,27 @@
|
|||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
<UseDebugLibraries>true</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||||
<ConfigurationType>Application</ConfigurationType>
|
<ConfigurationType>Application</ConfigurationType>
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
<UseDebugLibraries>false</UseDebugLibraries>
|
||||||
<PlatformToolset>v141</PlatformToolset>
|
<PlatformToolset>v141</PlatformToolset>
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
<CharacterSet>MultiByte</CharacterSet>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||||
<ImportGroup Label="ExtensionSettings">
|
<ImportGroup Label="ExtensionSettings">
|
||||||
@ -94,12 +94,13 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)..\..\libLicenseClient\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -108,12 +109,13 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>Disabled</Optimization>
|
<Optimization>Disabled</Optimization>
|
||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)..\..\libLicenseClient\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -122,7 +124,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
@ -130,6 +132,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)..\..\libLicenseClient\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -140,7 +143,7 @@
|
|||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||||
<WarningLevel>Level3</WarningLevel>
|
<WarningLevel>Level3</WarningLevel>
|
||||||
<Optimization>MaxSpeed</Optimization>
|
<Optimization>MaxSpeed</Optimization>
|
||||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||||
@ -148,6 +151,7 @@
|
|||||||
<SDLCheck>true</SDLCheck>
|
<SDLCheck>true</SDLCheck>
|
||||||
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
<PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||||
<ConformanceMode>true</ConformanceMode>
|
<ConformanceMode>true</ConformanceMode>
|
||||||
|
<AdditionalIncludeDirectories>$(ProjectDir)..\..\libLicenseClient\api;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
@ -169,6 +173,11 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\libLicenseClient\libLicenseClient.vcxproj">
|
||||||
|
<Project>{51345e59-83e5-4389-93a9-0131b40522b7}</Project>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
<ImportGroup Label="ExtensionTargets">
|
<ImportGroup Label="ExtensionTargets">
|
||||||
</ImportGroup>
|
</ImportGroup>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user