-
Notifications
You must be signed in to change notification settings - Fork 210
Description
Hi !
First of all, thx for this wonderful work !!!
Now, there are some problems with the environment...
In fact, all the vars are passed without delimitors, soo cmd.exe can only see a big var with all the values (type SET and you'll see).
Agent read a wstring from pipe, and the serialize/unserialize process can enable us to send all the environment vars with '\0' delimitors...
First, we have to modify winpty_start_process
It's responsible to send the "start process" packet to the pipe.
It must not use a wchar_t* (because the putWString of the Buffer Class only send part before the first NULL)...
winpty.h
#include <string>
...
WINPTY_API int winpty_start_process(winpty_t *pc,
const wchar_t *appname,
const wchar_t *cmdline,
const wchar_t *cwd,
std::wstring env);winpty.cc
WINPTY_API int winpty_start_process(winpty_t *pc,
const wchar_t *appname,
const wchar_t *cmdline,
const wchar_t *cwd,
std::wstring env)
{
WriteBuffer packet;
packet.putInt(AgentMsg::StartProcess);
packet.putWString(appname ? appname : L"");
packet.putWString(cmdline ? cmdline : L"");
packet.putWString(cwd ? cwd : L"");
packet.putWString(env);
packet.putWString(getDesktopFullName());
writePacket(pc, packet);
return readInt32(pc);
}Now the pty.cc
It calls winpty_start_process
It must create a std::wstring with all the vars separated by a NULL and finishing by 2*NULL:
static NAN_METHOD(PtyStartProcess) {
NanScope();
if (args.Length() != 5
|| !args[0]->IsNumber() // pid
|| !args[1]->IsString() // file
|| !args[2]->IsString() // cmdline
|| !args[3]->IsArray() // env
|| !args[4]->IsString()) // cwd
{
return NanThrowError(
"Usage: pty.startProcess(pid, file, cmdline, env, cwd)");
}
// Get winpty_t by control pipe handle
int pid = args[0]->Int32Value();
winpty_t *pc = get_pipe_handle(pid);
assert(pc != nullptr);
const wchar_t *file = to_wstring(String::Utf8Value(args[1]->ToString()));
const wchar_t *cmdline = to_wstring(String::Utf8Value(args[2]->ToString()));
const wchar_t *cwd = to_wstring(String::Utf8Value(args[4]->ToString()));
// create environment block
std::wstring env;
const Handle<Array> envValues = Handle<Array>::Cast(args[3]);
uint32_t envValueCount = envValues->Length();
if (envValueCount > 0)
{
for(uint32_t i=0; i<envValueCount; i++)
{
env.append(to_wstring(String::Utf8Value(envValues->Get(i)->ToString())));
env.push_back(L'\0');
}
env.push_back(L'\0');
}
/*
wchar_t *env = NULL;
const Handle<Array> envValues = Handle<Array>::Cast(args[3]);
if(!envValues.IsEmpty()) {
OutputDebugStringW(L"NOT EMPTY");
if (envValues->Length() == 0) OutputDebugStringW(L"-> 0");
if (envValues->Length() == 1) OutputDebugStringW(L"-> 1");
if (envValues->Length() == 2) OutputDebugStringW(L"-> 2");
std::wstringstream envBlock;
for(uint32_t i = 0; i < envValues->Length(); i++) {
std::wstring envValue(to_wstring(String::Utf8Value(envValues->Get(i)->ToString())));
OutputDebugStringW(L"-----");
OutputDebugStringW(envValue.c_str());
envBlock << envValue << L' ';
}
std::wstring output = envBlock.str();
size_t count = output.size();
env = new wchar_t[count + 2];
wcsncpy(env, output.c_str(), count);
wcscat(env, L"\0");
}
*/
// Start new terminal
int result = winpty_start_process(pc, file, cmdline, cwd, env);
//delete env;
assert(0 == result);
NanReturnUndefined();
}I hope this could help other people ;)
PS: sorry for my soooo bad English...