如果你关注过命令行参数,也许发现有时你会在命令行参数的第一个参数中中看到应用程序的路径,有时又不会。那么什么情况下有路径呢?


其实是否有路径只是取决于获取命令行参数的时候用的是什么方法。而这是 Windows 操作系统的机制,与具体的运行环境无关。

本文内容

测试程序

考虑下面这样的测试程序:

using System;
using System.Globalization; namespace Walterlv.Demo.CommandLines
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"参数总数:{args.Length}");
OutputArgsInfo(args); Console.WriteLine($"按任意键继续……");
Console.ReadKey();
} private static void OutputArgsInfo(string[] args)
{
var digitCount = (args.Length - 1).ToString(CultureInfo.InvariantCulture).Length; for (var i = 0; i < args.Length; i++)
{
Console.WriteLine($"[{i.ToString().PadLeft(digitCount, ' ')}] {args[i]}");
}
}
}
}

当我们向命令行中传入参数的时候,我们可以得到所有的命令行。


▲ Main 函数中的命令行参数

这种行为与具体的 .NET SDK 无关。看我们的项目文件,可以发现,无论是老旧的 .NET Framework 4.5 还是新的 .NET Framework 4.7.2 还是更加主流的 .NET Core 2.1,命令行参数中都是没有应用程序路径的。

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net45;net472;netcoreapp2.1</TargetFrameworks>
</PropertyGroup> </Project>

那为什么有时候会看到应用程序路径呢?

解释

在《Windows 核心编程》一书中有说到:

可以获得一个指向进程的完整命令行的指针,方法是调用 GetCommandLine 函数:

PTSTR GetCommandLine();

该函数返回一个指向包含完整命令行的缓存的指针,该命令行包括执行文件的完整路径名。

也就是说,调用 GetCommandLine 函数时,我们将得到包含执行文件的完整路径名的命令行参数。这个方法对应到 .NET 中,是 System.Environment.GetCommandLineArgs()

于是修改我们刚刚的函数,加上 Environment.GetCommandLineArgs() 的调用:

using System;
using System.Globalization; namespace Walterlv.Demo.CommandLines
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine($"Main 函数参数列表中参数总数:{args.Length}");
OutputArgsInfo(args); args = Environment.GetCommandLineArgs();
Console.WriteLine($"GetCommandLineArgs 参数总数:{args.Length}");
OutputArgsInfo(args); Console.WriteLine($"按任意键继续……");
Console.ReadKey();
} private static void OutputArgsInfo(string[] args)
{
var digitCount = (args.Length - 1).ToString(CultureInfo.InvariantCulture).Length; for (var i = 0; i < args.Length; i++)
{
Console.WriteLine($"[{i.ToString().PadLeft(digitCount, ' ')}] {args[i]}");
}
}
}
}

现在,我们能看到参数列表中多了应用程序的完整路径:


▲ GetCommandLineArgs 中的命令行参数

事实上这样的差异不止在 .NET 中有体现,整个 Windows 上的程序都是这样的特性。这在《Windows 核心编程》一书中是有说明的。

总结

  1. Main 函数的参数中不包含应用程序执行路径;
  2. System.Environment.GetCommandLineArgs() 得到的命令行参数中包含应用程序的执行路径;
  3. Windows 上的所有程序其命令行参数的行为表现都是如此,这不是 .NET 的专属特性。

.NET 命令行参数包含应用程序路径吗?的更多相关文章

  1. R语言 使用命令行参数运行R程序

    args_test.R 代码如下: Args <- commandArgs()cat("Args[1]=",Args[1],"\n")cat(" ...

  2. (转)C#_WinForm接收命令行参数

    本文转载自:http://blog.csdn.net/lysc_forever/article/details/38356007 首先,我要仔细的声明下,本文讲的是接受命令行参数,让程序启动.而不是启 ...

  3. C#_WinForm接收命令行参数

    C#_WinForm接收命令行参数 2014-08-03 10:17 534人阅读 评论(0) 收藏 举报 首先,我要仔细的声明下,本文讲的是接受命令行参数,让程序启动.而不是启动那个黑黑的框...我 ...

  4. Perl的命令行参数和ARGV

    程序名:$0 $0表示当前正在运行的Perl脚本名.有3种情况: 如果执行方式为perl x.pl,则$0的值为x.pl而非perl命令本身 如果执行方式为./x.pl,则$0的值为./x.pl 如果 ...

  5. C语言中使用库函数解析命令行参数

    在编写需要命令行参数的C程序的时候,往往我们需要先解析命令行参数,然后根据这些参数来启动我们的程序. C的库函数中提供了两个函数可以用来帮助我们解析命令行参数:getopt.getopt_long. ...

  6. Win32程序支持命令行参数的做法(转载)

    转载:http://www.cnblogs.com/lanzhi/p/6470406.html 转载:http://blog.csdn.net/kelsel/article/details/52759 ...

  7. Win32程序支持命令行参数的做法

    作者:朱金灿 来源:http://blog.csdn.net/clever101 首先说说Win 32 API程序如何支持命令行参数.Win 32程序的入口函数为: int APIENTRY _tWi ...

  8. 7z命令行参数中的路径

    最近在自动化的过程中用到了7z命令行工具,发现其参数中的路径挺有意思的,在此总结一下.本文中所有demo使用的7z版本为:15.14 x64. 压缩某个文件夹 下面的命令会把g:\temp\目录和目录 ...

  9. Delphi 获取进程路径及命令行参数

    Delphi 获取进程路径及命令行参数, 但有的进程获取时会报错,不知为啥 type PVOID64 = UINT64; _UNICODE_STRING = packed record Length ...

随机推荐

  1. VS2010/MFC编程入门之十二(对话框:非模态对话框的创建及显示)

    上一节鸡啄米讲了模态对话框及其弹出过程,本节接着讲另一种对话框--非模态对话框的创建及显示. 鸡啄米已经说过,非模态对话框显示后,程序其他窗口仍能正常运行,可以响应用户输入,还可以相互切换.鸡啄米会将 ...

  2. 2017ACM/ICPC Guangxi Invitational Solution

    A: A Math Problem 题意:给出一个n,找出有多少个k满足kk  <= n 思路: kk的增长很快,当k == 16 的时候就已经超过1e18 了,对于每一次询问,暴力一下就可以 ...

  3. navicat中文破解版,navicat破解版,navicat for mysql10.0.11简体中文破解版

    https://blog.csdn.net/weixin_40426638/article/details/78933585 下载链接如下(里面有破解码) https://pan.baidu.com/ ...

  4. WPF usercontrol 自定义依赖属性

    1.依赖属性不同意一般属性,一般属性主要定义在对象中,而依赖属性是存在一个特殊的依赖属性表中.2.当我们触发改变值时,需要通过SetValue这种方式进行触发. UserControl1.xaml: ...

  5. pyDay16

    内容来自廖雪峰的官方网站. 1.Python内建的filter()函数用于过滤序列. 2.和map()类似,filter()也接收一个函数和一个序列.和map()不同的是,filter()把传入的函数 ...

  6. 20145104张家明 《Java程序设计》第4周学习总结

    20145104张家明 <Java程序设计>第4周学习总结 教材学习内容总结 第六章 1.继承的定义及目的 面向对象中,子类继承父类,避免重复的行为定义.不过并非为了避免重复定义行为就使用 ...

  7. 解决use -D_SCL_SECURE_NO_WARNINGS的问题

    加入预处理器(项目属性----C/C++----预处理----预处理器定义): _SCL_SECURE_NO_WARNINGS

  8. HBase参数优化

    zookeeper.session.timeout默认值:3分钟(180000ms)说明:RegionServer与Zookeeper间的连接超时时间.当超时时间到后,ReigonServer会被Zo ...

  9. CentOS7.2 切换成iptables规则

    关闭firewall service firewalld stop systemctl disable firewalld.service #禁止firewall开机启动 安装iptables规则: ...

  10. 【重新挂载磁盘空间】Linux系统/home的磁盘空间重新挂载给/root

    以下是在centos7版本上做测试 使用如下命令查看磁盘使用情况 ls -lh 文件系统 容量 已用 可用 已用% 挂载点 devtmpfs 3.9G 0 3.9G 0% /dev tmpfs 3.9 ...