- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
out.txt 运行它,但我想使用 Visual Stu-6ren">
我正在尝试将 C# 程序的输出重定向到一个文件。使用“cmd.exe”时,我可以简单地使用 myprogram.exe arg1 arg2 > out.txt
运行它,但我想使用 Visual Studio Start Options
.
我创建了一个C# 空项目并添加了这段代码:
using System;
class Test
{
public static void Main(string[] args)
{
foreach (var arg in args) Console.WriteLine(arg);
}
}
然后我在项目设置中编辑了命令行参数:
使用 Ctrl+F5 运行项目无法按预期运行。我在控制台而不是输出文件中打印了命令行参数:
arg1
arg2
>
output.txt
如果我将命令行参数更改为:arg1 arg2 "> output.txt"
我会得到以下输出:
arg1
arg2
^> output.txt
我注意到在 Output 文件夹中创建了一个空的 output.txt
文件。
这件事有可能完成还是我被迫继续使用 cmd.exe 来启动我的程序?
最佳答案
从严格意义上讲,您被迫使用命令提示符启动带有重定向输出的程序。否则,您需要自己解析命令行,GUI shell 可能不会这样做。
如果您只是想在 Start Debugging
时重定向输出,然后取消选中 Enable the Visual Studio hosting process
复选框,您就完成了。
如果您没有这样做,那么您在那里看到的 "output.txt"
实际上不是由您的应用程序生成的,而是"YourApplication.vshost.exe"
是在您开始调试之前由 Visual Studio IDE 生成的。内容永远是空的,不能写;因为它被 Hosting Process 锁定了.
但是,如果您希望应用程序无论以何种模式启动都表现得一样,事情就更复杂了。
当您开始调试应用程序时,它开始于:
"YourApplication.exe" arg1 arg2
因为输出已经被 IDE 重定向了。
当你Start Without Debugging
时,它开始于:
"%comspec%" /c ""YourApplication.exe" arg1 arg2 ^>output.txt & pause"
这是让您的应用程序获取您指定的所有参数的正确方法。
您可能想看看我之前对 How can I detect if "Press any key to continue . . ." will be displayed? 的回答.
这里我使用了类似 atavistic throwback 的方法在下面的代码中:
申请代码
using System.Diagnostics;
using System.Linq;
using System;
class Test {
public static void Main(string[] args) {
foreach(var arg in args)
Console.WriteLine(arg);
}
static Test() {
var current=Process.GetCurrentProcess();
var parent=current.GetParentProcess();
var grand=parent.GetParentProcess();
if(null==grand
||grand.MainModule.FileName!=current.MainModule.FileName)
using(var child=Process.Start(
new ProcessStartInfo {
FileName=Environment.GetEnvironmentVariable("comspec"),
Arguments="/c\x20"+Environment.CommandLine,
RedirectStandardOutput=true,
UseShellExecute=false
})) {
Console.Write(child.StandardOutput.ReadToEnd());
child.WaitForExit();
Environment.Exit(child.ExitCode);
}
#if false // change to true if child process debugging is needed
else {
if(!Debugger.IsAttached)
Debugger.Launch();
Main(Environment.GetCommandLineArgs().Skip(1).ToArray());
current.Kill(); // or Environment.Exit(0);
}
#endif
}
}
我们还需要下面的代码,这样它才能工作:
扩展方法代码
using System.Management; // add reference is required
using System.Runtime.InteropServices;
using System.Diagnostics;
using System.Collections.Generic;
using System.Linq;
using System;
public static partial class NativeMethods {
[DllImport("kernel32.dll")]
public static extern bool TerminateThread(
IntPtr hThread, uint dwExitCode);
[DllImport("kernel32.dll")]
public static extern IntPtr OpenThread(
uint dwDesiredAccess, bool bInheritHandle, uint dwThreadId);
}
public static partial class ProcessThreadExtensions /* public methods */ {
public static void Abort(this ProcessThread t) {
NativeMethods.TerminateThread(
NativeMethods.OpenThread(1, false, (uint)t.Id), 1);
}
public static IEnumerable<Process> GetChildProcesses(this Process p) {
return p.GetProcesses(1);
}
public static Process GetParentProcess(this Process p) {
return p.GetProcesses(-1).SingleOrDefault();
}
}
partial class ProcessThreadExtensions /* non-public methods */ {
static IEnumerable<Process> GetProcesses(
this Process p, int direction) {
return
from format in new[] {
"select {0} from Win32_Process where {1}" }
let selectName=direction<0?"ParentProcessId":"ProcessId"
let filterName=direction<0?"ProcessId":"ParentProcessId"
let filter=String.Format("{0} = {1}", p.Id, filterName)
let query=String.Format(format, selectName, filter)
let searcher=new ManagementObjectSearcher("root\\CIMV2", query)
from ManagementObject x in searcher.Get()
let process=
ProcessThreadExtensions.GetProcessById(x[selectName])
where null!=process
select process;
}
// not a good practice to use generics like this;
// but for the convenience ..
static Process GetProcessById<T>(T processId) {
try {
var id=(int)Convert.ChangeType(processId, typeof(int));
return Process.GetProcessById(id);
}
catch(ArgumentException) {
return default(Process);
}
}
}
因为在我们调试时,父级将是 Visual Studio IDE(当前名为 "devenv"
)。父进程和祖父进程实际上是多种多样的,我们需要一个规则来执行一些检查。
棘手的部分 是真正遇到Main
的是孙子。代码在每次运行时检查祖父进程。如果祖 parent 是 null
那么它会产生,但产生的进程将是 %comspec%
,这也是它将以相同的可执行文件启动的新进程的父进程当前。因此,如果祖 parent 与自己相同,那么它就不会继续生成,只会遇到 Main
。
Static Constructor在代码中使用,在Main
之前启动。 SO 上有一个已回答的问题:How does a static constructor work? .
当我们开始调试时,我们正在调试祖父进程(产生)。为了使用孙子进程进行调试,我制作了带有条件编译的 Debugger.Launch
,它将调用 Main
,以保持 Main
清晰。
有关调试器的已回答问题也会有所帮助:Attach debugger in C# to another process .
关于c# - 如何使用 Visual Studio "command line arguments"选项将 C# 项目的标准输出重定向到文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16262394/
例如,如果我的程序名称是 test.c 然后对于以下运行命令,argc = 2 而不是 4。 $test abc pqr* *xyz* 最佳答案 尝试运行: $ echo abc pqr* *xyz*
我正在尝试使用一个容器来显示TextField,但是该容器不喜欢我的操作顺序。这是我的代码: Widget build(BuildContext context) { return Scaffol
我有以下代码: class MetricGoogleGateway extends AMetricGateway{ constructor(id, name, token) {
我像这样调用下面的对象方法。 new Cout( elem1 ).load( 'body' ) new COut( elem1 ).display( 'email' ) 我一次只使用一个实例。因为我一
我正在尝试使用 C++11 中的可变参数函数模板,并通过如下代码了解了基本思想: void helper() { std::cout void helper( T&& arg ) {
在学习 ExtJS 4 时,我发现在定义一个新类时,在 initComponent 中方法可以使用 this.callParent(arguments) 调用父类的构造函数. 我想知道这个 argum
使用 XCode 9,Beta 3。Swift 4。 statsView.createButton("Button name") { [weak self] Void in //stuff st
以下代码将打印1: (function (arguments) { console.log(arguments); }(1, 2)); 实际上,arguments 对象已被覆盖。是否可以恢复函
/** * @param $name * @return Response * @Route ("/afficheN/{name}",name="afficheN") */ public fu
我习惯使用Scala scopt用于命令行选项解析。您可以选择参数是否为 .required()通过调用刚刚显示的函数。 如何定义仅在定义了另一个参数时才需要的参数? 例如,我有一个标志 --writ
所以这是我的代码: def is_valid_move(board, column): '''Returns True if and only if there is an o
我试图在这里运行此代码: threads = [threading.Thread(name='ThreadNumber{}'.format(n),target=SB, args(shoe_type,m
在静态类型函数编程语言(例如 Standard ML、F#、OCaml 和 Haskell)中,编写函数时通常将参数彼此分开,并通过空格与函数名称分开: let add a b = a + b
function validateArguments(args) { if(args.length 2) { throw new RangeError("Invalid amo
我正在使用 Django 1.5 并尝试将参数传递到我的 URL。当我使用前两个参数时,下面的代码工作正常,使用第三个参数时我收到错误。我已经引用了新的 Django 1.5 更新中的 url 用法,
我刚刚开始使用 ember js 并且多次被这个功能绊倒 有人可以简要介绍一下 this._super() 的使用,并解释 ...arguments 的重要性 谢谢 最佳答案 每当您覆盖类/函数(例如
这个问题在这里已经有了答案: How to fix an "Argument passed to call that takes no arguments" error? (2 个答案) 关闭 3
我正在创建一个简单的登录注册应用程序。但是我遇到了错误,我不知道如何解决,请帮忙!这是我的代码: // // ViewController.swift // CHLogbook-Applicati
我是 Swift 的初学者。我尝试创建一个表示 Meal 的简单类。 它有一些属性和一个返回可选的构造函数 但是当我尝试测试它或在任何地方实例化它时,我得到的只是一个错误。似乎无法弄清楚发生了什么。
我有一个在特殊环境下运行其他程序的系统程序: cset shield -e PROGRAM .现在要运行一个 java 程序,我输入了 cset shield -e java PROGRAM ,但这不
我是一名优秀的程序员,十分优秀!