C# 使用相同的参数启动程序的第二个副本
应用程序使用相同的参数重新启动自身的另一个副本的正确方法是什么 我当前的方法是执行以下操作C# 使用相同的参数启动程序的第二个副本,c#,C#,应用程序使用相同的参数重新启动自身的另一个副本的正确方法是什么 我当前的方法是执行以下操作 static void Main() { Console.WriteLine("Start New Copy"); Console.ReadLine(); string[] args = Environment.GetCommandLineArgs(); //Will not work if using vshost, uncomment the next line t
static void Main()
{
Console.WriteLine("Start New Copy");
Console.ReadLine();
string[] args = Environment.GetCommandLineArgs();
//Will not work if using vshost, uncomment the next line to fix that issue.
//args[0] = Regex.Replace(args[0], "\\.vshost\\.exe$", ".exe");
//Put quotes around arguments that contain spaces.
for (int i = 1; i < args.Length; i++)
{
if (args[i].Contains(' '))
args[i] = String.Concat('"', args[i], '"');
}
//Combine the arguments in to one string
string joinedArgs = string.Empty;
if (args.Length > 1)
joinedArgs = string.Join(" ", args, 1, args.Length - 1);
//Start the new process
Process.Start(args[0], joinedArgs);
}
static void Main()
{
Console.WriteLine(“启动新副本”);
Console.ReadLine();
字符串[]args=Environment.GetCommandLineArgs();
//如果使用vshost,请取消注释下一行以修复该问题,则将不起作用。
//args[0]=Regex.Replace(args[0],“\\.vshost\\.exe$”,“.exe”);
//在包含空格的参数周围加引号。
for(int i=1;i1)
joinedArgs=string.Join(“,args,1,args.Length-1);
//启动新流程
Process.Start(args[0],joinedarg);
}
然而,那里似乎有很多繁忙的工作。忽略vshost的条带化,我仍然需要将带有空格的参数包装为“
,并将参数数组合并到单个字符串中
是否有更好的方法来启动程序的新副本(包括相同的参数),或者只需要传入或获取参数的字符串数组?这就足够了吗
static void Main(string[] args)
{
string commandLineArgs = args.Join(" ");
}
您必须引用包含空格(以及我不确定的其他字符)的命令行参数
var commandLine = string.Join(" ", args.Select(s => s.Contains(' ') ? "\"" + s + "\"" : s));
var newProcess = Process.Start("yourapplication.exe", commandLine);
另外,不是使用
string[] args = Environment.GetCommandLineArgs();
您可以在Main
方法中接受它们:
public static void Main(string[] args)
{
var commandLine = string.Join(" ", args.Select(s => s.Contains(' ') ? "\"" + s + "\"" : s));
var newProcess = Process.Start(Environment.GetCommandLineArgs()[0], commandLine);
}
您现在使用的vshost解决方案似乎很好,或者您可以通过取消选中项目“调试”选项卡上的“启用Visual Studio宿主进程”来禁用整个vshost。当您这样做时,某些调试功能确实会被禁用。这是一个很好的解释
编辑:
解决此问题的更好方法是将代码库添加到入口点程序集:
public static void Main(string[] args)
{
var imagePath = Assembly.GetEntryAssembly().CodeBase;
var commandLine = string.Join(" ", args.Select(s => s.Contains(' ') ? "\"" + s + "\"" : s));
var newProcess = Process.Start(imagePath, commandLine);
}
无论是否启用vshost,这都可以使用。好的,我想应该可以
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
private static extern System.IntPtr GetCommandLine();
static void Main(string[] args)
{
System.IntPtr ptr = GetCommandLine();
string commandLine = Marshal.PtrToStringAuto(ptr);
string arguments = commandLine.Substring(commandLine.IndexOf("\"", 1) + 2);
Console.WriteLine(arguments);
Process.Start(Assembly.GetEntryAssembly().Location, arguments);
}
参考:Aww,一个.NET fork炸弹,多么可爱:)@Pheonixblade9我之所以将
控制台.ReadLine()
放在:)请参阅关于将解析的命令行参数组合回单个字符串的内容。较短的版本:它比“+arg+更复杂“
。正在尝试了解此应用程序的用例。。。Hmm@JMC我有一个程序,当人们进入RDP时,它是windows的替代shell,但是一些用户(管理员)需要完整的桌面+我的替代shell应用程序,所以我要做的是:1。我检测用户是否是管理员,2。检查资源管理器是否已在当前会话中运行,3。启动Explorer并隐藏我的替换shell(关闭shell会注销当前用户)。启动一个新的替换外壳程序副本,它不会在终止时注销windows。不,使用命令行参数测试它。这是“一些参数”
您的第一次运行将是args[0]=“This”;args[1]=“是”;args[2]=“一些args”
但是您的第二次运行将是args[0]=“这个”;args[1]=“是”;args[2]=“一些”;args[3]=“args”
此外,您根本不知道如何启动流程。包括它并处理您创建的额外参数,我将删除我的-1。这是我一直在考虑的函数,但记不起它的名称。这基本上是一种更复杂的说法Environment.CommandLine
,它不会工作,因为进程.Start
要求文件名和参数作为两个独立的参数。这不是一个复杂的方法,只是实际的命令行。顺便说一句,为什么-我投票???更新了代码以仅提供参数。您还可以从命令行中删除当前正在执行的exe路径,而不是我使用的子字符串表达式。向下投票是因为代码不会按发布的方式运行,但更新修复了问题。这是做同样事情的一种更复杂的方式。去看看什么环境。命令行返回的结果与你的pInvoke调用是一样的。是的。。我只是懒得花些额外的精力来拆分它。+1用于提及“启用Visual Studio托管进程”选项。比起在代码中绕过它,我更喜欢它。我知道如何取消检查托管进程,这就是为什么它在我的代码中被注释的原因,因为我没有检查该进程。但我不想让那些只是复制和粘贴我的代码的人怀疑为什么它不起作用。@ScottChamberlain为避免vshost问题又添加了一个替代方案。