mirror of
https://github.com/ModOrganizer2/mob.git
synced 2026-07-27 14:07:05 -07:00
split process
This commit is contained in:
@@ -38,7 +38,6 @@ int run(int argc, char** argv)
|
||||
::SetConsoleCtrlHandler(signal_handler, TRUE);
|
||||
|
||||
curl_init curl;
|
||||
vcvars();
|
||||
|
||||
current_env::set(
|
||||
"PATH",
|
||||
|
||||
-227
@@ -6,233 +6,6 @@
|
||||
namespace builder
|
||||
{
|
||||
|
||||
process::impl::impl(const impl& i)
|
||||
: interrupt(i.interrupt.load())
|
||||
{
|
||||
}
|
||||
|
||||
process::impl& process::impl::operator=(const impl& i)
|
||||
{
|
||||
interrupt = i.interrupt.load();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
process::process()
|
||||
: flags_(process::noflags), code_(0)
|
||||
{
|
||||
}
|
||||
|
||||
process::~process()
|
||||
{
|
||||
try
|
||||
{
|
||||
join();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
process process::raw(const std::string& cmd)
|
||||
{
|
||||
process p;
|
||||
p.raw_ = cmd;
|
||||
return p;
|
||||
}
|
||||
|
||||
process& process::name(const std::string& name)
|
||||
{
|
||||
name_ = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string& process::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
process& process::binary(const fs::path& p)
|
||||
{
|
||||
bin_ = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const fs::path& process::binary() const
|
||||
{
|
||||
return bin_;
|
||||
}
|
||||
|
||||
process& process::cwd(const fs::path& p)
|
||||
{
|
||||
cwd_ = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const fs::path& process::cwd() const
|
||||
{
|
||||
return cwd_;
|
||||
}
|
||||
|
||||
process& process::flags(flags_t f)
|
||||
{
|
||||
flags_ = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
process::flags_t process::flags() const
|
||||
{
|
||||
return flags_;
|
||||
}
|
||||
|
||||
process& process::env(const builder::env& e)
|
||||
{
|
||||
env_ = e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string process::make_name() const
|
||||
{
|
||||
if (!name_.empty())
|
||||
return name_;
|
||||
|
||||
return make_cmd();
|
||||
}
|
||||
|
||||
std::string process::make_cmd() const
|
||||
{
|
||||
if (!raw_.empty())
|
||||
return raw_;
|
||||
|
||||
std::string s = "\"" + bin_.string() + "\" " + cmd_.string();
|
||||
|
||||
if ((flags_ & stdout_is_verbose) == 0)
|
||||
s += redir_nul();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void process::pipe_into(const process& p)
|
||||
{
|
||||
raw_ = make_cmd() + " | " + p.make_cmd();
|
||||
}
|
||||
|
||||
void process::run()
|
||||
{
|
||||
if (!cwd_.empty())
|
||||
debug("> cd " + cwd_.string());
|
||||
|
||||
const auto what = make_cmd();
|
||||
debug("> " + what);
|
||||
|
||||
if (conf::dry())
|
||||
return;
|
||||
|
||||
do_run(what);
|
||||
}
|
||||
|
||||
void process::do_run(const std::string& what)
|
||||
{
|
||||
STARTUPINFOA si = { .cb=sizeof(si) };
|
||||
PROCESS_INFORMATION pi = {};
|
||||
|
||||
const std::string cmd = current_env::get("COMSPEC");
|
||||
const std::string args = "/C \"" + what + "\"";
|
||||
|
||||
const char* cwd_p = nullptr;
|
||||
std::string cwd_s;
|
||||
|
||||
if (!cwd_.empty())
|
||||
{
|
||||
create_directories(cwd_);
|
||||
cwd_s = cwd_.string();
|
||||
cwd_p = (cwd_s.empty() ? nullptr : cwd_s.c_str());
|
||||
}
|
||||
|
||||
const auto r = ::CreateProcessA(
|
||||
cmd.c_str(), const_cast<char*>(args.c_str()),
|
||||
nullptr, nullptr, FALSE, CREATE_NEW_PROCESS_GROUP,
|
||||
env_.get_pointers(), cwd_p, &si, &pi);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
bail_out("failed to start '" + cmd + "'", e);
|
||||
}
|
||||
|
||||
::CloseHandle(pi.hThread);
|
||||
impl_.handle.reset(pi.hProcess);
|
||||
}
|
||||
|
||||
void process::interrupt()
|
||||
{
|
||||
impl_.interrupt = true;
|
||||
}
|
||||
|
||||
void process::join()
|
||||
{
|
||||
if (!impl_.handle)
|
||||
return;
|
||||
|
||||
bool interrupted = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const auto r = WaitForSingleObject(impl_.handle.get(), 100);
|
||||
|
||||
if (r == WAIT_OBJECT_0)
|
||||
{
|
||||
// done
|
||||
GetExitCodeProcess(impl_.handle.get(), &code_);
|
||||
|
||||
if ((flags_ & allow_failure) || impl_.interrupt)
|
||||
break;
|
||||
|
||||
if (code_ != 0)
|
||||
{
|
||||
impl_.handle = {};
|
||||
bail_out(make_name() + " returned " + std::to_string(code_));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (r == WAIT_TIMEOUT)
|
||||
{
|
||||
if (impl_.interrupt && !interrupted)
|
||||
{
|
||||
const auto pid = GetProcessId(impl_.handle.get());
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
error("process id is 0, terminating instead");
|
||||
::TerminateProcess(impl_.handle.get(), 0xffff);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("sending sigint to " + std::to_string(pid));
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid);
|
||||
}
|
||||
|
||||
interrupted = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto e = GetLastError();
|
||||
impl_.handle = {};
|
||||
bail_out("failed to wait on process", e);
|
||||
}
|
||||
|
||||
impl_.handle = {};
|
||||
}
|
||||
|
||||
int process::exit_code() const
|
||||
{
|
||||
return static_cast<int>(code_);
|
||||
}
|
||||
|
||||
|
||||
void op::touch(const fs::path& p)
|
||||
|
||||
@@ -5,116 +5,6 @@
|
||||
namespace builder
|
||||
{
|
||||
|
||||
void vcvars();
|
||||
|
||||
|
||||
class op;
|
||||
|
||||
class process
|
||||
{
|
||||
friend class op;
|
||||
|
||||
public:
|
||||
enum flags_t
|
||||
{
|
||||
noflags = 0x00,
|
||||
stdout_is_verbose = 0x01,
|
||||
allow_failure = 0x02
|
||||
};
|
||||
|
||||
process();
|
||||
~process();
|
||||
|
||||
static process raw(const std::string& cmd);
|
||||
|
||||
static process pipe(const process& p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class... Processes>
|
||||
static process pipe(const process& p1, const process& p2, Processes&&... ps)
|
||||
{
|
||||
auto r = p1;
|
||||
r.pipe_into(p2);
|
||||
pipe(r, std::forward<Processes>(ps)...);
|
||||
return r;
|
||||
}
|
||||
|
||||
process& name(const std::string& name);
|
||||
const std::string& name() const;
|
||||
|
||||
process& binary(const fs::path& p);
|
||||
const fs::path& binary() const;
|
||||
|
||||
process& cwd(const fs::path& p);
|
||||
const fs::path& cwd() const;
|
||||
|
||||
process& flags(flags_t f);
|
||||
flags_t flags() const;
|
||||
|
||||
template <class... Args>
|
||||
process& arg(Args&&... args)
|
||||
{
|
||||
cmd_.arg(std::forward<Args>(args)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <template<class, class> class Container, class K, class V, class Alloc>
|
||||
process& args(const Container<std::pair<K, V>, Alloc>& v, cmd::flags f=cmd::noflags)
|
||||
{
|
||||
for (auto&& [name, value] : v)
|
||||
arg(name, value, f);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
process& args(const Container& v, cmd::flags f=cmd::noflags)
|
||||
{
|
||||
for (auto&& e : v)
|
||||
cmd_.arg(e, f);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
process& env(const builder::env& e);
|
||||
|
||||
void run();
|
||||
void interrupt();
|
||||
void join();
|
||||
|
||||
int exit_code() const;
|
||||
|
||||
private:
|
||||
struct impl
|
||||
{
|
||||
handle_ptr handle;
|
||||
std::atomic<bool> interrupt{false};
|
||||
|
||||
impl() = default;
|
||||
impl(const impl&);
|
||||
impl& operator=(const impl&);
|
||||
};
|
||||
|
||||
std::string name_;
|
||||
fs::path bin_;
|
||||
fs::path cwd_;
|
||||
flags_t flags_;
|
||||
cmd cmd_;
|
||||
builder::env env_;
|
||||
std::string raw_;
|
||||
|
||||
impl impl_;
|
||||
DWORD code_;
|
||||
|
||||
std::string make_name() const;
|
||||
std::string make_cmd() const;
|
||||
void pipe_into(const process& p);
|
||||
void do_run(const std::string& what);
|
||||
};
|
||||
|
||||
|
||||
class op
|
||||
{
|
||||
public:
|
||||
|
||||
+236
@@ -0,0 +1,236 @@
|
||||
#include "pch.h"
|
||||
#include "process.h"
|
||||
#include "conf.h"
|
||||
|
||||
namespace builder
|
||||
{
|
||||
|
||||
process::impl::impl(const impl& i)
|
||||
: interrupt(i.interrupt.load())
|
||||
{
|
||||
}
|
||||
|
||||
process::impl& process::impl::operator=(const impl& i)
|
||||
{
|
||||
interrupt = i.interrupt.load();
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
process::process()
|
||||
: flags_(process::noflags), code_(0)
|
||||
{
|
||||
}
|
||||
|
||||
process::~process()
|
||||
{
|
||||
try
|
||||
{
|
||||
join();
|
||||
}
|
||||
catch(...)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
process process::raw(const std::string& cmd)
|
||||
{
|
||||
process p;
|
||||
p.raw_ = cmd;
|
||||
return p;
|
||||
}
|
||||
|
||||
process& process::name(const std::string& name)
|
||||
{
|
||||
name_ = name;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string& process::name() const
|
||||
{
|
||||
return name_;
|
||||
}
|
||||
|
||||
process& process::binary(const fs::path& p)
|
||||
{
|
||||
bin_ = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const fs::path& process::binary() const
|
||||
{
|
||||
return bin_;
|
||||
}
|
||||
|
||||
process& process::cwd(const fs::path& p)
|
||||
{
|
||||
cwd_ = p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
const fs::path& process::cwd() const
|
||||
{
|
||||
return cwd_;
|
||||
}
|
||||
|
||||
process& process::flags(flags_t f)
|
||||
{
|
||||
flags_ = f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
process::flags_t process::flags() const
|
||||
{
|
||||
return flags_;
|
||||
}
|
||||
|
||||
process& process::env(const builder::env& e)
|
||||
{
|
||||
env_ = e;
|
||||
return *this;
|
||||
}
|
||||
|
||||
std::string process::make_name() const
|
||||
{
|
||||
if (!name_.empty())
|
||||
return name_;
|
||||
|
||||
return make_cmd();
|
||||
}
|
||||
|
||||
std::string process::make_cmd() const
|
||||
{
|
||||
if (!raw_.empty())
|
||||
return raw_;
|
||||
|
||||
std::string s = "\"" + bin_.string() + "\" " + cmd_.string();
|
||||
|
||||
if ((flags_ & stdout_is_verbose) == 0)
|
||||
s += redir_nul();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
void process::pipe_into(const process& p)
|
||||
{
|
||||
raw_ = make_cmd() + " | " + p.make_cmd();
|
||||
}
|
||||
|
||||
void process::run()
|
||||
{
|
||||
if (!cwd_.empty())
|
||||
debug("> cd " + cwd_.string());
|
||||
|
||||
const auto what = make_cmd();
|
||||
debug("> " + what);
|
||||
|
||||
if (conf::dry())
|
||||
return;
|
||||
|
||||
do_run(what);
|
||||
}
|
||||
|
||||
void process::do_run(const std::string& what)
|
||||
{
|
||||
STARTUPINFOA si = { .cb=sizeof(si) };
|
||||
PROCESS_INFORMATION pi = {};
|
||||
|
||||
const std::string cmd = current_env::get("COMSPEC");
|
||||
const std::string args = "/C \"" + what + "\"";
|
||||
|
||||
const char* cwd_p = nullptr;
|
||||
std::string cwd_s;
|
||||
|
||||
if (!cwd_.empty())
|
||||
{
|
||||
create_directories(cwd_);
|
||||
cwd_s = cwd_.string();
|
||||
cwd_p = (cwd_s.empty() ? nullptr : cwd_s.c_str());
|
||||
}
|
||||
|
||||
const auto r = ::CreateProcessA(
|
||||
cmd.c_str(), const_cast<char*>(args.c_str()),
|
||||
nullptr, nullptr, FALSE, CREATE_NEW_PROCESS_GROUP,
|
||||
env_.get_pointers(), cwd_p, &si, &pi);
|
||||
|
||||
if (!r)
|
||||
{
|
||||
const auto e = GetLastError();
|
||||
bail_out("failed to start '" + cmd + "'", e);
|
||||
}
|
||||
|
||||
::CloseHandle(pi.hThread);
|
||||
impl_.handle.reset(pi.hProcess);
|
||||
}
|
||||
|
||||
void process::interrupt()
|
||||
{
|
||||
impl_.interrupt = true;
|
||||
}
|
||||
|
||||
void process::join()
|
||||
{
|
||||
if (!impl_.handle)
|
||||
return;
|
||||
|
||||
bool interrupted = false;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
const auto r = WaitForSingleObject(impl_.handle.get(), 100);
|
||||
|
||||
if (r == WAIT_OBJECT_0)
|
||||
{
|
||||
// done
|
||||
GetExitCodeProcess(impl_.handle.get(), &code_);
|
||||
|
||||
if ((flags_ & allow_failure) || impl_.interrupt)
|
||||
break;
|
||||
|
||||
if (code_ != 0)
|
||||
{
|
||||
impl_.handle = {};
|
||||
bail_out(make_name() + " returned " + std::to_string(code_));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (r == WAIT_TIMEOUT)
|
||||
{
|
||||
if (impl_.interrupt && !interrupted)
|
||||
{
|
||||
const auto pid = GetProcessId(impl_.handle.get());
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
error("process id is 0, terminating instead");
|
||||
::TerminateProcess(impl_.handle.get(), 0xffff);
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
debug("sending sigint to " + std::to_string(pid));
|
||||
GenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid);
|
||||
}
|
||||
|
||||
interrupted = true;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto e = GetLastError();
|
||||
impl_.handle = {};
|
||||
bail_out("failed to wait on process", e);
|
||||
}
|
||||
|
||||
impl_.handle = {};
|
||||
}
|
||||
|
||||
int process::exit_code() const
|
||||
{
|
||||
return static_cast<int>(code_);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
+108
@@ -0,0 +1,108 @@
|
||||
#include "utility.h"
|
||||
|
||||
namespace builder
|
||||
{
|
||||
|
||||
class process
|
||||
{
|
||||
public:
|
||||
enum flags_t
|
||||
{
|
||||
noflags = 0x00,
|
||||
stdout_is_verbose = 0x01,
|
||||
allow_failure = 0x02
|
||||
};
|
||||
|
||||
process();
|
||||
~process();
|
||||
|
||||
static process raw(const std::string& cmd);
|
||||
|
||||
static process pipe(const process& p)
|
||||
{
|
||||
return p;
|
||||
}
|
||||
|
||||
template <class... Processes>
|
||||
static process pipe(const process& p1, const process& p2, Processes&&... ps)
|
||||
{
|
||||
auto r = p1;
|
||||
r.pipe_into(p2);
|
||||
pipe(r, std::forward<Processes>(ps)...);
|
||||
return r;
|
||||
}
|
||||
|
||||
process& name(const std::string& name);
|
||||
const std::string& name() const;
|
||||
|
||||
process& binary(const fs::path& p);
|
||||
const fs::path& binary() const;
|
||||
|
||||
process& cwd(const fs::path& p);
|
||||
const fs::path& cwd() const;
|
||||
|
||||
process& flags(flags_t f);
|
||||
flags_t flags() const;
|
||||
|
||||
template <class... Args>
|
||||
process& arg(Args&&... args)
|
||||
{
|
||||
cmd_.arg(std::forward<Args>(args)...);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <template<class, class> class Container, class K, class V, class Alloc>
|
||||
process& args(const Container<std::pair<K, V>, Alloc>& v, cmd::flags f=cmd::noflags)
|
||||
{
|
||||
for (auto&& [name, value] : v)
|
||||
arg(name, value, f);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <class Container>
|
||||
process& args(const Container& v, cmd::flags f=cmd::noflags)
|
||||
{
|
||||
for (auto&& e : v)
|
||||
cmd_.arg(e, f);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
process& env(const builder::env& e);
|
||||
|
||||
void run();
|
||||
void interrupt();
|
||||
void join();
|
||||
|
||||
int exit_code() const;
|
||||
|
||||
private:
|
||||
struct impl
|
||||
{
|
||||
handle_ptr handle;
|
||||
std::atomic<bool> interrupt{false};
|
||||
|
||||
impl() = default;
|
||||
impl(const impl&);
|
||||
impl& operator=(const impl&);
|
||||
};
|
||||
|
||||
std::string name_;
|
||||
fs::path bin_;
|
||||
fs::path cwd_;
|
||||
flags_t flags_;
|
||||
cmd cmd_;
|
||||
builder::env env_;
|
||||
std::string raw_;
|
||||
|
||||
impl impl_;
|
||||
DWORD code_;
|
||||
|
||||
std::string make_name() const;
|
||||
std::string make_cmd() const;
|
||||
void pipe_into(const process& p);
|
||||
void do_run(const std::string& what);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -5,6 +5,7 @@
|
||||
#include "../conf.h"
|
||||
#include "../tools.h"
|
||||
#include "../utility.h"
|
||||
#include "../op.h"
|
||||
|
||||
namespace builder
|
||||
{
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
|
||||
#include "net.h"
|
||||
#include "op.h"
|
||||
#include "process.h"
|
||||
|
||||
namespace builder
|
||||
{
|
||||
|
||||
+9
-14
@@ -3,6 +3,7 @@
|
||||
#include "conf.h"
|
||||
#include "op.h"
|
||||
#include "net.h"
|
||||
#include "process.h"
|
||||
|
||||
namespace builder
|
||||
{
|
||||
@@ -262,9 +263,6 @@ void directory_deleter::cancel()
|
||||
}
|
||||
|
||||
|
||||
static env g_env_x86, g_env_x64;
|
||||
|
||||
|
||||
fs::path find_vcvars()
|
||||
{
|
||||
const std::vector<std::string> editions =
|
||||
@@ -347,20 +345,17 @@ env get_vcvars_env(arch a)
|
||||
return e;
|
||||
}
|
||||
|
||||
void vcvars()
|
||||
|
||||
env env::vs_x86()
|
||||
{
|
||||
g_env_x86 = get_vcvars_env(arch::x86);
|
||||
g_env_x64 = get_vcvars_env(arch::x64);
|
||||
static env e = get_vcvars_env(arch::x86);
|
||||
return e;
|
||||
}
|
||||
|
||||
env env::vs_x64()
|
||||
{
|
||||
return g_env_x64;
|
||||
}
|
||||
|
||||
env env::vs_x86()
|
||||
{
|
||||
return g_env_x86;
|
||||
static env e = get_vcvars_env(arch::x64);
|
||||
return e;
|
||||
}
|
||||
|
||||
env env::vs(arch a)
|
||||
@@ -368,10 +363,10 @@ env env::vs(arch a)
|
||||
switch (a)
|
||||
{
|
||||
case arch::x86:
|
||||
return g_env_x86;
|
||||
return vs_x86();
|
||||
|
||||
case arch::x64:
|
||||
return g_env_x64;
|
||||
return vs_x64();
|
||||
|
||||
case arch::dont_care:
|
||||
return {};
|
||||
|
||||
+1
-1
@@ -157,8 +157,8 @@ public:
|
||||
prepend
|
||||
};
|
||||
|
||||
static env vs_x64();
|
||||
static env vs_x86();
|
||||
static env vs_x64();
|
||||
static env vs(arch a);
|
||||
|
||||
env& append_path(const fs::path& p);
|
||||
|
||||
@@ -85,6 +85,7 @@
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\process.cpp" />
|
||||
<ClCompile Include="..\src\tasks\boost.cpp" />
|
||||
<ClCompile Include="..\src\tasks\bzip2.cpp" />
|
||||
<ClCompile Include="..\src\tasks\fmt.cpp" />
|
||||
@@ -112,6 +113,7 @@
|
||||
<ClInclude Include="..\src\op.h" />
|
||||
<ClInclude Include="..\src\net.h" />
|
||||
<ClInclude Include="..\src\pch.h" />
|
||||
<ClInclude Include="..\src\process.h" />
|
||||
<ClInclude Include="..\src\tasks\task.h" />
|
||||
<ClInclude Include="..\src\tasks\tasks.h" />
|
||||
<ClInclude Include="..\src\tools.h" />
|
||||
|
||||
@@ -87,6 +87,9 @@
|
||||
<ClCompile Include="..\src\tasks\pyqt.cpp">
|
||||
<Filter>src\tasks</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\src\process.cpp">
|
||||
<Filter>src</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\src\pch.h">
|
||||
@@ -113,5 +116,8 @@
|
||||
<ClInclude Include="..\src\tasks\tasks.h">
|
||||
<Filter>src\tasks</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\process.h">
|
||||
<Filter>src</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
Reference in New Issue
Block a user