zoukankan      html  css  js  c++  java
  • Windows下如何让非NT程序像NT程序一样毫无踪迹在后台运行?

    Windows版本:Windows 10

    Delphi版本:Delphi 10.3

    需求说明:让正常的图形界面程序或DOS程序,能够彻底隐藏踪迹,像NT程序一样在后台悄悄运行!!正常的程序,如果在运行时候,会有程序窗口,如果加入了在任务栏显示代码,最小化会在任务栏有图标!!这些我都不想要,我就想让这些正常程序运行时候,根本任何运行痕迹都看不到!!!

    解决过程:

    通常这样的程序,把运行的参数设置为SW_HIDE就可以了,但是,对于有些程序,这样设置是不可以的,当最小化时候,会在任务栏留有图标!!怎么办?创建虚拟桌面,让这个运行的程序在这个虚拟桌面中,这样,在当前运行程序的桌面中就看不到任何踪迹了!!

    Delphi实现代码:

    uses TLHelp32; // 判断进程是否运行用的单元
    
    const
      DesktopName: PChar = 'NewDesktop'; //虚拟桌面名称
    
    var
      desktopHandle: THandle; // 桌面handle
    
    {
      像NT程序一样在后台运行程序,前台看不到被运行程序
      说明:无论要运行的程序是正常的图形界面程序,还是DOS程序,在运行程序的桌面中看不到它的任何运行的踪迹,
      被运行的程序像NT程序一样悄悄在后台运行,即使这个程序正常运行时候最小化会在任务栏有图标!!
      在任务管理器中会查看到被运行程序的进程!!
      参数:
      fullExe:要运行程序的全路径名称
      exeParam:要运行程序的参数
      tempDesktopName:创建的虚拟桌面名称
      tempDesktopHandle:创建的虚拟桌面Handle
      返回值:是否运行成功
    }
    function RunInbackGround(fullExe: string; exeParam: string;
      tempDesktopName: string; var tempDesktopHandle: THandle): boolean;
    var
      isSuccess: boolean; // 是否运行成功的返回值
    
      CmdLine: string; // 要执行的命令(要执行程序的全路径名称+参数)
      WorkingDirP: PChar; // 工作目录
      StartupInfo: TStartupInfo; // 进程启动参数
      ProcessInfo: TProcessInformation; // 进程信息
      ErrorCode: integer; // 进程启动的错误代码
      exeName: string; // 要执行程序名称
    
      // 是否程序正在运行
      function isExeRunning(exeName: string): boolean;
      var
        lppe: TProcessEntry32;
        isFound: boolean;
        Hand: THandle;
        tempName: string; // 程序名称
        temp: boolean; // 返回值变量
        judgePos: integer; // 扩展名判断位置
      begin
        Hand := CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
        lppe.dwSize := SizeOf(lppe); // 必须设置此值
        isFound := Process32First(Hand, lppe);
    
        temp := false; // 返回的布尔值
    
        // 程序名称变量
        tempName := trim(exeName);
    
        // 扩展名分隔符位置
        judgePos := Pos('.', tempName);
    
        // 判断是否有扩展名
        if judgePos = 0 then
        begin
          tempName := tempName + '.exe'; // 添加".exe"扩展名
        end
        else
        begin
          if Length(copy(tempName, judgePos, 4)) < 4 then
          begin
            // 删除不符合添加的扩展名
            Delete(tempName, judgePos, (Length(tempName) - judgePos + 1));
            // 添加".exe"扩展名
            tempName := tempName + '.exe';
          end;
        end;
    
        // 循环判断是否有相同名称程序
        while isFound do
        begin
    
          // 判断当前程序名称和指定程序名称相同
          if lppe.szExeFile = tempName then
          begin
            temp := true;
            Break;
          end;
    
          // Memo1.Lines.Add(IntToStr(i) + ' : ' +IntToStr(lppe.th32ProcessID)+' '+ StrPas(lppe.szExeFile));
          isFound := Process32Next(Hand, lppe);
        end;
    
        result := temp;
      end;
    
    // 杀死进程
      procedure KillProc(procName: string);
      const
        PROCESS_TERMINATE = $0001;
      var
        ExeFileName: String;
        ContinueLoop: Bool;
        FSnapshotHandle: THandle;
        FProcessEntry32: TProcessEntry32;
      begin
        ExeFileName := procName;
        FSnapshotHandle := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        FProcessEntry32.dwSize := SizeOf(FProcessEntry32);
        ContinueLoop := Process32First(FSnapshotHandle, FProcessEntry32);
        while integer(ContinueLoop) <> 0 do
        begin
          if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile))
            = UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile)
            = UpperCase(ExeFileName))) then
            TerminateProcess(OpenProcess(PROCESS_TERMINATE, Bool(0),
              FProcessEntry32.th32ProcessID), 0);
          ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32);
        end;
      end;
    
    begin
    
      isSuccess := true; // 是否运行成功的返回值的默认值
    
      {
        一,创建用于存放要运行程序的虚拟桌面
      }
      // 如果虚拟桌面没有创建,则创建
      if tempDesktopHandle = 0 then
      begin
        tempDesktopHandle := CreateDesktop(PChar(tempDesktopName), nil, nil, 0,
          GENERIC_ALL, nil);
      end;
    
      {
        二,运行指定的程序
      }
      try
    
        // 要执行的命令(要执行程序的全路径名称+参数)
        CmdLine := '"' + trim(fullExe) + '" ' + trim(exeParam);
        WorkingDirP := nil; // 工作目录
    
        exeName := ExtractFileName(fullExe); // 得到要运行的程序名称
        // 如果要运行程序运行中,则先杀死它
        if isExeRunning(exeName) = true then
        begin
          KillProc(exeName); // 杀死正在运行的程序
        end;
    
        ZeroMemory(@StartupInfo, SizeOf(StartupInfo));
        StartupInfo.cb := SizeOf(StartupInfo);
    
        StartupInfo.lpDesktop := DesktopName; // 设置启动程序的虚拟桌面(注意:这个参数才真正让运行的程序隐藏起来)
        StartupInfo.dwFlags := STARTF_USESHOWWINDOW;
        StartupInfo.wShowWindow := SW_HIDE; // 常规的隐藏运行程序窗口参数
    
        // 创建要运行程序的进程(CREATE_NO_WINDOW是创建无窗口程序的参数)
        if not CreateProcess(nil, PChar(CmdLine), nil, nil, false, CREATE_NO_WINDOW,
          nil, WorkingDirP, StartupInfo, ProcessInfo) then
        begin
          isSuccess := false;
          ErrorCode := GetLastError;
        end;
    
        with ProcessInfo do
        begin
          CloseHandle(hThread);
          CloseHandle(hProcess);
        end;
    
      except
        on e: exception do
        begin
          isSuccess := false;
        end;
      end;
    
      result := isSuccess;
    end;

    Delphi示例代码:

    procedure TForm2.Button3Click(Sender: TObject);
    var
      FileName, Parameters: string;
    begin
    
      FileName := '要运行的程序,可以是图形界面也可以是DOS程序';
    
      Parameters :='要运行程序的参数,没有就空';
    
      if RunInbackGround(FileName, Parameters, DesktopName, desktopHandle) = true
      then
      begin
        showMessage('虚拟创建桌面完毕:' + IntToStr(desktopHandle));
        showMessage('指定程序已经运行:' + FileName);
      end
      else
      begin
        showMessage('虚拟创建失败,指定程序没能运行!');
      end;
    
    end;

    未完待续,后面会加入FreePascal实现的代码。。。

  • 相关阅读:
    想当老板的人,三点特征很重要(转)
    突破三个自我,你就不光是老板的料
    掌握这3套创业战略 保你赚到百万财富 
    也感山西黑窑洞
    再游府河有感
    朋友的影响力非常大,朋友决定你的财富
    夏日乘凉
    职业生涯的八大“定位法则”
    一生何求
    赠你一方明月
  • 原文地址:https://www.cnblogs.com/sunylat/p/13637426.html
Copyright © 2011-2022 走看看