C# 在C中使用CreateProcessWithLogonW的帮助#
我试图在Windows XP上执行一个带有asp.net(C#)内参数的控制台应用程序。我尝试过diagnostics.Process,但我就是无法让它工作,所以我切换到CreateProcessWithLogonW。我使用了中的代码示例,但控制台应用程序似乎没有运行,并且CreateProcessWithLogonWAPI调用的返回值为false 我的控制台应用程序语法类似于:“C:\Program Files\business Intelligence\mycommand.exe”arg1 arg2 arg3 arg4,如果我在dos窗口中以交互方式运行它,则运行良好 在C代码中,我在程序名之前和之后添加了双引号。当代码运行时,我注意到任务管理器进程数在我运行它的那一秒没有增加,这告诉我应用程序没有运行。processInfo结构具有所有0 我的问题是: 1-用于“CreateProcessWithLogonW”调用的两个“command”参数是否需要双引号?现在,我把整个命令行放在每个命令行中C# 在C中使用CreateProcessWithLogonW的帮助#,c#,asp.net,winapi,C#,Asp.net,Winapi,我试图在Windows XP上执行一个带有asp.net(C#)内参数的控制台应用程序。我尝试过diagnostics.Process,但我就是无法让它工作,所以我切换到CreateProcessWithLogonW。我使用了中的代码示例,但控制台应用程序似乎没有运行,并且CreateProcessWithLogonWAPI调用的返回值为false 我的控制台应用程序语法类似于:“C:\Program Files\business Intelligence\mycommand.exe”arg1
2-如何捕获标准输出,以便知道发生了什么?pInvoke的一个示例在防御方面是有效的,您能否先使用smth simple(如ping)进行尝试?我已经修改了pInvoke的代码来执行ping 127.0.0.1,请看下面的代码是否适合您。回答你的问题:1-我想没有必要这样做,但会双向工作,2-你可以这样做,但如果应用程序不启动的地方,它不会帮助你 示例代码:
public const UInt32 Infinite = 0xffffffff;
public const Int32 Startf_UseStdHandles = 0x00000100;
public const Int32 StdOutputHandle = -11;
public const Int32 StdErrorHandle = -12;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public struct StartupInfo
{
public int cb;
public String reserved;
public String desktop;
public String title;
public int x;
public int y;
public int xSize;
public int ySize;
public int xCountChars;
public int yCountChars;
public int fillAttribute;
public int flags;
public UInt16 showWindow;
public UInt16 reserved2;
public byte reserved3;
public IntPtr stdInput;
public IntPtr stdOutput;
public IntPtr stdError;
}
public struct ProcessInformation
{
public IntPtr process;
public IntPtr thread;
public int processId;
public int threadId;
}
[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
public static extern bool CreateProcessWithLogonW(
String userName,
String domain,
String password,
UInt32 logonFlags,
String applicationName,
String commandLine,
UInt32 creationFlags,
UInt32 environment,
String currentDirectory,
ref StartupInfo startupInfo,
out ProcessInformation processInformation);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern bool GetExitCodeProcess(IntPtr process, ref UInt32 exitCode);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern UInt32 WaitForSingleObject(IntPtr handle, UInt32 milliseconds);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern IntPtr GetStdHandle(IntPtr handle);
[DllImport("Kernel32.dll", SetLastError = true)]
public static extern bool CloseHandle(IntPtr handle);
private void button1_Click(object sender, RoutedEventArgs e)
{
StartupInfo startupInfo = new StartupInfo();
startupInfo.reserved = null;
startupInfo.flags &= Startf_UseStdHandles;
startupInfo.stdOutput = (IntPtr)StdOutputHandle;
startupInfo.stdError = (IntPtr)StdErrorHandle;
UInt32 exitCode = 123456;
ProcessInformation processInfo = new ProcessInformation();
String command = @"c:\windows\system32\ping.exe 127.0.0.1";
String user = "admin";
String domain = System.Environment.MachineName;
String password = "password";
String currentDirectory = System.IO.Directory.GetCurrentDirectory();
try
{
CreateProcessWithLogonW(
user,
domain,
password,
(UInt32)1,
null,
command,
(UInt32)0,
(UInt32)0,
currentDirectory,
ref startupInfo,
out processInfo);
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
Console.WriteLine("Running ...");
WaitForSingleObject(processInfo.process, Infinite);
GetExitCodeProcess(processInfo.process, ref exitCode);
Console.WriteLine("Exit code: {0}", exitCode);
CloseHandle(processInfo.process);
CloseHandle(processInfo.thread);
}
希望这有帮助,如果进程根本没有运行,您应该会得到一个异常。当你调用它时,你会得到一个异常吗?如果是,是哪个异常?(请将此附加信息添加到您的问题中) 如果你没有得到异常,几乎可以肯定的是,应用程序正在执行,但应用程序内部出现了一些故障——它退出的速度很快,以至于你看不到它在执行。要验证或排除这种可能性,您可以添加一个Thread.Sleep(20000)调用作为mycommand.exe应用程序的第一行,该调用将使该应用程序保持20秒,以便您可以使用任务管理器发现它,并将调试工作从调用者应用程序转移到被调用者应用程序 回答您的问题#1:是的,您需要引号,因为您的EXE路径有空格
对你的#2的回答:是的,你可以这样做,但在回答了第一个更紧迫的问题后,你最好把它分成一个单独的SO问题 这篇文章对我很有用
没有例外。mycommand.exe是第三方工具,因此我无法添加任何内容。如果应用程序正在执行,任务管理器中的计数器应至少增加1,然后下降1。。即使是在一秒钟内。当我启动notepad.exe之类的东西时,代码也会工作。但是,我需要从我的应用程序捕获输出。这可以告诉我应用程序是否工作但遇到错误,甚至“未找到文件”是否有用,这可以告诉我我没有正确构造命令。为了重定向标准输出,您必须设置StartupInfo结构的stdInput、stdOutput、stdError字段。您可以使用reflector检查System.Diagnostics.Process类的StartWithCreateProcess方法,以获取如何执行此操作的示例。简言之,您需要创建管道(CreatePipe api调用),将管道的句柄分配给StartupInfo的stdInput、stdOutput和stdError字段,然后使用FileStreamsI从管道读取\写入\数据,我知道,但这样不会让您在24小时内接受自己的答案,我还有7小时要走。