如何在 C# 中通过 lpEnvironment 调用 CreateProcess()

Posted

技术标签:

【中文标题】如何在 C# 中通过 lpEnvironment 调用 CreateProcess()【英文标题】:How to call CreateProcess() in C# passing lpEnvironment 【发布时间】:2014-08-17 20:43:50 【问题描述】:

我将原生 CreateProcess 导入到我的 C# 项目中 用于 ICorDebug 目的http://msdn.microsoft.com/en-us/library/vstudio/ms232508(v=vs.100).aspx

 [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)]
        void CreateProcess([In, MarshalAs(UnmanagedType.LPWStr)] string lpApplicationName, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCommandLine, [In] SECURITY_ATTRIBUTES lpProcessAttributes, [In] SECURITY_ATTRIBUTES lpThreadAttributes, [In] int bInheritHandles, [In] uint dwCreationFlags, [In] IntPtr lpEnvironment, [In, MarshalAs(UnmanagedType.LPWStr)] string lpCurrentDirectory, [In] STARTUPINFO pStartupInfo, [In] PROCESS_INFORMATION pProcessInformation, [In] CorDebugCreateProcessFlags debuggingFlags, [MarshalAs(UnmanagedType.Interface)] out ICorDebugProcess ppProcess);

我称之为试图以这种方式传递 lpEnvironment

            IntPtr intPtrEnv;
            if (variables != string.Empty)
                intPtrEnv = Marshal.StringToHGlobalUni(variables);
            else
                intPtrEnv = new IntPtr(0);

 p_codebugger.CreateProcess(
                                exepath,
                                exepath,
                                null,
                                null,
                                1, // inherit handles
                                (UInt32)CreateProcessFlags.CREATE_NEW_CONSOLE,
                                intPtrEnv,
                                ".",
                                si,
                                pi,
                                CorDebugCreateProcessFlags.DEBUG_NO_SPECIAL_OPTIONS,
                                out proc);

变量字符串包含:

"COR_ENABLE_PROFILING=1\0COR_PROFILER=PROFILER_GUID\0COR_PROFILER_PATH=GetProfilerFullPat\0\0"

我得到一个错误 值超出允许范围

对如何将环境块从 c# 传递到 c++ dll 有任何建议吗?

【问题讨论】:

格式化您的问题可能有助于获得更好的答案... 为当前目录传递 null。为什么要通过两次 exepath? si 和 pi 在哪里初始化?您的环境最后有三个空值,其中一个是隐式的。你只需要两个。 env 字符串的其余部分在哪里。你肯定需要更多的环境变量。 让我这么说吧。当我通过 IntPtr.Zero 而不是 env 字符串时,一切正常。 但是您只是丢弃了所有其余的默认环境。你是故意的吗? 【参考方案1】:

好的,我设法解决了我的问题。 首先我使用 StringBuilder 而不是 IntPtr。 添加字符串"COR_ENABLE_PROFILING=1\0COR_PROFILER=PROFILER_GUID\0COR_PROFILER_PATH=GetProfilerFullPat\0\0" 我只需添加(“COR_ENABLE_PROFILING=1”)和增加 Stringbuilder 长度 + 1 等......; 结尾应该再增加一次 lenght++(这是 ansi 编码); 第二件事是在导入的方法中更改并添加编组 而不是 [In] IntPtr lpEnvironment 添加[In, MarshalAs(UnmanagedType.LPStr)] StringBuilder lpEnvironment

【讨论】:

【参考方案2】:

不需要为此使用 P/Invoke,您可以直接在 C# 代码中使用 .Net Process.Start 方法。

如果您想自定义进程启动、传递环境变量等,请使用采用ProcessStartInfo 对象的重载之一。

【讨论】:

也许,但我正在使用 ICorDebug 接口。为了在进程创建后立即进行这项工作(捕获调试事件),我需要使用 create 方法msdn.microsoft.com/en-US/en-en/library/ms232508(v=vs.110).aspx

以上是关于如何在 C# 中通过 lpEnvironment 调用 CreateProcess()的主要内容,如果未能解决你的问题,请参考以下文章

在 Store C# 中通过哈希查找证书

如何在 C# 中通过电子邮件发送本地链接(共享服务器链接)?

如何从另一个 WinForm 中通过 C# WinForm 查看

在 C# 中通过 Telnet 发送和接收命令

如何从我的 C# 代码中通过自定义 url 方案访问传递到我的应用程序的值?

请问c# 中如何实现在PictureBox中通过鼠标拖拽画出矩形框呢?picturebox中的MouseDown和MouseMove如何使用