本文记录一个 Win32 的有趣行为,调用 CreateProcess 方法传入特别的参数,可以让任务管理器里的命令行不显示应用文件路径

开始之前,先看看下面这张有趣的图片

可以看到我编写的 SvcawgewawkuHenaynairbelhurno.exe 应用在任务管理器的命令行里面显示的参数居然是 C:\Windows\notepad.exe 而不是具体的 SvcawgewawkuHenaynairbelhurno 应用 C:\lindexi\Code\SvcawgewawkuHenaynairbelhurno\SvcawgewawkuHenaynairbelhurno\bin\Debug\net6.0\SvcawgewawkuHenaynairbelhurno.dll 路径

这是如何实现的呢?这是使用了 CreateProcess 方法的一个过时用法,那就是在此方法的 lpApplicationName 参数里面传入将要启动的进程路径,在第二个参数 lpCommandLine 里面传入的是 C:\Windows\notepad.exe 命令行参数

以下是 CreateProcess 方法签名

BOOL CreateProcessW
(
[in, optional] LPCWSTR lpApplicationName,
[in, out, optional] LPWSTR lpCommandLine,
[in, optional] LPSECURITY_ATTRIBUTES lpProcessAttributes,
[in, optional] LPSECURITY_ATTRIBUTES lpThreadAttributes,
[in] BOOL bInheritHandles,
[in] DWORD dwCreationFlags,
[in, optional] LPVOID lpEnvironment,
[in, optional] LPCWSTR lpCurrentDirectory,
[in] LPSTARTUPINFOW lpStartupInfo,
[out] LPPROCESS_INFORMATION lpProcessInformation
);

在开始之前,需要聊聊 CreateProcess 方法的参数。根据 Windows 核心编程 第 5 版的 4.2.1 章的内容,可以知道几乎所有的应用代码都应该传入 null 给到 lpApplicationName 参数。这个 lpApplicationName 参数是为了支持 Windows 的 POSIX 子系统。换句话说就是正常咱是不应该使用到这个参数的。以下是书中的原文:

之所以让我们能为 CreateProcess 添加 pszApplicationName 参数,实际是为了支持 Windows 的 POSIX 子系统

注:书中的 pszApplicationName 参数,就是以上代码的 lpApplicationName 参数,只是参数命名有所不同而已

如果咱偏偏就要用这个 lpApplicationName 参数呢,就可以玩出一些无文档的锅,例如让任务管理器里面的命令行行为奇怪起来

接下来咱将创建一个控制台项目来测试此行为

先新建一个 dotnet 6 控制台程序,为了方便 PInvoke 调用 Win32 的 CreateProcess 函数,根据 dotnet 使用 CsWin32 库简化 Win32 函数调用逻辑 博客,添加 Microsoft.Windows.CsWin32 库,编辑 csproj 项目文件,替换为如下代码

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

  <PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWin32" PrivateAssets="all" Version="0.2.63-beta" />
</ItemGroup>
</Project>

接着再新建一个 NativeMethods.txt 文件,在此文件添加 CreateProcess 内容,用于让 CsWin32 生成调用相关的代码。但是 CsWin32 生成的代码比较难以使用,这里由自己定义了简单使用的方法

[DllImport("kernel32.dll", CharSet = CharSet.Unicode, EntryPoint = "CreateProcessW", ExactSpelling = true, SetLastError = true)]
static extern bool CreateProcess([In] string lpApplicationName, [In] string lpCommandLine, [In] IntPtr lpProcessAttributes,
[In] IntPtr lpThreadAttributes, [In] bool bInheritHandles, [In] uint dwCreationFlags, [In] IntPtr lpEnvironment,
[In] IntPtr lpCurrentDirectory, [In] in STARTUPINFOW lpStartupInfo, [Out] out PROCESS_INFORMATION lpProcessInformation);

为了方便代码使用,这里启动的进程也是自身应用路径。先使用以下代码获取自身的应用程序路径。当然,你也可以换成其他你喜欢的应用程序路径

var mainModuleFileName = Process.GetCurrentProcess().MainModule!.FileName!;

接下来创建一个有趣的命令行参数,例如就是记事本的路径

var arguments = "\"C:\\windows\\notepad.exe\"";

接着调用 CreateProcess 函数,如以下代码

var mainModuleFileName = Process.GetCurrentProcess().MainModule!.FileName!;

var startupInfo = new STARTUPINFOW();
startupInfo.cb = (uint) Marshal.SizeOf<STARTUPINFOW>(); var arguments = "\"C:\\windows\\notepad.exe\""; CreateProcess(mainModuleFileName, arguments, IntPtr.Zero, IntPtr.Zero, false, (uint) PROCESS_CREATION_FLAGS.CREATE_NEW_CONSOLE,
IntPtr.Zero, IntPtr.Zero, startupInfo, out var information);

由于是应用程序启动自身应用程序路径,还需要加上一点代码,防止不断启动

var processList = Process.GetProcessesByName(Assembly.GetExecutingAssembly().GetName().Name);
if (processList.Length > 1)
{
Console.WriteLine($"被启动的进程");
Console.Read();
}

开始启动项目,即可看到在任务管理器里面显示的命令行奇怪起来

如果以上的 arguments 是一个空字符串,那任务管理器将依然显示的是应用程序的文件路径

本文的代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 5bdc7de90b19094ecde1fc78a404f3d753c159cf

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源。请在命令行继续输入以下代码

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git
git pull origin 5bdc7de90b19094ecde1fc78a404f3d753c159cf

获取代码之后,进入 SvcawgewawkuHenaynairbelhurno 文件夹

Win32 使用 CreateProcess 方法让任务管理器里的命令行不显示应用文件路径的更多相关文章

  1. 【Android测试】【随笔】在手机里用命令行创建中文文件夹

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/4580319.html 不知道为啥当时自己写了一段在手机里用 ...

  2. 命令行下从bak文件恢复sqlserver数据库方法

    命令行下从bak文件恢复sqlserver数据库方法 注:本文所示访问从SqlServer 2000 - 2014版都是通用的 参考:http://blog.sina.com.cn/s/blog_5c ...

  3. 方法:怎么用ionic命令行调试你的ionic app

    官网上有很详细的解说  http://blog.ionic.io/live-reload-all-things-ionic-cli/ 下面说说我自己的调试过程(android版): 首先用命令行进入你 ...

  4. 不用输入ssh -i命令行即可携带pem文件快速登录的方法

    如果要登录的服务器只允许pem认证 每次输入ssh -i xxxx.pem 用户@ip 地址  就很烦 这里有个一劳永逸的方法: 进入到自己的用户目录,例如/home/me 把pem文件放在当前目录 ...

  5. Mac os下换行符导致发布到npm里的命令行模块不能使用问题

    学习node,弄一个命令行模块,发布到npm后,Windows安装后可以使用,但Mac 终端下则不行.对比grunt-cli搞了一夜,甚是郁闷,最后发现竟然是操作系统的换行符问题. npm insta ...

  6. 在终端(Terminal)里用命令行进行数学运算

    有时候我们进行一些数学运算,我们会去开系统自带的计算来做这件事情,其实我们也可以直接在终端里面用命令行进行的. 在命令行里敲 bc 进入数学计算模式,然后随便输入数学表达式 回车 ,结果就出来了,是不 ...

  7. Centos命令行窗口显示一大串前缀,777;notify;Command completed;的解决方法

    How to remove the return code from the terminal prompt In addition to the PS1 environment variable, ...

  8. 在VS中向命令行添加参数的方法

    在VS中向命令行添加参数的方法 在VS中向命令行添加参数,即向main()函数传递参数的方法: 右键单击要 添加参数的工程-->属性-->配置属性-->调试,在右侧“命令参数”栏输入 ...

  9. Mysql命令行中文乱码的解决方法

    环境:Windows 8 64位,Mysql  5.0.96 for Win64 (x86) 数据库本身安装时默认已经是使用utf8编码的了,但在命令行中执行查询时,查询到的中文依然乱码,解决方法如下 ...

  10. 命令行从Android手机中导出已安装APK的方法调研

    一.背景 二.步骤 一.背景 很多时候,APK文件只存在于应用市场,在PC上无法直接下载.用手机下载下来后就直接安装了,也不能保存原始的APK文件. APK安装到手机后,Android系统会保存一份和 ...

随机推荐

  1. 三维模型3DTile格式轻量化压缩必要性分析

    三维模型3DTile格式轻量化压缩必要性分析 理解3DTile格式轻量化压缩的必要性,首先需要理解三维模型的复杂性和数据量.三维模型通常包含大量的顶点.面片和纹理信息,这使得其数据量非常大,尤其对于大 ...

  2. 记录--Vue中的$attrs你真的会用吗?

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 先来看一个业务需求: 项目经常会遇到产品经理要求你做某组件一样的功能,还要在它的基础上增加东西.如何只用少量代码高效的二次封装组件呢? 例 ...

  3. Chrome浏览器:The request client is not a secure context and the resource is in more-private address ...

    1.概述 新版的chrome浏览器会校验发起端的域名和访问资源的域名直接的关系,如果客户端发起域名比访问资源所在的域名更public(开放),会导致The request client is not ...

  4. 搭建Spring Cloud父工程

    1.首先创建一个maven项目 删除src目录,当做一级目录用来管理第三方jar版本控制. 2.配置pom文件. SpringCloud.SpringCloudAlibaba.SpringBoot版本 ...

  5. NetAdapt:MobileNetV3用到的自动化网络简化方法 | ECCV 2018

    NetAdapt的思想巧妙且有效,将优化目标分为多个小目标,并且将实际指标引入到优化过程中,能够自动化产生一系列平台相关的简化网络,不仅搜索速度快,而且得到简化网络在准确率和时延上都于较好的表现   ...

  6. MemfireCloud让静态托管页面动起来!

    静态托管 我们最常接触到的静态托管是github pages,它的常见工作模式是在github上创建一个仓库,使用hexo类的工具初始化仓库,编写markdown文件,生成静态页面,推送到github ...

  7. #线性筛,斐波那契数列,GCD#BZOJ 2813 奇妙的Fibonacci

    题目 有一个斐波那契数列,满足 \[F_n=\begin{cases}1\qquad (n==1)\\1\qquad (n==2)\\F_{n-1}+F_{n-2}\qquad (n>2)\en ...

  8. #完全背包输出具体方案#AT4298 [ABC118D] Match Matching

    题目 分析 首先,用完全背包求出\(n\)根火柴能够组成的最大位数, 然后选择尽量大的数字拼凑即可 代码 #include <cstdio> #include <cctype> ...

  9. 使用OHOS SDK构建benchmark

    参照OHOS IDE和SDK的安装方法配置好开发环境. 从github下载源码. 执行如下命令: git clone --depth=1 https://github.com/google/bench ...

  10. SMOKE多模式排放清单处理技术及EDGAR/MEIC清单制作与VOCs排放量核算

    大气污染问题既是局部.当地的,也是区域的,甚至是全球的.本地的污染物排放除了对当地造成严重影响外,同时还会在动力输送作用下,极大地影响下风向地区的大气环境状况.数值模式模拟是分析大气污染物时空分布和成 ...