我有以下代码:
info = new System.Diagnostics.ProcessStartInfo("TheProgram.exe", String.Join(" ", args));
info.CreateNoWindow = true;
info.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
info.RedirectStandardOutput = true;
info.UseShellExecute = false;
System.Diagnostics.Process p = System.Diagnostics.Process.Start(info);
p.WaitForExit();
Console.WriteLine(p.StandardOutput.ReadToEnd()); //need the StandardOutput contents
Run Code Online (Sandbox Code Playgroud)
我知道我开始的进程的输出大约是7MB.在Windows控制台中运行它可以正常工作.不幸的是,这会在WaitForExit上无限期挂起.另请注意,对于较小的输出(例如3KB),此代码不会挂起.
ProcessStartInfo中的内部StandardOutput是否可能无法缓冲7MB?如果是这样,我该怎么做呢?如果没有,我做错了什么?
我正在尝试在C#中执行批处理文件,但我没有运气好.
我在互联网上找到了多个例子,但它对我不起作用.
public void ExecuteCommand(string command)
{
int ExitCode;
ProcessStartInfo ProcessInfo;
Process Process;
ProcessInfo = new ProcessStartInfo("cmd.exe", "/c " + command);
ProcessInfo.CreateNoWindow = true;
ProcessInfo.UseShellExecute = false;
Process = Process.Start(ProcessInfo);
Process.WaitForExit();
ExitCode = Process.ExitCode;
Process.Close();
MessageBox.Show("ExitCode: " + ExitCode.ToString(), "ExecuteCommand");
}
Run Code Online (Sandbox Code Playgroud)
命令字符串包含批处理文件的名称(存储在其中system32
)以及它应该操作的一些文件.(例如:) txtmanipulator file1.txt file2.txt file3.txt
.当我手动执行批处理文件时,它可以正常工作.
执行代码时,它给了我一个 **ExitCode: 1** (Catch all for general errors)
我究竟做错了什么?
当我开始一个新的过程时,如果我使用它会有什么不同
WindowStyle = Hidden
Run Code Online (Sandbox Code Playgroud)
或者
CreateNoWindow = true
Run Code Online (Sandbox Code Playgroud)
ProcessStartInfo
班级的财产?
什么是环境变量概念?
在C#程序中,我需要调用可执行文件.可执行文件将调用驻留在同一文件夹中的其他可执行文件.可执行文件依赖于两个环境变量"PATH"和"RAYPATH"来正确设置.我尝试了以下两件事:
当我运行该进程时,系统找不到可执行文件("executionable1").我试图将StartInfo.FileName设置为"executeable1"的完整路径 - 但是找不到在"executeable1"中调用表单的EXE文件...
我该如何处理?
string pathvar = System.Environment.GetEnvironmentVariable("PATH");
System.Environment.SetEnvironmentVariable("PATH", pathvar + @";C:\UD_\bin\DAYSIM\bin_windows\;C:\UD_\bin\Radiance\bin\;C:\UD_\bin\DAYSIM;");
System.Environment.SetEnvironmentVariable("RAYPATH", @"C:\UD_\bin\DAYSIM\lib\;C:\UD_\bin\Radiance\lib\");
System.Diagnostics.Process p = new System.Diagnostics.Process();
p.StartInfo.WorkingDirectory = @"C:\UD_\bin\DAYSIM\bin_windows";
//string pathvar = p.StartInfo.EnvironmentVariables["PATH"];
//p.StartInfo.EnvironmentVariables["PATH"] = pathvar + @";C:\UD_\bin\DAYSIM\bin_windows\;C:\UD_\bin\Radiance\bin\;C:\UD_\bin\DAYSIM;";
//p.StartInfo.EnvironmentVariables["RAYPATH"] = @"C:\UD_\bin\DAYSIM\lib\;C:\UD_\bin\Radiance\lib\";
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.CreateNoWindow = true;
p.StartInfo.FileName = "executeable1";
p.StartInfo.Arguments = arg1 + " " + arg2;
p.Start();
p.WaitForExit();
Run Code Online (Sandbox Code Playgroud) 从未以管理员身份运行的应用程序,我有以下代码:
ProcessStartInfo proc = new ProcessStartInfo();
proc.WindowStyle = ProcessWindowStyle.Normal;
proc.FileName = myExePath;
proc.CreateNoWindow = false;
proc.UseShellExecute = false;
proc.Verb = "runas";
Run Code Online (Sandbox Code Playgroud)
当我调用Process.Start(proc)时,我没有弹出请求以管理员身份运行的权限,并且exe不以管理员身份运行.
我尝试将app.manifest添加到myExePath中找到的可执行文件,并将requestedExecutionLevel更新为
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Run Code Online (Sandbox Code Playgroud)
使用更新的app.manifest,在Process.Start(proc)调用中,我得到一个异常,"请求的操作需要提升."
为什么.Verb操作没有设置管理员权限?
我正在测试Windows Server 2008 R2 Standard.
我在svn.exe周围写了一个快速而又脏的包装器来检索一些内容并用它做一些事情,但对于某些输入它偶尔会重复挂起并且无法完成.例如,一个调用是svn列表:
svn list "http://myserver:84/svn/Documents/Instruments/" --xml --no-auth-cache --username myuser --password mypassword
Run Code Online (Sandbox Code Playgroud)
当我从命令shell执行此操作时,此命令行运行正常,但它在我的应用程序中挂起.运行它的我的c#代码是:
string cmd = "svn.exe";
string arguments = "list \"http://myserver:84/svn/Documents/Instruments/\" --xml --no-auth-cache --username myuser --password mypassword";
int ms = 5000;
ProcessStartInfo psi = new ProcessStartInfo(cmd);
psi.Arguments = arguments;
psi.RedirectStandardOutput = true;
psi.WindowStyle = ProcessWindowStyle.Normal;
psi.UseShellExecute = false;
Process proc = Process.Start(psi);
StreamReader output = new StreamReader(proc.StandardOutput.BaseStream, Encoding.UTF8);
proc.WaitForExit(ms);
if (proc.HasExited)
{
return output.ReadToEnd();
}
Run Code Online (Sandbox Code Playgroud)
这需要整整5000毫秒,永远不会完成.延长时间并没有帮助.在一个单独的命令提示符中,它立即运行,所以我很确定它与等待时间不足无关.但是,对于其他输入,这似乎工作正常.
我也尝试在这里运行一个单独的cmd.exe(其中exe是svn.exe,而args是原始的arg字符串),但仍然发生了挂起:
string cmd = "cmd";
string arguments = "/S /C \"" + exe + " …
Run Code Online (Sandbox Code Playgroud) 我试图以编程方式执行msbuild并且无法执行以下命令:
string command = string.Format(@"C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe ""{0}\{1}.csproj""", _args.ProjectPath, _args.ProjectName);
Run Code Online (Sandbox Code Playgroud)
字符串呈现为:
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe "C:\...\TestResults\Foo 2011-08-31 16_29_40\Out\Foo\solutionName\projectName\projectName.csproj"
Run Code Online (Sandbox Code Playgroud)
然后我使用新的ProcessStartInfo(命令).问题似乎是Foo和2011之间的空间.我得到以下输出:
MSBUILD : error MSB1008: Only one project can be specified.
Switch: 16_29_40\Out\Foo\solutionName\projectName\projectName.csproj
Run Code Online (Sandbox Code Playgroud)
如何将项目文件传递给msbuild?
我想启动一个具有提升权限但具有隐藏窗口的子进程(实际上是相同的控制台应用程序).
我做下一个:
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
UseShellExecute = true, // !
Verb = "runas",
};
var process = new Process
{
StartInfo = info
};
process.Start();
Run Code Online (Sandbox Code Playgroud)
这工作:
var identity = new WindowsPrincipal(WindowsIdentity.GetCurrent());
identity.IsInRole(WindowsBuiltInRole.Administrator); // returns true
Run Code Online (Sandbox Code Playgroud)
但是UseShellExecute = true
创建了一个新窗口,我也无法重定向输出.
所以我下次做的时候:
var info = new ProcessStartInfo(Assembly.GetEntryAssembly().Location)
{
RedirectStandardError = true,
RedirectStandardOutput = true,
UseShellExecute = false, // !
Verb = "runas"
};
var process = new Process
{
EnableRaisingEvents = true,
StartInfo = info
};
DataReceivedEventHandler actionWrite …
Run Code Online (Sandbox Code Playgroud) 例如,我已经成功开发并部署了ClickOnce应用程序,该应用程序注册了相关的文件扩展名*.abc
.当我单击命名文件x.abc
或x.abc
从命令提示符处键入时,ClickOnce应用程序启动,我可以通过专用API检索文件.我还可以使用以下代码以编程方式启动应用程序:
System.Diagnostics.Process.Start ("x.abc");
Run Code Online (Sandbox Code Playgroud)
我的Windows Vista 64位盒上的一切正常.
但是,如果我尝试在Windows 7(也是64位)上做同样的事情,我有一个非常奇怪的问题.这是我观察到的:
x.abc
从资源管理器中双击手动启动.x.abc
从命令提示符手动启动工作.Process.Start("x.abc")
没有启动申请; 但是,返回的进程对象显示没有错误,并且ClickOnce应用程序以某种方式立即退出.但即使是Trace
在ClickOnce应用程序的最开始,也永远不会到达.Process.Start("x.bat")
的文件也无法启动ClickOnce应用程序!同样从Explorer工作开始(当然).x.bat
x.abc
x.bat
试图分析发生的事情ProcMon
并不是很有帮助,因为从我的观点来看,启动应用程序的ClickOnce过程非常难以遵循.我观察rundll32
到上班,但没有任何失败的证据.
正在执行的程序Process.Start
是一个完全信任的控制台应用程序,真的没什么特别的.
我无法看到在Windows 7上处理ClickOnce应用程序的方式发生了哪些变化,为什么Process.Start
与从Explorer中启动文件完全相同.值得一提的是,使用该Start
方法的更高级版本ProcessStartInfo
并设置UseShellExecute
为true
无效.
开始cmd
使用Process.Start
,然后尝试推出x.abc
正好显示了同样的问题.如果我将环境设置与cmd
手动启动进行比较,我会看到如何ProgramFiles
定义的差异(第一个指向C:\Program Files (x86)
而第二个指向C:\Program Files
).从我的.NET应用程序启动的应用程序是在32位仿真层(SysWoW64)上启动的.
我能够x.abc
通过启动32位版本的命令提示符(即,%windir%\SysWoW64\cmd.exe
)然后x.abc
在提示符下键入来重现启动失败.我还发现了一个丑陋的解决方法,即通过启动%windir%\Sysnative\cmd.exe /C x.abc
而不是从32位环境启动64位命令提示符x.abc
. …
我正在尝试作为一个不同的用户运行一个进程,该用户在运行Vista并启用了UAC的2台不同计算机上具有管理员权限但在其中一个中我得到一个Win32Exception,其中显示"目录名称无效"
谁能告诉我我的代码有什么问题?
var myFile = "D:\\SomeFolder\\MyExecutable.exe";
var workingFolder = "D:\\SomeFolder";
var pInfo = new System.Diagnostics.ProcessStartInfo();
pInfo.FileName = myFile;
pInfo.WorkingDirectory = workingFolder;
pInfo.Arguments = myArgs;
pInfo.LoadUserProfile = true;
pInfo.UseShellExecute = false;
pInfo.UserName = {UserAccount};
pInfo.Password = {SecureStringPassword};
pInfo.Domain = ".";
System.Diagnostics.Process.Start(pInfo);
Run Code Online (Sandbox Code Playgroud)
UPDATE
执行上述代码的应用程序具有requireAdministrator执行级别.我甚至将工作文件夹设置为"Path.GetDirectoryName(myFile)"和"New System.IO.FileInfo(myFile).DirectoryName"