本文记录一个 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. 使用Java给图片添加水印

    什么是水印呢?比如使用手机拍摄一张照片的时候,照片右下角的位置显示得有日期和时间信息,那就表示一个水印. 项目开发中给图片添加水印的操作很常见,比如给图片添加日期和时间,给图片添加公司的logo之类的 ...

  2. 用phpStudy配置apache服务器

    一:下载phpStudy 1进入官网https://www.xp.cn/download.html 选择稳定的2018版本 2执行下载好的文件,选择下载地址 注意!这里的安装路径不能有中文 3亮两个绿 ...

  3. Python简单程序设计(计算程序设计(存款利息)篇)

    如题: 解题方式如下:

  4. 记录--7 个沙雕又带有陷阱的 JS 面试题

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 为了保证的可读性,本文采用意译而非直译. 在 JS 面试中,经常会看到一些简单而又沙雕的题目,这些题目包含一些陷阱,但这些在我们规范的编码 ...

  5. 记录--vue3中的ref,toRef,toRefs

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. ref的使用 ref 接受一个原始值,返回一个具有响应式的对象,对象有一个value属性,其值就是所传递的原始值. ref是做的一个 ...

  6. ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接

    ConnectionResetError: [WinError 10054] 远程主机强迫关闭了一个现有的连接 是因为使用urlopen方法太过频繁,引起远程主机的怀疑,被网站认定为是攻击行为.导致u ...

  7. C#词云生成器

    GitHub - sdcb/Sdcb.WordCloud: Generate WordCloud image from .NET/.NET Core 效果 根据mask生成

  8. 使用 shell 脚本自动申请进京证 (六环外)

    问题背景 外地车辆进入北京,需要办理<进京证>,不办理证件驶入后会被执法设备抓拍,一次罚 100 扣 1 分,目前唯一的线上办理通道是下载<北京交警>App,注册后添加车辆,就 ...

  9. 区块链从入门到放弃系列教程-涵盖密码学,超级账本,以太坊,Libra,比特币等持续更新

    目录 简介 什么是区块链 区块链不是什么 区块链的基础:密码学 区块链的基础:分布式系统和共识机制 超级账本Hyperledger 以太坊 Libra 比特币 总结 简介 区块链是一种防篡改的共享数字 ...

  10. 动态库 DLL 封装二:dll封装方法

    例:我新建的工程是,带lib的MFC规则的DLL 主要有三个文件需要写东西 ( .h /  .cpp  /  .def ) 示例: // a.h ...... #ifdef __cplusplus e ...