delphi 使用CreateDesktop时出现灰色屏幕,未显示任务栏或图标

wkyowqbh  于 2022-11-04  发布在  其他
关注(0)|答案(1)|浏览(270)

我正在开发一个创建新桌面的应用程序,我希望这个桌面是可用的,比如有图标、任务栏......为此,我使用了CreateDesktop()函数,但新创建的桌面只是一个灰色屏幕。即使在那个桌面上执行explorer.exe,它也不起作用,仍然有一个灰色屏幕,如下所示:

(我还想,如果我试图用资源管理器打开一个文件,该文件不是在新桌面中打开的,而是在旧桌面中打开的)
我使用了这个GitHub项目,它是用C++编写的,并在 Delphi 中进行了修改:
https://github.com/MalwareTech/CreateDesktop/
这是我的代码:

function CreateHiddenDesktop(desktopname : string) : THandle;
var
  pi : TProcessInformation;
  si : TStartupInfoA;
  hidden_Desktop,original_desktop : THandle;
begin
  //Creating a new desktop
  hidden_Desktop := CreateDesktop('hdtest',nil,nil,0,GENERIC_ALL,nil);
  //Saving handle of current desktop
  original_desktop := GetThreadDesktop(GetCurrentThreadID());

  SetThreadDesktop(hidden_desktop);

  //Executing explorer.exe in the new desktop
  si := Default(TStartupInfoA);
  si.cb := sizeof(si);
  si.lpDesktop := 'hdtest';

  if not CreateProcessA(
        'C:\Windows\System32\explorer.exe',         
        nil, 
        nil,                
        nil,               
        False,
        0,
        nil,                
        nil,        
        si,                 //Startup Info
        pi                 //Process Info
  ) then
    MessageBox(0, PChar('error when creating process inside the desktop'), PChar(''), 0);

  SetThreadDesktop(original_desktop);

  Result := hidden_desktop;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  hidden_Desktop,original_desktop : THandle;
  msg : TMSG;
begin
  hidden_Desktop := CreateHiddenDesktop('hdtest');
  original_desktop := GetThreadDesktop(GetCurrentThreadId());

  MessageBox(0, PChar('Entering hidden desktop'), PChar('HVNC'), 0);

  SetThreadDesktop(hidden_desktop);
  SwitchDesktop(hidden_desktop);

  //If the keys CTR + ALT + E are pressed we go back to the original desktop
  if RegisterHotKey(0,1,MOD_CONTROL + MOD_ALT + MOD_NOREPEAT,ord('E')) then
  begin
    while(GetMessage(msg, 0, 0, 0)) do
    begin
      if msg.message = WM_HOTKEY then
      begin
        SwitchDesktop(original_desktop);
        break;
      end;
    end;
  end;

  CloseHandle(hidden_desktop);
end;
mwkjh3gx

mwkjh3gx1#

因此,我找到的解决方案是,当使用SetThreadDesktop()时,我需要先创建另一个线程,因为我的应用程序有一个GUI。
事实证明,这是因为 Delphi 应用程序是作为Admnistrator执行的。当我在用户上下文中执行它时,它工作了。
我在这上面浪费了好几天的时间...

相关问题