相关文章推荐
儒雅的核桃  ·  RxJava2.x实现定时器的方法_rxja ...·  7 月前    · 
博学的板凳  ·  Android应用程序级build.grad ...·  1 年前    · 
慷慨的蚂蚁  ·  GitHub ...·  1 年前    · 
深沉的伤疤  ·  excel中weekday函数使用方法或怎么 ...·  1 年前    · 
刚毅的红金鱼  ·  SQL数据库查询时间语句一天、一周、一月、一 ...·  1 年前    · 
Code  ›  CreateProcess时不显示或者不创建窗口 (或用虚拟桌面实现后台调用外部程序) 开发者社区
desktop 后台技术 虚拟桌面 createprocess
https://cloud.tencent.com/developer/article/1471042
傲视众生的饭卡
1 年前
作者头像
战神伽罗
0 篇文章

CreateProcess时不显示或者不创建窗口 (或用虚拟桌面实现后台调用外部程序)

前往专栏
腾讯云
开发者社区
文档 意见反馈 控制台
首页
学习
活动
专区
工具
TVP
文章/答案/技术大牛
发布
首页
学习
活动
专区
工具
TVP
返回腾讯云官网
社区首页 > 专栏 > Eureka的技术时光轴 > 正文

CreateProcess时不显示或者不创建窗口 (或用虚拟桌面实现后台调用外部程序)

发布 于 2019-07-24 15:18:36
2K 0
举报

【方法一:】 将 CreateProcess()的参数dwCreationFlags指定为CREATE_NO_WINDOW,即以不创建窗口方式创建DOS进程。 【参考代码:】 if (!CreateProcess(NULL, szCommand, NULL, NULL, FALSE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) 【方法二:】 指定STARTUPINFO结构中WORD wShowWindow为SW_HIDE(但是一定要有这一句: si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESHOWWINDOW; ),即以不显示窗口方式创建DOS进程。 【参考代码:】 STARTUPINFO si; PROCESS_INFORMATION pi; ::ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si); si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESHOWWINDOW; si.wShowWindow = SW_HIDE; ::ZeroMemory(&pi, sizeof(pi)); if (!CreateProcess(NULL, szCommand, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi)) 【方法三:】 将这个DOS窗口放到另外一个桌面上,实现隐藏。 【参考代码:】 si.lpDesktop="NewDesktop"; if (!CreateProcess(NULL, szCommand, NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) 方法三的详细原理: 参考 http://blog.163.com/madengyao_super/blog/static/2859822020093249493150/ 。 =============================================================================== 【用 虚拟桌面 实现后台调用外部程序】 最近需要实现一个无线通信的功能,X他XX的,该死的硬件厂商竟然不提供接口函数,只提供一个EXE可执行文件-_-! 这样就需要我在程序里调用他的这个EXE可执行文件。 调用EXE文件,可以用WINEXEC()、SHELLEXECUTE()和CreateProcess()等函数来实现,我这里就用CreateProcess()来调用。 但是一个软件,两个EXE文件,这叫什么??实在没办法,我想在打开的时候不让用户看到这个执行文件:首先调用FINDWINDOW来查找窗口的句柄,之后再用SendMessage()来隐藏窗口,但是还是会有一瞬主窗口被显示出来的,或许你会说我BT吧,但是我实在是不忍心看到…… 那么怎么解决这个问题呢,首先我当然在CreateProcess()上面寻找方法,可惜,它只有一个参数可以设置窗口的默认显示方式,但是一旦这个窗口自己重设了显示方式,它就没有任何作用了。 继续查找文档,这时我看到CreateProcess()的一个参数TStartupInfo中有 lpDesktop这么一个属性,按照MSDN的说法,如果该指针为NULL,那么新建的Process将在当前Desktop上启动,而如果对其赋了一个Desktop的名称后,Process将在指定的Desktop上启动,恩,看来不错,就从它入手了; 首先,建立一个虚拟的Desktop。 const DesktopName: PChar = 'NewDesktop'; FDesktop:= CreateDesktop(DesktopName, nil, nil, 0, GENERIC_ALL, nil); 然后,在CreateProcess的时候,指定程序在我新生成的Desktop上运行: SI: TStartupInfo; begin FillChar(SI, SizeOf(SI), 0); SI.cb:= SizeOf(SI); SI.lpDesktop:= DesktopName; SI.wShowWindow:= SW_HIDE; SI.dwFlags:= STARTF_USESHOWWINDOW; SI.hStdError:= 0; SI.hStdInput:= 0; SI.hStdOutput:= 0; if not CreateProcess(PChar('……'), nil, nil, nil, True, CREATE_NEW_CONSOLE + HIGH_PRIORITY_CLASS, nil, PChar('……'), SI, FProceInfo) then begin Application.MessageBox('Error', 'Error', $10); Exit; 再用FindWindow去找程序的主窗口. 开始我直接写下了这样的代码: WindowHandle:= FindWindow(nil, '……'); 但是,这样是找不到不在当前Desktop中的Window的,那怎么办呢? 这个时候,我突然看到一位同事在上班时间偷偷打游戏,我问他:“你不怕被抓到??” 他说:“给你看一个工具!” 原来是一个叫“玩游戏一键隐藏”的小工具,仔细想想,他应该是利用各桌面之间的切换来达到这种效果的,于是又开始查看MSDN,终于看到可以用SetThreadDesktop()函数,这个函数可以设置当前Thread工作所在的Desktop,于是我在以上代码前又加了一句: if not SetThreadDesktop(FDesktop) then begin Exit; 但是,程序运行后,该函数却返回了false,说明方法调用失败了,再仔细看MSDN,发现有这么一句话: [color=red]The SetThreadDesktop function will fail if the calling thread has any windows or hooks on its current desktop (unless the hDesktop parameter is a handle to the current desktop).[/color] 对不起,我的E文水平实在有够呛-_-!! 具体是什么意思我就不太清楚了,PASSION帮我翻译的时候,我也没怎么记得,只记得是要切换Desktop的线程要“干净”。 不好意思,我对这个“干净”的理解就是一个新的线城,于是抱着试一试的心情,我写下了: TFindWindowThread = class(TThread) private FDesktop, FWindowHandle: THandle; protected procedure Execute(); override; public constructor Create(Suspended: Boolean; const ADesktop: THandle); reintroduce; property WindowHandle: THandle read FWindowHandle; 而主程序中的代码变成这样: FindWindowThread:= TFindWindowThread.Create(False, FDesktop); FindWindowThread.WaitFor; WindowHandle:= FindWindowThread.WindowHandle; finally FindWindowThread.Free; if WindowHandle = 0 then begin Application.MessageBox('Error', 'Error', $10);

 
推荐文章
儒雅的核桃  ·  RxJava2.x实现定时器的方法_rxjava2 定时器-CSDN博客
7 月前
博学的板凳  ·  Android应用程序级build.gradle提供错误: httpclient定义与Android现在提供的类冲突的类。-腾讯云开发者社区-腾讯云
1 年前
慷慨的蚂蚁  ·  GitHub 首个开源图像识别系统又在搞事情!下-阿里云开发者社区
1 年前
深沉的伤疤  ·  excel中weekday函数使用方法或怎么计算星期-百度经验
1 年前
刚毅的红金鱼  ·  SQL数据库查询时间语句一天、一周、一月、一年_mysql_失去梦想变成大咸鱼-亚马逊云科技技术品牌专区
1 年前
今天看啥   ·   Py中国   ·   codingpro   ·   小百科   ·   link之家   ·   卧龙AI搜索
删除内容请联系邮箱 2879853325@qq.com
Code - 代码工具平台
© 2024 ~ 沪ICP备11025650号