当前位置: 首页 > news >正文

.NET 命令行参数包含应用程序路径吗?

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


其实是否有路径只是取决于获取命令行参数的时候用的是什么方法。而这是 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 函数中的命令行参数
▲ 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 中的命令行参数
▲ GetCommandLineArgs 中的命令行参数

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

总结

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

相关文章:

  • 分析现有 WPF / Windows Forms 程序能否顺利迁移到 .NET Core 3.0(使用 .NET Core 3.0 Desktop API Analyzer )
  • C# 空合并操作符(??)不可重载?其实有黑科技可以间接重载!
  • UWP 轻量级样式定义(Lightweight Styling)
  • 预编译框架,开发高性能应用 - 课程 - 微软技术暨生态大会 2018
  • 将 UWP 中 CommandBar 的展开方向改为向下展开
  • .NET 中创建支持集合初始化器的类型
  • .NET 中让 Task 支持带超时的异步等待
  • .NET/C# 中你可以在代码中写多个 Main 函数,然后按需要随时切换
  • WPF 的 ElementName 在 ContextMenu 中无法绑定成功?试试使用 x:Reference!
  • WPF 中的 NameScope
  • Windows 下的高 DPI 应用开发(UWP / WPF / Windows Forms / Win32)
  • 技术、产品、交流、思考 - 微软技术暨生态大会 2018
  • .NET/C# 反射的的性能数据,以及高性能开发建议(反射获取 Attribute 和反射调用方法)
  • .NET/C# 异常处理:写一个空的 try 块代码,而把重要代码写到 finally 中(Constrained Execution Regions)
  • WindowsXamlHost:在 WPF 中使用 UWP 控件库中的控件
  • 【402天】跃迁之路——程序员高效学习方法论探索系列(实验阶段159-2018.03.14)...
  • 【跃迁之路】【444天】程序员高效学习方法论探索系列(实验阶段201-2018.04.25)...
  • android图片蒙层
  • C# 免费离线人脸识别 2.0 Demo
  • const let
  • ES6之路之模块详解
  • IDEA 插件开发入门教程
  • JavaScript 是如何工作的:WebRTC 和对等网络的机制!
  • Js基础——数据类型之Null和Undefined
  • Linux下的乱码问题
  • PHP 程序员也能做的 Java 开发 30分钟使用 netty 轻松打造一个高性能 websocket 服务...
  • Yii源码解读-服务定位器(Service Locator)
  • 对超线程几个不同角度的解释
  • 看完九篇字体系列的文章,你还觉得我是在说字体?
  • 利用jquery编写加法运算验证码
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 软件开发学习的5大技巧,你知道吗?
  • 一些关于Rust在2019年的思考
  • Linux权限管理(week1_day5)--技术流ken
  • 阿里云服务器如何修改远程端口?
  • ​直流电和交流电有什么区别为什么这个时候又要变成直流电呢?交流转换到直流(整流器)直流变交流(逆变器)​
  • # 计算机视觉入门
  • #常见电池型号介绍 常见电池尺寸是多少【详解】
  • $().each和$.each的区别
  • $con= MySQL有关填空题_2015年计算机二级考试《MySQL》提高练习题(10)
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (pytorch进阶之路)扩散概率模型
  • (附源码)springboot炼糖厂地磅全自动控制系统 毕业设计 341357
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (六)vue-router+UI组件库
  • (论文阅读32/100)Flowing convnets for human pose estimation in videos
  • (四)【Jmeter】 JMeter的界面布局与组件概述
  • (一一四)第九章编程练习
  • (转) Face-Resources
  • (转)【Hibernate总结系列】使用举例
  • (转)iOS字体
  • (转)Java socket中关闭IO流后,发生什么事?(以关闭输出流为例) .
  • *上位机的定义
  • .chm格式文件如何阅读
  • .net core MVC 通过 Filters 过滤器拦截请求及响应内容