mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-06 01:50:38 +00:00
Allow specifying environment variable modifications
* This works for local and remote invocations of programs, but is mostly useful on unix systems (Windows programs use env vars less often)
This commit is contained in:
@@ -487,7 +487,7 @@ struct IRemoteServer
|
||||
virtual rdctype::array<DirectoryFile> ListFolder(const char *path) = 0;
|
||||
|
||||
virtual uint32_t ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
|
||||
const CaptureOptions *opts) = 0;
|
||||
void *env, const CaptureOptions *opts) = 0;
|
||||
|
||||
virtual void TakeOwnershipCapture(const char *filename) = 0;
|
||||
virtual rdctype::str CopyCaptureToRemote(const char *filename, float *progress) = 0;
|
||||
@@ -529,7 +529,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_ListFolder(
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
|
||||
RemoteServer_ExecuteAndInject(RemoteServer *remote, const char *app, const char *workingDir,
|
||||
const char *cmdLine, const CaptureOptions *opts);
|
||||
const char *cmdLine, void *env, const CaptureOptions *opts);
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_TakeOwnershipCapture(RemoteServer *remote,
|
||||
const char *filename);
|
||||
@@ -628,7 +628,7 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_StartGlobalHook(const char
|
||||
const char *logfile,
|
||||
const CaptureOptions *opts);
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
|
||||
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
|
||||
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, void *env,
|
||||
const char *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC RENDERDOC_InjectIntoProcess(
|
||||
uint32_t pid, const char *logfile, const CaptureOptions *opts, bool32 waitForExit);
|
||||
@@ -647,3 +647,11 @@ extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetCommitHash();
|
||||
extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name);
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char *name,
|
||||
const char *value);
|
||||
|
||||
extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_MakeEnvironmentModificationList(int numElems);
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetEnvironmentModification(
|
||||
void *mem, int idx, const char *variable, const char *value, EnvironmentModificationType type,
|
||||
EnvironmentSeparator separator);
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeEnvironmentModificationList(void *mem);
|
||||
|
||||
@@ -523,3 +523,18 @@ enum TargetControlMessageType
|
||||
eTargetControlMsg_RegisterAPI,
|
||||
eTargetControlMsg_NewChild,
|
||||
};
|
||||
|
||||
enum EnvironmentModificationType
|
||||
{
|
||||
eEnvMod_Set,
|
||||
eEnvMod_Append,
|
||||
eEnvMod_Prepend,
|
||||
};
|
||||
|
||||
enum EnvironmentSeparator
|
||||
{
|
||||
eEnvSep_Platform,
|
||||
eEnvSep_SemiColon,
|
||||
eEnvSep_Colon,
|
||||
eEnvSep_None,
|
||||
};
|
||||
|
||||
@@ -50,6 +50,22 @@ void Serialiser::Serialise(const char *name, DirectoryFile &el)
|
||||
Serialise("flags", el.flags);
|
||||
}
|
||||
|
||||
template <>
|
||||
string ToStrHelper<false, Process::ModificationType>::Get(const Process::ModificationType &el)
|
||||
{
|
||||
return "<...>";
|
||||
}
|
||||
|
||||
template <>
|
||||
void Serialiser::Serialise(const char *name, Process::EnvironmentModification &el)
|
||||
{
|
||||
ScopedContext scope(this, name, "Process::EnvironmentModification", 0, true);
|
||||
|
||||
Serialise("type", el.type);
|
||||
Serialise("name", el.name);
|
||||
Serialise("value", el.value);
|
||||
}
|
||||
|
||||
enum RemoteServerPacket
|
||||
{
|
||||
eRemoteServer_Noop,
|
||||
@@ -372,18 +388,27 @@ static void ActiveRemoteClientThread(void *data)
|
||||
recvser->Serialise("cmdLine", cmdLine);
|
||||
recvser->Serialise("opts", opts);
|
||||
|
||||
uint64_t envListSize = 0;
|
||||
Process::EnvironmentModification *env = NULL;
|
||||
recvser->Serialise("envListSize", envListSize);
|
||||
|
||||
if(envListSize > 0)
|
||||
recvser->SerialiseComplexArray("env", env, envListSize);
|
||||
|
||||
uint32_t ident = eReplayCreate_NetworkIOFailed;
|
||||
|
||||
if(threadData->allowExecution)
|
||||
{
|
||||
ident = Process::LaunchAndInjectIntoProcess(app.c_str(), workingDir.c_str(),
|
||||
cmdLine.c_str(), "", &opts, false);
|
||||
cmdLine.c_str(), env, "", &opts, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("Requested to execute program - disallowing based on configuration");
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(env);
|
||||
|
||||
sendType = eRemoteServer_ExecuteAndInject;
|
||||
sendSer.Serialise("ident", ident);
|
||||
}
|
||||
@@ -769,7 +794,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
|
||||
uint32_t ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
|
||||
uint32_t ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, void *env,
|
||||
const CaptureOptions *opts)
|
||||
{
|
||||
CaptureOptions capopts = opts ? *opts : CaptureOptions();
|
||||
@@ -778,11 +803,35 @@ public:
|
||||
string workstr = workingDir && workingDir[0] ? workingDir : "";
|
||||
string cmdstr = cmdLine && cmdLine[0] ? cmdLine : "";
|
||||
|
||||
Process::EnvironmentModification *envList = (Process::EnvironmentModification *)env;
|
||||
|
||||
Serialiser sendData("", Serialiser::WRITING, false);
|
||||
sendData.Serialise("app", appstr);
|
||||
sendData.Serialise("workingDir", workstr);
|
||||
sendData.Serialise("cmdLine", cmdstr);
|
||||
sendData.Serialise("opts", capopts);
|
||||
|
||||
uint64_t envListSize = 0;
|
||||
if(envList)
|
||||
{
|
||||
Process::EnvironmentModification *it = envList;
|
||||
for(;;)
|
||||
{
|
||||
if(it->name == "")
|
||||
break;
|
||||
envListSize++;
|
||||
it++;
|
||||
}
|
||||
|
||||
// include terminator
|
||||
envListSize++;
|
||||
}
|
||||
|
||||
sendData.Serialise("envListSize", envListSize);
|
||||
|
||||
if(envListSize > 0)
|
||||
sendData.SerialiseComplexArray("env", envList, envListSize);
|
||||
|
||||
Send(eRemoteServer_ExecuteAndInject, sendData);
|
||||
|
||||
RemoteServerPacket type = eRemoteServer_ExecuteAndInject;
|
||||
@@ -1019,9 +1068,9 @@ RemoteServer_RemoteSupportedReplays(RemoteServer *remote, rdctype::array<rdctype
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
|
||||
RemoteServer_ExecuteAndInject(RemoteServer *remote, const char *app, const char *workingDir,
|
||||
const char *cmdLine, const CaptureOptions *opts)
|
||||
const char *cmdLine, void *env, const CaptureOptions *opts)
|
||||
{
|
||||
return remote->ExecuteAndInject(app, workingDir, cmdLine, opts);
|
||||
return remote->ExecuteAndInject(app, workingDir, cmdLine, env, opts);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RemoteServer_TakeOwnershipCapture(RemoteServer *remote,
|
||||
|
||||
@@ -52,17 +52,17 @@ enum ModificationType
|
||||
eEnvModification_Replace = 0,
|
||||
|
||||
// prepend/append options will replace if there is no existing variable
|
||||
eEnvModification_Append, // append with no separators
|
||||
eEnvModification_AppendColon, // append, separated by colons
|
||||
eEnvModification_AppendSemiColon, // append, separated by semi-colons
|
||||
eEnvModification_AppendPlatform, // append, separated by colons for linux & semi-colons for
|
||||
// windows
|
||||
eEnvModification_AppendSemiColon, // append, separated by semi-colons
|
||||
eEnvModification_AppendColon, // append, separated by colons
|
||||
eEnvModification_Append, // append with no separators
|
||||
|
||||
eEnvModification_Prepend, // prepend with no separators
|
||||
eEnvModification_PrependColon, // prepend, separated by colons
|
||||
eEnvModification_PrependSemiColon, // prepend, separated by semi-colons
|
||||
eEnvModification_PrependPlatform, // prepend, separated by colons for linux & semi-colons for
|
||||
// windows
|
||||
eEnvModification_PrependSemiColon, // prepend, separated by semi-colons
|
||||
eEnvModification_PrependColon, // prepend, separated by colons
|
||||
eEnvModification_Prepend, // prepend with no separators
|
||||
};
|
||||
struct EnvironmentModification
|
||||
{
|
||||
@@ -84,8 +84,8 @@ uint32_t InjectIntoProcess(uint32_t pid, const char *logfile, const CaptureOptio
|
||||
bool waitForExit);
|
||||
uint32_t LaunchProcess(const char *app, const char *workingDir, const char *cmdLine);
|
||||
uint32_t LaunchAndInjectIntoProcess(const char *app, const char *workingDir, const char *cmdLine,
|
||||
const char *logfile, const CaptureOptions *opts,
|
||||
bool waitForExit);
|
||||
EnvironmentModification *env, const char *logfile,
|
||||
const CaptureOptions *opts, bool waitForExit);
|
||||
void *LoadModule(const char *module);
|
||||
void *GetFunctionAddress(void *module, const char *function);
|
||||
uint32_t GetCurrentPID();
|
||||
|
||||
@@ -361,8 +361,9 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c
|
||||
}
|
||||
|
||||
uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
|
||||
const char *cmdLine, const char *logfile,
|
||||
const CaptureOptions *opts, bool waitForExit)
|
||||
const char *cmdLine, EnvironmentModification *envList,
|
||||
const char *logfile, const CaptureOptions *opts,
|
||||
bool waitForExit)
|
||||
{
|
||||
if(app == NULL || app[0] == 0)
|
||||
{
|
||||
@@ -375,6 +376,22 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
|
||||
map<string, string> env = EnvStringToEnvMap((const char **)currentEnvironment);
|
||||
vector<EnvironmentModification> &modifications = GetEnvModifications();
|
||||
|
||||
if(envList)
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
EnvironmentModification e = *envList;
|
||||
e.name = trim(e.name);
|
||||
|
||||
if(e.name == "")
|
||||
break;
|
||||
|
||||
modifications.push_back(e);
|
||||
|
||||
envList++;
|
||||
}
|
||||
}
|
||||
|
||||
if(logfile == NULL)
|
||||
logfile = "";
|
||||
|
||||
|
||||
@@ -171,6 +171,35 @@ extern "C" __declspec(dllexport) void __cdecl RENDERDOC_SetLogFile(const char *l
|
||||
if(log)
|
||||
RenderDoc::Inst().SetLogFile(log);
|
||||
}
|
||||
|
||||
static Process::EnvironmentModification tempEnvMod;
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl RENDERDOC_EnvModName(const char *name)
|
||||
{
|
||||
if(name)
|
||||
tempEnvMod.name = name;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl RENDERDOC_EnvModValue(const char *value)
|
||||
{
|
||||
if(value)
|
||||
tempEnvMod.value = value;
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl RENDERDOC_EnvMod(Process::ModificationType *type)
|
||||
{
|
||||
if(type)
|
||||
{
|
||||
tempEnvMod.type = *type;
|
||||
Process::RegisterEnvironmentModification(tempEnvMod);
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" __declspec(dllexport) void __cdecl RENDERDOC_ApplyEnvMods(void *ignored)
|
||||
{
|
||||
Process::ApplyEnvironmentModification();
|
||||
}
|
||||
|
||||
void InjectDLL(HANDLE hProcess, wstring libName)
|
||||
{
|
||||
wchar_t dllPath[MAX_PATH + 1] = {0};
|
||||
@@ -591,8 +620,9 @@ uint32_t Process::LaunchProcess(const char *app, const char *workingDir, const c
|
||||
}
|
||||
|
||||
uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workingDir,
|
||||
const char *cmdLine, const char *logfile,
|
||||
const CaptureOptions *opts, bool waitForExit)
|
||||
const char *cmdLine, EnvironmentModification *env,
|
||||
const char *logfile, const CaptureOptions *opts,
|
||||
bool waitForExit)
|
||||
{
|
||||
void *func = GetProcAddress(GetModuleHandleA("renderdoc.dll"), "RENDERDOC_SetLogFile");
|
||||
|
||||
@@ -607,18 +637,53 @@ uint32_t Process::LaunchAndInjectIntoProcess(const char *app, const char *workin
|
||||
if(pi.dwProcessId == 0)
|
||||
return 0;
|
||||
|
||||
// don't need it
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
uint32_t ret = InjectIntoProcess(pi.dwProcessId, logfile, opts, false);
|
||||
|
||||
if(ret == 0)
|
||||
{
|
||||
ResumeThread(pi.hThread);
|
||||
CloseHandle(pi.hThread);
|
||||
CloseHandle(pi.hProcess);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(env)
|
||||
{
|
||||
uintptr_t loc = FindRemoteDLL(pi.dwProcessId, L"renderdoc.dll");
|
||||
|
||||
if(loc == 0)
|
||||
{
|
||||
RDCERR("Can't locate renderdoc.dll in remote PID %d", pi.dwProcessId);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
string name = trim(env->name);
|
||||
string value = env->value;
|
||||
ModificationType type = env->type;
|
||||
|
||||
if(name == "")
|
||||
break;
|
||||
|
||||
InjectFunctionCall(pi.hProcess, loc, "RENDERDOC_EnvModName", (void *)name.c_str(),
|
||||
name.size() + 1);
|
||||
InjectFunctionCall(pi.hProcess, loc, "RENDERDOC_EnvModValue", (void *)value.c_str(),
|
||||
value.size() + 1);
|
||||
InjectFunctionCall(pi.hProcess, loc, "RENDERDOC_EnvMod", &type, sizeof(type));
|
||||
|
||||
env++;
|
||||
}
|
||||
|
||||
// parameter is unused
|
||||
InjectFunctionCall(pi.hProcess, loc, "RENDERDOC_ApplyEnvMods", env,
|
||||
sizeof(EnvironmentModification));
|
||||
}
|
||||
}
|
||||
|
||||
// done with it
|
||||
CloseHandle(pi.hProcess);
|
||||
|
||||
ResumeThread(pi.hThread);
|
||||
|
||||
if(waitForExit)
|
||||
|
||||
@@ -252,6 +252,33 @@ extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetConfigSetting(const char
|
||||
RenderDoc::Inst().SetConfigSetting(name, value);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void *RENDERDOC_CC RENDERDOC_MakeEnvironmentModificationList(int numElems)
|
||||
{
|
||||
return new Process::EnvironmentModification[numElems + 1]; // last one is a terminator
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_SetEnvironmentModification(
|
||||
void *mem, int idx, const char *variable, const char *value, EnvironmentModificationType type,
|
||||
EnvironmentSeparator separator)
|
||||
{
|
||||
Process::EnvironmentModification *mods = (Process::EnvironmentModification *)mem;
|
||||
|
||||
Process::ModificationType modType = Process::eEnvModification_Replace;
|
||||
|
||||
if(type == eEnvMod_Append)
|
||||
modType = Process::ModificationType(Process::eEnvModification_AppendPlatform + (int)separator);
|
||||
if(type == eEnvMod_Prepend)
|
||||
modType = Process::ModificationType(Process::eEnvModification_PrependPlatform + (int)separator);
|
||||
|
||||
mods[idx] = Process::EnvironmentModification(modType, variable, value);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_FreeEnvironmentModificationList(void *mem)
|
||||
{
|
||||
Process::EnvironmentModification *mods = (Process::EnvironmentModification *)mem;
|
||||
delete[] mods;
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API void RENDERDOC_CC RENDERDOC_LogText(const char *text)
|
||||
{
|
||||
RDCLOG("%s", text);
|
||||
@@ -336,10 +363,11 @@ RENDERDOC_CreateReplayRenderer(const char *logfile, float *progress, ReplayRende
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API uint32_t RENDERDOC_CC
|
||||
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine,
|
||||
RENDERDOC_ExecuteAndInject(const char *app, const char *workingDir, const char *cmdLine, void *env,
|
||||
const char *logfile, const CaptureOptions *opts, bool32 waitForExit)
|
||||
{
|
||||
return Process::LaunchAndInjectIntoProcess(app, workingDir, cmdLine, logfile, opts,
|
||||
return Process::LaunchAndInjectIntoProcess(app, workingDir, cmdLine,
|
||||
(Process::EnvironmentModification *)env, logfile, opts,
|
||||
waitForExit != 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -303,7 +303,7 @@ struct CaptureCommand : public Command
|
||||
|
||||
uint32_t ident = RENDERDOC_ExecuteAndInject(
|
||||
executable.c_str(), workingDir.empty() ? "" : workingDir.c_str(),
|
||||
cmdLine.empty() ? "" : cmdLine.c_str(), logFile.empty() ? "" : logFile.c_str(), &opts,
|
||||
cmdLine.empty() ? "" : cmdLine.c_str(), NULL, logFile.empty() ? "" : logFile.c_str(), &opts,
|
||||
parser.exist("wait-for-exit"));
|
||||
|
||||
if(ident == 0)
|
||||
|
||||
@@ -98,15 +98,15 @@ namespace renderdocui.Code
|
||||
while (m_Thread.IsAlive && !Running) ;
|
||||
}
|
||||
|
||||
public UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, string logfile, CaptureOptions opts)
|
||||
public UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, EnvironmentModification[] env, string logfile, CaptureOptions opts)
|
||||
{
|
||||
if (m_Remote == null)
|
||||
{
|
||||
return StaticExports.ExecuteAndInject(app, workingDir, cmdLine, logfile, opts);
|
||||
return StaticExports.ExecuteAndInject(app, workingDir, cmdLine, env, logfile, opts);
|
||||
}
|
||||
else
|
||||
{
|
||||
return m_Remote.ExecuteAndInject(app, workingDir, cmdLine, opts);
|
||||
return m_Remote.ExecuteAndInject(app, workingDir, cmdLine, env, opts);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -536,6 +536,21 @@ namespace renderdoc
|
||||
NewChild,
|
||||
};
|
||||
|
||||
public enum EnvironmentModificationType
|
||||
{
|
||||
Set,
|
||||
Append,
|
||||
Prepend,
|
||||
};
|
||||
|
||||
public enum EnvironmentSeparator
|
||||
{
|
||||
Platform,
|
||||
SemiColon,
|
||||
Colon,
|
||||
None,
|
||||
};
|
||||
|
||||
public static class EnumString
|
||||
{
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
@@ -865,5 +880,19 @@ namespace renderdoc
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
|
||||
public static string Str(this EnvironmentSeparator sep)
|
||||
{
|
||||
switch (sep)
|
||||
{
|
||||
case EnvironmentSeparator.Platform: return "Platform style";
|
||||
case EnvironmentSeparator.SemiColon: return "Semi-colon (;)";
|
||||
case EnvironmentSeparator.Colon: return "Colon (:)";
|
||||
case EnvironmentSeparator.None: return "No Separator";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,45 @@ using System.Collections.Generic;
|
||||
|
||||
namespace renderdoc
|
||||
{
|
||||
// this isn't an Interop struct, since it needs to be passed C# -> C++ and
|
||||
// it's not POD which we don't support. It's here just as a utility container
|
||||
public class EnvironmentModification
|
||||
{
|
||||
public string variable;
|
||||
public string value;
|
||||
|
||||
public EnvironmentModificationType type;
|
||||
public EnvironmentSeparator separator;
|
||||
|
||||
public string GetTypeString()
|
||||
{
|
||||
string ret;
|
||||
|
||||
if (type == EnvironmentModificationType.Append)
|
||||
ret = String.Format("Append, {0}", separator.Str());
|
||||
else if (type == EnvironmentModificationType.Prepend)
|
||||
ret = String.Format("Prepend, {0}", separator.Str());
|
||||
else
|
||||
ret = "Set";
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public string GetDescription()
|
||||
{
|
||||
string ret;
|
||||
|
||||
if (type == EnvironmentModificationType.Append)
|
||||
ret = String.Format("Append {0} with {1} using {2}", variable, value, separator.Str());
|
||||
else if (type == EnvironmentModificationType.Prepend)
|
||||
ret = String.Format("Prepend {0} with {1} using {2}", variable, value, separator.Str());
|
||||
else
|
||||
ret = String.Format("Set {0} to {1}", variable, value);
|
||||
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public class TargetControlMessage
|
||||
{
|
||||
@@ -864,7 +903,7 @@ namespace renderdoc
|
||||
private static extern void RemoteServer_ListFolder(IntPtr real, IntPtr path, IntPtr outlist);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern UInt32 RemoteServer_ExecuteAndInject(IntPtr real, IntPtr app, IntPtr workingDir, IntPtr cmdLine, CaptureOptions opts);
|
||||
private static extern UInt32 RemoteServer_ExecuteAndInject(IntPtr real, IntPtr app, IntPtr workingDir, IntPtr cmdLine, IntPtr env, CaptureOptions opts);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RemoteServer_TakeOwnershipCapture(IntPtr real, IntPtr filename);
|
||||
@@ -879,6 +918,17 @@ namespace renderdoc
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RemoteServer_CloseCapture(IntPtr real, IntPtr rendPtr);
|
||||
|
||||
// static exports for lists of environment modifications
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr RENDERDOC_MakeEnvironmentModificationList(int numElems);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RENDERDOC_SetEnvironmentModification(IntPtr mem, int idx, IntPtr variable, IntPtr value,
|
||||
EnvironmentModificationType type, EnvironmentSeparator separator);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RENDERDOC_FreeEnvironmentModificationList(IntPtr mem);
|
||||
|
||||
private IntPtr m_Real = IntPtr.Zero;
|
||||
|
||||
public RemoteServer(IntPtr real) { m_Real = real; }
|
||||
@@ -966,13 +1016,28 @@ namespace renderdoc
|
||||
return ret;
|
||||
}
|
||||
|
||||
public UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, CaptureOptions opts)
|
||||
public UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts)
|
||||
{
|
||||
IntPtr app_mem = CustomMarshal.MakeUTF8String(app);
|
||||
IntPtr workingDir_mem = CustomMarshal.MakeUTF8String(workingDir);
|
||||
IntPtr cmdLine_mem = CustomMarshal.MakeUTF8String(cmdLine);
|
||||
|
||||
UInt32 ret = RemoteServer_ExecuteAndInject(m_Real, app_mem, workingDir_mem, cmdLine_mem, opts);
|
||||
IntPtr env_mem = RENDERDOC_MakeEnvironmentModificationList(env.Length);
|
||||
|
||||
for (int i = 0; i < env.Length; i++)
|
||||
{
|
||||
IntPtr var_mem = CustomMarshal.MakeUTF8String(env[i].variable);
|
||||
IntPtr val_mem = CustomMarshal.MakeUTF8String(env[i].value);
|
||||
|
||||
RENDERDOC_SetEnvironmentModification(env_mem, i, var_mem, val_mem, env[i].type, env[i].separator);
|
||||
|
||||
CustomMarshal.Free(var_mem);
|
||||
CustomMarshal.Free(val_mem);
|
||||
}
|
||||
|
||||
UInt32 ret = RemoteServer_ExecuteAndInject(m_Real, app_mem, workingDir_mem, cmdLine_mem, env_mem, opts);
|
||||
|
||||
RENDERDOC_FreeEnvironmentModificationList(env_mem);
|
||||
|
||||
CustomMarshal.Free(app_mem);
|
||||
CustomMarshal.Free(workingDir_mem);
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace renderdoc
|
||||
private static extern void RENDERDOC_StartGlobalHook(IntPtr pathmatch, IntPtr logfile, CaptureOptions opts);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern UInt32 RENDERDOC_ExecuteAndInject(IntPtr app, IntPtr workingDir, IntPtr cmdLine,
|
||||
private static extern UInt32 RENDERDOC_ExecuteAndInject(IntPtr app, IntPtr workingDir, IntPtr cmdLine, IntPtr env,
|
||||
IntPtr logfile, CaptureOptions opts, bool waitForExit);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
@@ -100,6 +100,16 @@ namespace renderdoc
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern bool RENDERDOC_GetThumbnail(IntPtr filename, byte[] outmem, ref UInt32 len);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern IntPtr RENDERDOC_MakeEnvironmentModificationList(int numElems);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RENDERDOC_SetEnvironmentModification(IntPtr mem, int idx, IntPtr variable, IntPtr value,
|
||||
EnvironmentModificationType type, EnvironmentSeparator separator);
|
||||
|
||||
[DllImport("renderdoc.dll", CharSet = CharSet.Unicode, CallingConvention = CallingConvention.Cdecl)]
|
||||
private static extern void RENDERDOC_FreeEnvironmentModificationList(IntPtr mem);
|
||||
|
||||
public static bool SupportLocalReplay(string logfile, out string driverName)
|
||||
{
|
||||
IntPtr mem = CustomMarshal.Alloc(typeof(templated_array));
|
||||
@@ -145,14 +155,29 @@ namespace renderdoc
|
||||
CustomMarshal.Free(pathmatch_mem);
|
||||
}
|
||||
|
||||
public static UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, string logfile, CaptureOptions opts)
|
||||
public static UInt32 ExecuteAndInject(string app, string workingDir, string cmdLine, EnvironmentModification[] env, string logfile, CaptureOptions opts)
|
||||
{
|
||||
IntPtr app_mem = CustomMarshal.MakeUTF8String(app);
|
||||
IntPtr workingDir_mem = CustomMarshal.MakeUTF8String(workingDir);
|
||||
IntPtr cmdLine_mem = CustomMarshal.MakeUTF8String(cmdLine);
|
||||
IntPtr logfile_mem = CustomMarshal.MakeUTF8String(logfile);
|
||||
|
||||
UInt32 ret = RENDERDOC_ExecuteAndInject(app_mem, workingDir_mem, cmdLine_mem, logfile_mem, opts, false);
|
||||
IntPtr env_mem = RENDERDOC_MakeEnvironmentModificationList(env.Length);
|
||||
|
||||
for(int i=0; i < env.Length; i++)
|
||||
{
|
||||
IntPtr var_mem = CustomMarshal.MakeUTF8String(env[i].variable);
|
||||
IntPtr val_mem = CustomMarshal.MakeUTF8String(env[i].value);
|
||||
|
||||
RENDERDOC_SetEnvironmentModification(env_mem, i, var_mem, val_mem, env[i].type, env[i].separator);
|
||||
|
||||
CustomMarshal.Free(var_mem);
|
||||
CustomMarshal.Free(val_mem);
|
||||
}
|
||||
|
||||
UInt32 ret = RENDERDOC_ExecuteAndInject(app_mem, workingDir_mem, cmdLine_mem, env_mem, logfile_mem, opts, false);
|
||||
|
||||
RENDERDOC_FreeEnvironmentModificationList(env_mem);
|
||||
|
||||
CustomMarshal.Free(app_mem);
|
||||
CustomMarshal.Free(workingDir_mem);
|
||||
|
||||
+84
-40
@@ -34,6 +34,8 @@
|
||||
System.Windows.Forms.ColumnHeader pid;
|
||||
System.Windows.Forms.ColumnHeader name;
|
||||
System.Windows.Forms.Label label5;
|
||||
System.Windows.Forms.Label label3;
|
||||
System.Windows.Forms.Label label6;
|
||||
this.globalLabel = new System.Windows.Forms.Label();
|
||||
this.actionsGroup = new System.Windows.Forms.GroupBox();
|
||||
this.actionsFlow = new System.Windows.Forms.FlowLayoutPanel();
|
||||
@@ -68,7 +70,6 @@
|
||||
this.saveDialog = new System.Windows.Forms.SaveFileDialog();
|
||||
this.loadDialog = new System.Windows.Forms.OpenFileDialog();
|
||||
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.cmdline = new System.Windows.Forms.TextBox();
|
||||
this.workDirBrowse = new System.Windows.Forms.Button();
|
||||
this.workDirPath = new System.Windows.Forms.TextBox();
|
||||
@@ -76,6 +77,8 @@
|
||||
this.exePath = new System.Windows.Forms.TextBox();
|
||||
this.pidRefresh = new System.Windows.Forms.Button();
|
||||
this.pidList = new System.Windows.Forms.ListView();
|
||||
this.environmentDisplay = new System.Windows.Forms.TextBox();
|
||||
this.setEnv = new System.Windows.Forms.Button();
|
||||
this.tableLayoutPanel2 = new System.Windows.Forms.TableLayoutPanel();
|
||||
this.programGroup = new System.Windows.Forms.GroupBox();
|
||||
this.processGroup = new System.Windows.Forms.GroupBox();
|
||||
@@ -85,6 +88,8 @@
|
||||
pid = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
name = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
|
||||
label5 = new System.Windows.Forms.Label();
|
||||
label3 = new System.Windows.Forms.Label();
|
||||
label6 = new System.Windows.Forms.Label();
|
||||
this.actionsGroup.SuspendLayout();
|
||||
this.actionsFlow.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.queuedCapFrame)).BeginInit();
|
||||
@@ -135,10 +140,30 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
label5.Location = new System.Drawing.Point(9, 16);
|
||||
label5.Name = "label5";
|
||||
label5.Size = new System.Drawing.Size(475, 23);
|
||||
label5.Size = new System.Drawing.Size(478, 23);
|
||||
label5.TabIndex = 3;
|
||||
label5.Text = "NOTE: Injecting only works when the process has not used the target API";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
label3.AutoSize = true;
|
||||
label3.Location = new System.Drawing.Point(6, 74);
|
||||
label3.Name = "label3";
|
||||
label3.Size = new System.Drawing.Size(126, 13);
|
||||
label3.TabIndex = 7;
|
||||
label3.Text = "Command-line Arguments";
|
||||
this.toolTip.SetToolTip(label3, "The command-line that will be passed to the executable on launch");
|
||||
//
|
||||
// label6
|
||||
//
|
||||
label6.AutoSize = true;
|
||||
label6.Location = new System.Drawing.Point(6, 103);
|
||||
label6.Name = "label6";
|
||||
label6.Size = new System.Drawing.Size(112, 13);
|
||||
label6.TabIndex = 8;
|
||||
label6.Text = "Environment Variables";
|
||||
this.toolTip.SetToolTip(label6, "The command-line that will be passed to the executable on launch");
|
||||
//
|
||||
// globalLabel
|
||||
//
|
||||
this.globalLabel.AutoSize = true;
|
||||
@@ -158,10 +183,10 @@
|
||||
this.actionsGroup.AutoSize = true;
|
||||
this.actionsGroup.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.actionsGroup.Controls.Add(this.actionsFlow);
|
||||
this.actionsGroup.Location = new System.Drawing.Point(10, 558);
|
||||
this.actionsGroup.Location = new System.Drawing.Point(10, 584);
|
||||
this.actionsGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.actionsGroup.Name = "actionsGroup";
|
||||
this.actionsGroup.Size = new System.Drawing.Size(197, 65);
|
||||
this.actionsGroup.Size = new System.Drawing.Size(200, 65);
|
||||
this.actionsGroup.TabIndex = 11;
|
||||
this.actionsGroup.TabStop = false;
|
||||
this.actionsGroup.Text = "Actions";
|
||||
@@ -218,10 +243,10 @@
|
||||
this.globalGroup.AutoSize = true;
|
||||
this.globalGroup.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.globalGroup.Controls.Add(this.globalFlow);
|
||||
this.globalGroup.Location = new System.Drawing.Point(10, 643);
|
||||
this.globalGroup.Location = new System.Drawing.Point(10, 669);
|
||||
this.globalGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.globalGroup.Name = "globalGroup";
|
||||
this.globalGroup.Size = new System.Drawing.Size(197, 80);
|
||||
this.globalGroup.Size = new System.Drawing.Size(200, 80);
|
||||
this.globalGroup.TabIndex = 12;
|
||||
this.globalGroup.TabStop = false;
|
||||
this.globalGroup.Text = "Global Process Hook";
|
||||
@@ -257,10 +282,10 @@
|
||||
this.capOptsGroup.AutoSize = true;
|
||||
this.capOptsGroup.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
|
||||
this.capOptsGroup.Controls.Add(this.capOptsFlow);
|
||||
this.capOptsGroup.Location = new System.Drawing.Point(10, 425);
|
||||
this.capOptsGroup.Location = new System.Drawing.Point(10, 451);
|
||||
this.capOptsGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.capOptsGroup.Name = "capOptsGroup";
|
||||
this.capOptsGroup.Size = new System.Drawing.Size(197, 113);
|
||||
this.capOptsGroup.Size = new System.Drawing.Size(200, 113);
|
||||
this.capOptsGroup.TabIndex = 4;
|
||||
this.capOptsGroup.TabStop = false;
|
||||
this.capOptsGroup.Text = "Capture Options";
|
||||
@@ -369,8 +394,8 @@
|
||||
this.APIValidation.Size = new System.Drawing.Size(130, 20);
|
||||
this.APIValidation.TabIndex = 12;
|
||||
this.APIValidation.Text = "Enable API validation";
|
||||
this.toolTip.SetToolTip(this.APIValidation, "Initialise the graphics API with built-in validation enabled - allows capturing and reading of errors and war" +
|
||||
"nings generated by the API's own debugging system");
|
||||
this.toolTip.SetToolTip(this.APIValidation, "Initialise the graphics API with built-in validation enabled - allows capturing a" +
|
||||
"nd reading of errors and warnings generated by the API\'s own debugging system");
|
||||
this.APIValidation.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// HookIntoChildren
|
||||
@@ -443,9 +468,9 @@
|
||||
this.panel2.Controls.Add(this.save);
|
||||
this.panel2.Controls.Add(this.close);
|
||||
this.panel2.Controls.Add(this.capture);
|
||||
this.panel2.Location = new System.Drawing.Point(3, 736);
|
||||
this.panel2.Location = new System.Drawing.Point(3, 762);
|
||||
this.panel2.Name = "panel2";
|
||||
this.panel2.Size = new System.Drawing.Size(211, 26);
|
||||
this.panel2.Size = new System.Drawing.Size(214, 26);
|
||||
this.panel2.TabIndex = 8;
|
||||
//
|
||||
// load
|
||||
@@ -475,7 +500,7 @@
|
||||
// close
|
||||
//
|
||||
this.close.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.close.Location = new System.Drawing.Point(164, 3);
|
||||
this.close.Location = new System.Drawing.Point(167, 3);
|
||||
this.close.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.close.Name = "close";
|
||||
this.close.Size = new System.Drawing.Size(41, 23);
|
||||
@@ -487,7 +512,7 @@
|
||||
// capture
|
||||
//
|
||||
this.capture.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.capture.Location = new System.Drawing.Point(107, 3);
|
||||
this.capture.Location = new System.Drawing.Point(110, 3);
|
||||
this.capture.Margin = new System.Windows.Forms.Padding(0);
|
||||
this.capture.Name = "capture";
|
||||
this.capture.Size = new System.Drawing.Size(52, 23);
|
||||
@@ -522,30 +547,20 @@
|
||||
this.loadDialog.FileName = "Settings.cap";
|
||||
this.loadDialog.Filter = "Capture settings|*.cap";
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(6, 74);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(126, 13);
|
||||
this.label3.TabIndex = 7;
|
||||
this.label3.Text = "Command-line Arguments";
|
||||
this.toolTip.SetToolTip(this.label3, "The command-line that will be passed to the executable on launch");
|
||||
//
|
||||
// cmdline
|
||||
//
|
||||
this.cmdline.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.cmdline.Location = new System.Drawing.Point(137, 71);
|
||||
this.cmdline.Name = "cmdline";
|
||||
this.cmdline.Size = new System.Drawing.Size(54, 20);
|
||||
this.cmdline.Size = new System.Drawing.Size(57, 20);
|
||||
this.cmdline.TabIndex = 4;
|
||||
this.toolTip.SetToolTip(this.cmdline, "The command-line that will be passed to the executable on launch");
|
||||
//
|
||||
// workDirBrowse
|
||||
//
|
||||
this.workDirBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.workDirBrowse.Location = new System.Drawing.Point(167, 45);
|
||||
this.workDirBrowse.Location = new System.Drawing.Point(170, 45);
|
||||
this.workDirBrowse.Name = "workDirBrowse";
|
||||
this.workDirBrowse.Size = new System.Drawing.Size(24, 20);
|
||||
this.workDirBrowse.TabIndex = 3;
|
||||
@@ -560,7 +575,7 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.workDirPath.Location = new System.Drawing.Point(137, 45);
|
||||
this.workDirPath.Name = "workDirPath";
|
||||
this.workDirPath.Size = new System.Drawing.Size(24, 20);
|
||||
this.workDirPath.Size = new System.Drawing.Size(27, 20);
|
||||
this.workDirPath.TabIndex = 2;
|
||||
this.toolTip.SetToolTip(this.workDirPath, "The working directory the executable will be launched in");
|
||||
this.workDirPath.TextChanged += new System.EventHandler(this.workDirPath_TextChanged);
|
||||
@@ -570,7 +585,7 @@
|
||||
// exeBrowse
|
||||
//
|
||||
this.exeBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.exeBrowse.Location = new System.Drawing.Point(167, 18);
|
||||
this.exeBrowse.Location = new System.Drawing.Point(170, 18);
|
||||
this.exeBrowse.Name = "exeBrowse";
|
||||
this.exeBrowse.Size = new System.Drawing.Size(24, 20);
|
||||
this.exeBrowse.TabIndex = 1;
|
||||
@@ -586,7 +601,7 @@
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.exePath.Location = new System.Drawing.Point(137, 19);
|
||||
this.exePath.Name = "exePath";
|
||||
this.exePath.Size = new System.Drawing.Size(24, 20);
|
||||
this.exePath.Size = new System.Drawing.Size(27, 20);
|
||||
this.exePath.TabIndex = 0;
|
||||
this.toolTip.SetToolTip(this.exePath, "The executable file to launch");
|
||||
this.exePath.TextChanged += new System.EventHandler(this.exePath_TextChanged);
|
||||
@@ -596,7 +611,7 @@
|
||||
// pidRefresh
|
||||
//
|
||||
this.pidRefresh.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.pidRefresh.Location = new System.Drawing.Point(412, 180);
|
||||
this.pidRefresh.Location = new System.Drawing.Point(415, 180);
|
||||
this.pidRefresh.Name = "pidRefresh";
|
||||
this.pidRefresh.Size = new System.Drawing.Size(75, 23);
|
||||
this.pidRefresh.TabIndex = 6;
|
||||
@@ -619,12 +634,37 @@
|
||||
this.pidList.Location = new System.Drawing.Point(6, 42);
|
||||
this.pidList.MultiSelect = false;
|
||||
this.pidList.Name = "pidList";
|
||||
this.pidList.Size = new System.Drawing.Size(185, 129);
|
||||
this.pidList.Size = new System.Drawing.Size(188, 129);
|
||||
this.pidList.TabIndex = 5;
|
||||
this.toolTip.SetToolTip(this.pidList, "Select the process to inject into - must not yet have utilised the target API");
|
||||
this.pidList.UseCompatibleStateImageBehavior = false;
|
||||
this.pidList.View = System.Windows.Forms.View.Details;
|
||||
//
|
||||
// environmentDisplay
|
||||
//
|
||||
this.environmentDisplay.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.environmentDisplay.BackColor = System.Drawing.SystemColors.Control;
|
||||
this.environmentDisplay.Cursor = System.Windows.Forms.Cursors.IBeam;
|
||||
this.environmentDisplay.Location = new System.Drawing.Point(137, 97);
|
||||
this.environmentDisplay.Name = "environmentDisplay";
|
||||
this.environmentDisplay.ReadOnly = true;
|
||||
this.environmentDisplay.Size = new System.Drawing.Size(27, 20);
|
||||
this.environmentDisplay.TabIndex = 9;
|
||||
this.toolTip.SetToolTip(this.environmentDisplay, "The working directory the executable will be launched in");
|
||||
//
|
||||
// setEnv
|
||||
//
|
||||
this.setEnv.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.setEnv.Location = new System.Drawing.Point(170, 96);
|
||||
this.setEnv.Name = "setEnv";
|
||||
this.setEnv.Size = new System.Drawing.Size(24, 20);
|
||||
this.setEnv.TabIndex = 10;
|
||||
this.setEnv.Text = "...";
|
||||
this.toolTip.SetToolTip(this.setEnv, "Browse for a working directory");
|
||||
this.setEnv.UseVisualStyleBackColor = true;
|
||||
this.setEnv.Click += new System.EventHandler(this.setEnv_Click);
|
||||
//
|
||||
// tableLayoutPanel2
|
||||
//
|
||||
this.tableLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
@@ -650,14 +690,17 @@
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(217, 765);
|
||||
this.tableLayoutPanel2.Size = new System.Drawing.Size(220, 791);
|
||||
this.tableLayoutPanel2.TabIndex = 8;
|
||||
//
|
||||
// programGroup
|
||||
//
|
||||
this.programGroup.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.programGroup.Controls.Add(this.label3);
|
||||
this.programGroup.Controls.Add(this.setEnv);
|
||||
this.programGroup.Controls.Add(this.environmentDisplay);
|
||||
this.programGroup.Controls.Add(label6);
|
||||
this.programGroup.Controls.Add(label3);
|
||||
this.programGroup.Controls.Add(label2);
|
||||
this.programGroup.Controls.Add(label1);
|
||||
this.programGroup.Controls.Add(this.cmdline);
|
||||
@@ -668,7 +711,7 @@
|
||||
this.programGroup.Location = new System.Drawing.Point(10, 10);
|
||||
this.programGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.programGroup.Name = "programGroup";
|
||||
this.programGroup.Size = new System.Drawing.Size(197, 108);
|
||||
this.programGroup.Size = new System.Drawing.Size(200, 134);
|
||||
this.programGroup.TabIndex = 10;
|
||||
this.programGroup.TabStop = false;
|
||||
this.programGroup.Text = "Program";
|
||||
@@ -680,10 +723,10 @@
|
||||
this.processGroup.Controls.Add(label5);
|
||||
this.processGroup.Controls.Add(this.pidList);
|
||||
this.processGroup.Controls.Add(this.pidRefresh);
|
||||
this.processGroup.Location = new System.Drawing.Point(10, 138);
|
||||
this.processGroup.Location = new System.Drawing.Point(10, 164);
|
||||
this.processGroup.Margin = new System.Windows.Forms.Padding(10);
|
||||
this.processGroup.Name = "processGroup";
|
||||
this.processGroup.Size = new System.Drawing.Size(197, 209);
|
||||
this.processGroup.Size = new System.Drawing.Size(200, 209);
|
||||
this.processGroup.TabIndex = 9;
|
||||
this.processGroup.TabStop = false;
|
||||
this.processGroup.Text = "Process";
|
||||
@@ -697,10 +740,10 @@
|
||||
this.vulkanLayerWarn.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
|
||||
this.vulkanLayerWarn.Image = global::renderdocui.Properties.Resources.information;
|
||||
this.vulkanLayerWarn.ImageAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
this.vulkanLayerWarn.Location = new System.Drawing.Point(3, 367);
|
||||
this.vulkanLayerWarn.Location = new System.Drawing.Point(3, 393);
|
||||
this.vulkanLayerWarn.Margin = new System.Windows.Forms.Padding(3, 10, 3, 10);
|
||||
this.vulkanLayerWarn.Name = "vulkanLayerWarn";
|
||||
this.vulkanLayerWarn.Size = new System.Drawing.Size(211, 38);
|
||||
this.vulkanLayerWarn.Size = new System.Drawing.Size(214, 38);
|
||||
this.vulkanLayerWarn.TabIndex = 13;
|
||||
this.vulkanLayerWarn.Text = "Warning: Vulkan capture is not configured. Click here to set up Vulkan capture.";
|
||||
this.vulkanLayerWarn.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
|
||||
@@ -714,7 +757,7 @@
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.AutoScroll = true;
|
||||
this.AutoScrollMinSize = new System.Drawing.Size(215, 0);
|
||||
this.ClientSize = new System.Drawing.Size(214, 738);
|
||||
this.ClientSize = new System.Drawing.Size(230, 754);
|
||||
this.Controls.Add(this.tableLayoutPanel2);
|
||||
this.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.Name = "CaptureDialog";
|
||||
@@ -774,7 +817,6 @@
|
||||
private System.Windows.Forms.FlowLayoutPanel capOptsFlow;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel2;
|
||||
private System.Windows.Forms.GroupBox programGroup;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.TextBox cmdline;
|
||||
private System.Windows.Forms.Button workDirBrowse;
|
||||
private System.Windows.Forms.TextBox workDirPath;
|
||||
@@ -794,6 +836,8 @@
|
||||
private System.Windows.Forms.GroupBox globalGroup;
|
||||
private System.Windows.Forms.Label globalLabel;
|
||||
private System.Windows.Forms.Button vulkanLayerWarn;
|
||||
private System.Windows.Forms.Button setEnv;
|
||||
private System.Windows.Forms.TextBox environmentDisplay;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -53,8 +53,11 @@ namespace renderdocui.Windows.Dialogs
|
||||
public string Executable = "";
|
||||
public string WorkingDir = "";
|
||||
public string CmdLine = "";
|
||||
public EnvironmentModification[] Environment = new EnvironmentModification[0];
|
||||
}
|
||||
|
||||
private EnvironmentModification[] m_EnvModifications = new EnvironmentModification[0];
|
||||
|
||||
private bool workDirHint = true;
|
||||
|
||||
private Core m_Core;
|
||||
@@ -69,6 +72,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
workDirPath.Text = settings.WorkingDir;
|
||||
cmdline.Text = settings.CmdLine;
|
||||
|
||||
SetEnvironmentModifications(settings.Environment);
|
||||
|
||||
workDirPath_Leave(null, null);
|
||||
|
||||
AllowFullscreen.Checked = settings.Options.AllowFullscreen;
|
||||
@@ -109,6 +114,8 @@ namespace renderdocui.Windows.Dialogs
|
||||
ret.WorkingDir = RealWorkDir;
|
||||
ret.CmdLine = cmdline.Text;
|
||||
|
||||
ret.Environment = m_EnvModifications;
|
||||
|
||||
ret.Options.AllowFullscreen = AllowFullscreen.Checked;
|
||||
ret.Options.AllowVSync = AllowVSync.Checked;
|
||||
ret.Options.HookIntoChildren = HookIntoChildren.Checked;
|
||||
@@ -195,7 +202,7 @@ namespace renderdocui.Windows.Dialogs
|
||||
|
||||
#region Callbacks
|
||||
|
||||
public delegate LiveCapture OnCaptureMethod(string exe, string workingDir, string cmdLine, CaptureOptions opts);
|
||||
public delegate LiveCapture OnCaptureMethod(string exe, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts);
|
||||
public delegate LiveCapture OnInjectMethod(UInt32 PID, string name, CaptureOptions opts);
|
||||
|
||||
private OnCaptureMethod m_CaptureCallback = null;
|
||||
@@ -285,7 +292,7 @@ namespace renderdocui.Windows.Dialogs
|
||||
|
||||
string cmdLine = cmdline.Text;
|
||||
|
||||
var live = m_CaptureCallback(exe, workingDir, cmdLine, GetSettings().Options);
|
||||
var live = m_CaptureCallback(exe, workingDir, cmdLine, GetSettings().Environment, GetSettings().Options);
|
||||
|
||||
if (queueFrameCap.Checked && live != null)
|
||||
live.QueueCapture((int)queuedCapFrame.Value);
|
||||
@@ -452,6 +459,36 @@ namespace renderdocui.Windows.Dialogs
|
||||
workDirPath.ForeColor = SystemColors.WindowText;
|
||||
}
|
||||
|
||||
private void setEnv_Click(object sender, EventArgs e)
|
||||
{
|
||||
EnvironmentEditor envEditor = new EnvironmentEditor();
|
||||
|
||||
foreach (var mod in m_EnvModifications)
|
||||
envEditor.AddModification(mod, true);
|
||||
|
||||
DialogResult res = envEditor.ShowDialog(this);
|
||||
|
||||
if (res == DialogResult.OK)
|
||||
SetEnvironmentModifications(envEditor.Modifications);
|
||||
}
|
||||
|
||||
private void SetEnvironmentModifications(EnvironmentModification[] modifications)
|
||||
{
|
||||
m_EnvModifications = modifications;
|
||||
|
||||
string envModText = "";
|
||||
|
||||
foreach (var mod in modifications)
|
||||
{
|
||||
if (envModText != "")
|
||||
envModText += ", ";
|
||||
|
||||
envModText += mod.GetDescription();
|
||||
}
|
||||
|
||||
environmentDisplay.Text = envModText;
|
||||
}
|
||||
|
||||
private void workDirPath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if(Directory.Exists(workDirPath.Text))
|
||||
|
||||
@@ -135,6 +135,12 @@
|
||||
<metadata name="label5.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label3.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label6.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="exeBrowser.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||
<value>17, 17</value>
|
||||
</metadata>
|
||||
|
||||
@@ -0,0 +1,337 @@
|
||||
namespace renderdocui.Windows.Dialogs
|
||||
{
|
||||
partial class EnvironmentEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Required designer variable.
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// Clean up any resources being used.
|
||||
/// </summary>
|
||||
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows Form Designer generated code
|
||||
|
||||
/// <summary>
|
||||
/// Required method for Designer support - do not modify
|
||||
/// the contents of this method with the code editor.
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
TreelistView.TreeListColumn treeListColumn1 = new TreelistView.TreeListColumn("Name", "Name");
|
||||
TreelistView.TreeListColumn treeListColumn2 = new TreelistView.TreeListColumn("Modification", "Modification");
|
||||
TreelistView.TreeListColumn treeListColumn3 = new TreelistView.TreeListColumn("Value", "Value");
|
||||
System.Windows.Forms.GroupBox groupBox2;
|
||||
System.Windows.Forms.Label label2;
|
||||
System.Windows.Forms.Label label1;
|
||||
System.Windows.Forms.GroupBox groupBox1;
|
||||
System.Windows.Forms.Button ok;
|
||||
System.Windows.Forms.Button cancel;
|
||||
this.variables = new TreelistView.TreeListView();
|
||||
this.varValue = new System.Windows.Forms.TextBox();
|
||||
this.varName = new System.Windows.Forms.TextBox();
|
||||
this.pendSeparator = new System.Windows.Forms.ComboBox();
|
||||
this.prependType = new System.Windows.Forms.RadioButton();
|
||||
this.appendType = new System.Windows.Forms.RadioButton();
|
||||
this.setType = new System.Windows.Forms.RadioButton();
|
||||
this.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
this.addUpdate = new System.Windows.Forms.Button();
|
||||
this.delete = new System.Windows.Forms.Button();
|
||||
this.flowLayoutPanel2 = new System.Windows.Forms.FlowLayoutPanel();
|
||||
tableLayoutPanel1 = new System.Windows.Forms.TableLayoutPanel();
|
||||
groupBox2 = new System.Windows.Forms.GroupBox();
|
||||
label2 = new System.Windows.Forms.Label();
|
||||
label1 = new System.Windows.Forms.Label();
|
||||
groupBox1 = new System.Windows.Forms.GroupBox();
|
||||
ok = new System.Windows.Forms.Button();
|
||||
cancel = new System.Windows.Forms.Button();
|
||||
tableLayoutPanel1.SuspendLayout();
|
||||
((System.ComponentModel.ISupportInitialize)(this.variables)).BeginInit();
|
||||
groupBox2.SuspendLayout();
|
||||
groupBox1.SuspendLayout();
|
||||
this.flowLayoutPanel1.SuspendLayout();
|
||||
this.flowLayoutPanel2.SuspendLayout();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// tableLayoutPanel1
|
||||
//
|
||||
tableLayoutPanel1.ColumnCount = 2;
|
||||
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
|
||||
tableLayoutPanel1.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute, 20F));
|
||||
tableLayoutPanel1.Controls.Add(this.variables, 0, 0);
|
||||
tableLayoutPanel1.Controls.Add(groupBox2, 0, 1);
|
||||
tableLayoutPanel1.Controls.Add(groupBox1, 1, 1);
|
||||
tableLayoutPanel1.Controls.Add(this.flowLayoutPanel1, 1, 2);
|
||||
tableLayoutPanel1.Controls.Add(this.flowLayoutPanel2, 1, 3);
|
||||
tableLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
tableLayoutPanel1.Location = new System.Drawing.Point(0, 0);
|
||||
tableLayoutPanel1.Name = "tableLayoutPanel1";
|
||||
tableLayoutPanel1.RowCount = 4;
|
||||
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
|
||||
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel1.RowStyles.Add(new System.Windows.Forms.RowStyle());
|
||||
tableLayoutPanel1.Size = new System.Drawing.Size(673, 474);
|
||||
tableLayoutPanel1.TabIndex = 2;
|
||||
//
|
||||
// variables
|
||||
//
|
||||
treeListColumn1.AutoSizeMinSize = 0;
|
||||
treeListColumn1.Width = 160;
|
||||
treeListColumn2.AutoSizeMinSize = 0;
|
||||
treeListColumn2.Width = 170;
|
||||
treeListColumn3.AutoSize = true;
|
||||
treeListColumn3.AutoSizeMinSize = 100;
|
||||
treeListColumn3.Width = 50;
|
||||
this.variables.Columns.AddRange(new TreelistView.TreeListColumn[] {
|
||||
treeListColumn1,
|
||||
treeListColumn2,
|
||||
treeListColumn3});
|
||||
this.variables.ColumnsOptions.LeftMargin = 0;
|
||||
tableLayoutPanel1.SetColumnSpan(this.variables, 2);
|
||||
this.variables.Cursor = System.Windows.Forms.Cursors.Arrow;
|
||||
this.variables.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||
this.variables.Font = new System.Drawing.Font("Consolas", 9F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
|
||||
this.variables.Location = new System.Drawing.Point(3, 3);
|
||||
this.variables.Name = "variables";
|
||||
this.variables.RowOptions.ShowHeader = false;
|
||||
this.variables.Size = new System.Drawing.Size(667, 257);
|
||||
this.variables.TabIndex = 11;
|
||||
this.variables.Text = "treeListView1";
|
||||
this.variables.ViewOptions.HoverHandTreeColumn = false;
|
||||
this.variables.ViewOptions.PadForPlusMinus = false;
|
||||
this.variables.ViewOptions.ShowLine = false;
|
||||
this.variables.ViewOptions.ShowPlusMinus = false;
|
||||
this.variables.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.variables_AfterSelect);
|
||||
//
|
||||
// groupBox2
|
||||
//
|
||||
groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
groupBox2.Controls.Add(label2);
|
||||
groupBox2.Controls.Add(this.varValue);
|
||||
groupBox2.Controls.Add(label1);
|
||||
groupBox2.Controls.Add(this.varName);
|
||||
groupBox2.Location = new System.Drawing.Point(3, 266);
|
||||
groupBox2.Name = "groupBox2";
|
||||
groupBox2.Size = new System.Drawing.Size(489, 122);
|
||||
groupBox2.TabIndex = 4;
|
||||
groupBox2.TabStop = false;
|
||||
groupBox2.Text = "Environment Variable";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
label2.AutoSize = true;
|
||||
label2.Location = new System.Drawing.Point(9, 68);
|
||||
label2.Name = "label2";
|
||||
label2.Size = new System.Drawing.Size(34, 13);
|
||||
label2.TabIndex = 3;
|
||||
label2.Text = "Value";
|
||||
//
|
||||
// varValue
|
||||
//
|
||||
this.varValue.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.varValue.Location = new System.Drawing.Point(9, 84);
|
||||
this.varValue.Name = "varValue";
|
||||
this.varValue.Size = new System.Drawing.Size(473, 20);
|
||||
this.varValue.TabIndex = 2;
|
||||
this.varValue.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.varField_KeyPress);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
label1.AutoSize = true;
|
||||
label1.Location = new System.Drawing.Point(9, 16);
|
||||
label1.Name = "label1";
|
||||
label1.Size = new System.Drawing.Size(35, 13);
|
||||
label1.TabIndex = 1;
|
||||
label1.Text = "Name";
|
||||
//
|
||||
// varName
|
||||
//
|
||||
this.varName.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.varName.AutoCompleteMode = System.Windows.Forms.AutoCompleteMode.Suggest;
|
||||
this.varName.AutoCompleteSource = System.Windows.Forms.AutoCompleteSource.CustomSource;
|
||||
this.varName.Location = new System.Drawing.Point(9, 32);
|
||||
this.varName.Name = "varName";
|
||||
this.varName.Size = new System.Drawing.Size(473, 20);
|
||||
this.varName.TabIndex = 1;
|
||||
this.varName.TextChanged += new System.EventHandler(this.varName_TextChanged);
|
||||
this.varName.KeyPress += new System.Windows.Forms.KeyPressEventHandler(this.varField_KeyPress);
|
||||
//
|
||||
// groupBox1
|
||||
//
|
||||
groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
groupBox1.Controls.Add(this.pendSeparator);
|
||||
groupBox1.Controls.Add(this.prependType);
|
||||
groupBox1.Controls.Add(this.appendType);
|
||||
groupBox1.Controls.Add(this.setType);
|
||||
groupBox1.Location = new System.Drawing.Point(498, 266);
|
||||
groupBox1.Name = "groupBox1";
|
||||
groupBox1.Size = new System.Drawing.Size(172, 122);
|
||||
groupBox1.TabIndex = 2;
|
||||
groupBox1.TabStop = false;
|
||||
groupBox1.Text = "Modification type";
|
||||
//
|
||||
// pendSeparator
|
||||
//
|
||||
this.pendSeparator.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
this.pendSeparator.FormattingEnabled = true;
|
||||
this.pendSeparator.Location = new System.Drawing.Point(7, 92);
|
||||
this.pendSeparator.Name = "pendSeparator";
|
||||
this.pendSeparator.Size = new System.Drawing.Size(121, 21);
|
||||
this.pendSeparator.TabIndex = 6;
|
||||
//
|
||||
// prependType
|
||||
//
|
||||
this.prependType.AutoSize = true;
|
||||
this.prependType.Location = new System.Drawing.Point(7, 68);
|
||||
this.prependType.Name = "prependType";
|
||||
this.prependType.Size = new System.Drawing.Size(95, 17);
|
||||
this.prependType.TabIndex = 5;
|
||||
this.prependType.TabStop = true;
|
||||
this.prependType.Text = "Prepend Value";
|
||||
this.prependType.UseVisualStyleBackColor = true;
|
||||
this.prependType.CheckedChanged += new System.EventHandler(this.modification_CheckedChanged);
|
||||
//
|
||||
// appendType
|
||||
//
|
||||
this.appendType.AutoSize = true;
|
||||
this.appendType.Location = new System.Drawing.Point(7, 44);
|
||||
this.appendType.Name = "appendType";
|
||||
this.appendType.Size = new System.Drawing.Size(92, 17);
|
||||
this.appendType.TabIndex = 4;
|
||||
this.appendType.TabStop = true;
|
||||
this.appendType.Text = "Append Value";
|
||||
this.appendType.UseVisualStyleBackColor = true;
|
||||
this.appendType.CheckedChanged += new System.EventHandler(this.modification_CheckedChanged);
|
||||
//
|
||||
// setType
|
||||
//
|
||||
this.setType.AutoSize = true;
|
||||
this.setType.Location = new System.Drawing.Point(7, 20);
|
||||
this.setType.Name = "setType";
|
||||
this.setType.Size = new System.Drawing.Size(71, 17);
|
||||
this.setType.TabIndex = 3;
|
||||
this.setType.TabStop = true;
|
||||
this.setType.Text = "Set Value";
|
||||
this.setType.UseVisualStyleBackColor = true;
|
||||
this.setType.CheckedChanged += new System.EventHandler(this.modification_CheckedChanged);
|
||||
//
|
||||
// flowLayoutPanel1
|
||||
//
|
||||
this.flowLayoutPanel1.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowLayoutPanel1.Controls.Add(this.addUpdate);
|
||||
this.flowLayoutPanel1.Controls.Add(this.delete);
|
||||
this.flowLayoutPanel1.Location = new System.Drawing.Point(498, 391);
|
||||
this.flowLayoutPanel1.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
|
||||
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
|
||||
this.flowLayoutPanel1.Size = new System.Drawing.Size(172, 28);
|
||||
this.flowLayoutPanel1.TabIndex = 9;
|
||||
//
|
||||
// addUpdate
|
||||
//
|
||||
this.addUpdate.Location = new System.Drawing.Point(3, 3);
|
||||
this.addUpdate.Name = "addUpdate";
|
||||
this.addUpdate.Size = new System.Drawing.Size(80, 23);
|
||||
this.addUpdate.TabIndex = 7;
|
||||
this.addUpdate.Text = "Add / Update";
|
||||
this.addUpdate.UseVisualStyleBackColor = true;
|
||||
this.addUpdate.Click += new System.EventHandler(this.addUpdate_Click);
|
||||
//
|
||||
// delete
|
||||
//
|
||||
this.delete.Location = new System.Drawing.Point(89, 3);
|
||||
this.delete.Name = "delete";
|
||||
this.delete.Size = new System.Drawing.Size(80, 23);
|
||||
this.delete.TabIndex = 8;
|
||||
this.delete.Text = "Delete";
|
||||
this.delete.UseVisualStyleBackColor = true;
|
||||
this.delete.Click += new System.EventHandler(this.delete_Click);
|
||||
//
|
||||
// flowLayoutPanel2
|
||||
//
|
||||
this.flowLayoutPanel2.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.flowLayoutPanel2.Controls.Add(ok);
|
||||
this.flowLayoutPanel2.Controls.Add(cancel);
|
||||
this.flowLayoutPanel2.Location = new System.Drawing.Point(498, 445);
|
||||
this.flowLayoutPanel2.Margin = new System.Windows.Forms.Padding(3, 26, 3, 3);
|
||||
this.flowLayoutPanel2.Name = "flowLayoutPanel2";
|
||||
this.flowLayoutPanel2.Size = new System.Drawing.Size(172, 26);
|
||||
this.flowLayoutPanel2.TabIndex = 10;
|
||||
//
|
||||
// ok
|
||||
//
|
||||
ok.DialogResult = System.Windows.Forms.DialogResult.OK;
|
||||
ok.Location = new System.Drawing.Point(3, 3);
|
||||
ok.Name = "ok";
|
||||
ok.Size = new System.Drawing.Size(80, 23);
|
||||
ok.TabIndex = 9;
|
||||
ok.Text = "OK";
|
||||
ok.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// cancel
|
||||
//
|
||||
cancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
|
||||
cancel.Location = new System.Drawing.Point(89, 3);
|
||||
cancel.Name = "cancel";
|
||||
cancel.Size = new System.Drawing.Size(80, 23);
|
||||
cancel.TabIndex = 10;
|
||||
cancel.Text = "Cancel";
|
||||
cancel.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// EnvironmentEditor
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(673, 474);
|
||||
this.Controls.Add(tableLayoutPanel1);
|
||||
this.MaximizeBox = false;
|
||||
this.MinimizeBox = false;
|
||||
this.Name = "EnvironmentEditor";
|
||||
this.ShowIcon = false;
|
||||
this.ShowInTaskbar = false;
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||
this.Text = "Capture Environment Editor";
|
||||
this.Load += new System.EventHandler(this.EnvironmentEditor_Load);
|
||||
tableLayoutPanel1.ResumeLayout(false);
|
||||
((System.ComponentModel.ISupportInitialize)(this.variables)).EndInit();
|
||||
groupBox2.ResumeLayout(false);
|
||||
groupBox2.PerformLayout();
|
||||
groupBox1.ResumeLayout(false);
|
||||
groupBox1.PerformLayout();
|
||||
this.flowLayoutPanel1.ResumeLayout(false);
|
||||
this.flowLayoutPanel2.ResumeLayout(false);
|
||||
this.ResumeLayout(false);
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox varValue;
|
||||
private System.Windows.Forms.TextBox varName;
|
||||
private System.Windows.Forms.Button addUpdate;
|
||||
private System.Windows.Forms.ComboBox pendSeparator;
|
||||
private System.Windows.Forms.RadioButton prependType;
|
||||
private System.Windows.Forms.RadioButton appendType;
|
||||
private System.Windows.Forms.RadioButton setType;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
|
||||
private System.Windows.Forms.Button delete;
|
||||
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel2;
|
||||
private TreelistView.TreeListView variables;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows.Forms;
|
||||
using renderdoc;
|
||||
|
||||
namespace renderdocui.Windows.Dialogs
|
||||
{
|
||||
public partial class EnvironmentEditor : Form
|
||||
{
|
||||
public EnvironmentEditor()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
pendSeparator.Items.AddRange(new object[] {
|
||||
EnvironmentSeparator.Platform.Str(),
|
||||
EnvironmentSeparator.SemiColon.Str(),
|
||||
EnvironmentSeparator.Colon.Str(),
|
||||
EnvironmentSeparator.None.Str()
|
||||
});
|
||||
}
|
||||
|
||||
private void EnvironmentEditor_Load(object sender, EventArgs e)
|
||||
{
|
||||
pendSeparator.SelectedIndex = (int)EnvironmentSeparator.Platform;
|
||||
|
||||
setType.Checked = true;
|
||||
varName.Select();
|
||||
varName_TextChanged(varName, new EventArgs());
|
||||
|
||||
variables.NodesSelection.Clear();
|
||||
}
|
||||
|
||||
private int ExistingIndex()
|
||||
{
|
||||
int i=0;
|
||||
foreach (var n in variables.Nodes)
|
||||
{
|
||||
if ((string)n[0] == varName.Text)
|
||||
return i;
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void modification_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
pendSeparator.Enabled = !setType.Checked;
|
||||
}
|
||||
|
||||
private void varName_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
int idx = ExistingIndex();
|
||||
|
||||
if (idx >= 0)
|
||||
{
|
||||
addUpdate.Text = "Update";
|
||||
delete.Enabled = true;
|
||||
variables.NodesSelection.Clear();
|
||||
variables.NodesSelection.Add(variables.Nodes[idx]);
|
||||
}
|
||||
else
|
||||
{
|
||||
addUpdate.Text = "Add";
|
||||
delete.Enabled = false;
|
||||
|
||||
addUpdate.Enabled = (varName.Text.Trim() != "");
|
||||
}
|
||||
}
|
||||
|
||||
private void varField_KeyPress(object sender, KeyPressEventArgs e)
|
||||
{
|
||||
if (e.KeyChar == '\n' || e.KeyChar == '\r')
|
||||
{
|
||||
addUpdate.PerformClick();
|
||||
}
|
||||
}
|
||||
|
||||
private void variables_AfterSelect(object sender, TreeViewEventArgs e)
|
||||
{
|
||||
if (variables.SelectedNode != null)
|
||||
{
|
||||
EnvironmentModification mod = variables.SelectedNode.Tag as EnvironmentModification;
|
||||
|
||||
if (mod != null)
|
||||
{
|
||||
varName.Text = mod.variable;
|
||||
varValue.Text = mod.value;
|
||||
pendSeparator.SelectedIndex = (int)mod.separator;
|
||||
|
||||
if (mod.type == EnvironmentModificationType.Set)
|
||||
setType.PerformClick();
|
||||
else if (mod.type == EnvironmentModificationType.Append)
|
||||
appendType.PerformClick();
|
||||
else if (mod.type == EnvironmentModificationType.Prepend)
|
||||
prependType.PerformClick();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void delete_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (variables.SelectedNode != null)
|
||||
{
|
||||
variables.BeginUpdate();
|
||||
variables.Nodes.Remove(variables.SelectedNode);
|
||||
variables.EndUpdate();
|
||||
variables.NodesSelection.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
private void addUpdate_Click(object sender, EventArgs e)
|
||||
{
|
||||
EnvironmentModification mod = new EnvironmentModification();
|
||||
mod.variable = varName.Text;
|
||||
mod.value = varValue.Text;
|
||||
mod.separator = (EnvironmentSeparator)pendSeparator.SelectedIndex;
|
||||
|
||||
if (appendType.Checked)
|
||||
mod.type = EnvironmentModificationType.Append;
|
||||
else if (prependType.Checked)
|
||||
mod.type = EnvironmentModificationType.Prepend;
|
||||
else
|
||||
mod.type = EnvironmentModificationType.Set;
|
||||
|
||||
AddModification(mod, false);
|
||||
}
|
||||
|
||||
public void AddModification(EnvironmentModification mod, bool silent)
|
||||
{
|
||||
TreelistView.Node node = new TreelistView.Node();
|
||||
int idx = ExistingIndex();
|
||||
if (idx >= 0)
|
||||
node = variables.Nodes[idx];
|
||||
|
||||
if (mod.variable.Trim() == "")
|
||||
{
|
||||
if(!silent)
|
||||
MessageBox.Show("Environment variable cannot be just whitespace", "Invalid variable", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
variables.BeginUpdate();
|
||||
|
||||
if (idx < 0)
|
||||
variables.Nodes.Add(node);
|
||||
|
||||
node.SetData(new object[] { mod.variable, mod.GetTypeString(), mod.value });
|
||||
node.Tag = mod;
|
||||
|
||||
variables.EndUpdate();
|
||||
|
||||
variables.NodesSelection.Clear();
|
||||
variables.NodesSelection.Add(node);
|
||||
|
||||
varName.AutoCompleteCustomSource.Clear();
|
||||
for (int i = 0; i < variables.Nodes.Count; i++)
|
||||
varName.AutoCompleteCustomSource.Add((string)variables.Nodes[i][0]);
|
||||
}
|
||||
|
||||
public EnvironmentModification[] Modifications
|
||||
{
|
||||
get
|
||||
{
|
||||
EnvironmentModification[] ret = new EnvironmentModification[variables.Nodes.Count];
|
||||
for(int i=0; i < variables.Nodes.Count; i++)
|
||||
ret[i] = variables.Nodes[i].Tag as EnvironmentModification;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="tableLayoutPanel1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="groupBox2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label2.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="label1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="groupBox1.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="ok.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
<metadata name="cancel.GenerateMember" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>False</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -833,14 +833,14 @@ namespace renderdocui.Windows
|
||||
return "";
|
||||
}
|
||||
|
||||
private LiveCapture OnCaptureTrigger(string exe, string workingDir, string cmdLine, CaptureOptions opts)
|
||||
private LiveCapture OnCaptureTrigger(string exe, string workingDir, string cmdLine, EnvironmentModification[] env, CaptureOptions opts)
|
||||
{
|
||||
if (!PromptCloseLog())
|
||||
return null;
|
||||
|
||||
string logfile = m_Core.TempLogFilename(Path.GetFileNameWithoutExtension(exe));
|
||||
|
||||
UInt32 ret = m_Core.Renderer.ExecuteAndInject(exe, workingDir, cmdLine, logfile, opts);
|
||||
UInt32 ret = m_Core.Renderer.ExecuteAndInject(exe, workingDir, cmdLine, env, logfile, opts);
|
||||
|
||||
if (ret == 0)
|
||||
{
|
||||
|
||||
@@ -223,6 +223,12 @@
|
||||
<Compile Include="Windows\Dialogs\ColumnSelector.Designer.cs">
|
||||
<DependentUpon>ColumnSelector.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Windows\Dialogs\EnvironmentEditor.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Windows\Dialogs\EnvironmentEditor.Designer.cs">
|
||||
<DependentUpon>EnvironmentEditor.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Windows\Dialogs\FindAllDialog.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
@@ -400,6 +406,9 @@
|
||||
<EmbeddedResource Include="Windows\Dialogs\ColumnSelector.resx">
|
||||
<DependentUpon>ColumnSelector.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Windows\Dialogs\EnvironmentEditor.resx">
|
||||
<DependentUpon>EnvironmentEditor.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Windows\Dialogs\FindAllDialog.resx">
|
||||
<DependentUpon>FindAllDialog.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
||||
Reference in New Issue
Block a user