虚拟桌面技术的初步探讨

【文章标题】: 虚拟桌面技术的初步探讨  
【文章作者】:  newjueqi  
【作者邮箱】: [email protected]
【作者QQ号】: 190678908
【编写语言】:VC++6.0
【操作平台】: XP-SP2
【作者声明】:感觉到这是一种非常有意思的技术,这篇就当成是学习笔记吧!本人只是感兴趣,没有其它目的,失误之处敬请给位大侠原谅!

本文曾发表于看学论坛http://bbs.pediy.com/showthread.PHP?t=82537
                       壳狂http://www.unpack.cn/viewthread.php?tid=32988

什么是桌面?
      每一个运行着Window NT 的系统中都有一个Window 工作站对象,这个对象是安全对象的第一层,是所有用户安全对象的继承之源,每一个Window 工作站对象可以拥有一些桌面对象,每一个桌面都拥有一个窗口链。窗口链里存放着显示在所属桌面的各种窗口。Window NT 用了两个桌面窗口对象,一个是用来处理登陆界面、屏蔽、锁住工作站等,一个是我们登陆之后进来操作的窗口了。 
    Window NT通过"explorer.exe"进程来管理这个桌面对象。这就是为什么我们在任务管理器里杀掉"explorer.exe",我们的桌面就会消失的原因。

什么是虚拟桌面?
     虚拟桌面是一种可以在电脑原来桌面基础上再创造一个新的桌面出来,在新的桌面上可以进行日常的操作。

虚拟桌面的用途?
(1)  本人觉得这门技术最重要的用途就是可以把任何有UI界面的软件变成一个后台软件(即看不到任何界面,包括启动界面)
(2)  可以时工作时是一个桌面,娱乐时是一个桌面(大家可以去下载网站上搜索一下这类软件的用途,上面的功能描述非常有意思)

虚拟桌面的实现方法
在windows中,要创建一下新的桌面可用到API:CreateDesktop(),函数声明如下
HDESK CreateDesktop(
  LPCTSTR lpszDesktop,         // 新桌面的名称
  LPCTSTR lpszDevice,          // 为NULL
  LPDEVMODE pDevmode,          // 为NULL
  DWORD dwFlags,               // 指定应用程序在桌面的兼容方式
  ACCESS_MASK dwDesiredAccess, // 指定新桌面的权限
  LPSECURITY_ATTRIBUTES lpsa   //指定句柄是否能被继承
);

返回值是新创建的桌面的句柄。

那么新建了一个桌面后,怎么在这个新的桌面上运行程序呢?先不要着急,我们先来回顾一下创建进程的函数CreateProcess(),在这个函数的参数中StartupInfo中有 lpDesktop这么一个属性,如果这个属性为NULL则在当前的桌面创建线程,如果指定了桌面的名称,则进程将会在指定的桌面上启动,所以想在创建的新桌面里初始化一些程序,只要把lpDesktop参数指定为新桌面的名称即可。

另外也有一个简单的方法可把新的线程挂在新创建的桌面下,就是使用API函数SetThreadDesktop(),声明如下:
BOOL SetThreadDesktop(
  HDESK hDesktop  // 指向指定的桌面句柄
);

但使用这个函数要注意一点,根据MSDN的说法: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)  意思就是除非要指定的桌面句柄是当前的桌面,不然的话这个函数的调用会失败如果当前线程拥有任何的窗口(即UI界面).

怎么实现不同桌面之间的切换呢?
     要在不同的桌面之间切换,可用API函数SwitchDesktop,声明如下:
BOOL SwitchDesktop(
  HDESK hDesktop  // 桌面的句柄
);

另外也可通过点击“切换”按钮实现桌面的切换。

但又引申出一个新的问题,必须要知道各个桌面的句柄,获取桌面的句柄可通过API函数GetThreadDesktop,函数的声明如下:
HDESK GetThreadDesktop(
  DWORD dwThreadId   //线程的ID);

返回值就是指定线程所在的桌面了。
    而且我们必须要认清的是创建新桌面的线程启动是在旧的桌面上,所以可以用下面的语句轻松获得当前桌面的句柄:
GetThreadDesktop(GetCurrentThreadId());   
返回值就是旧的桌面句柄。

怎么关闭新创建的桌面?
     这个问题其实也不用我们担心,微软已经替我们想好了^-^ , 用CloseDesktop函数可轻松实现这个功能,函数声明如下:
    BOOL CloseDesktop(
  HDESK hDesktop  // 指定要关闭的桌面的句柄
);

下面贴一段代码的例子,是在新创建的桌面上运行计算器(calc.exe)实现计算器的后台运行

#include <windows.h>

HINSTANCE hInst;  //当前的实例句柄
HWND hWnd;        //窗口句柄
HDESK hvirtualDesk;    //新创建的虚拟桌面句柄
PROCESS_INFORMATION pi; //计算器进程信息

//消息循环
LRESULT CALLBACK WinProc(
      HWND hwnd,      // handle to window
      UINT uMsg,      // message identifier
      WPARAM wParam,  // first message parameter
      LPARAM lParam   // second message parameter
              )
{
  switch(uMsg)
  {
  case WM_CLOSE:
      TerminateProcess( pi.hProcess, 1 );
      CloseDesktop( hvirtualDesk );
      DestroyWindow(hwnd);
      PostQuitMessage(0);
      break;

case WM_DESTROY:

CloseDesktop( hvirtualDesk );
      PostQuitMessage(0);
      break;

case WM_HOTKEY:

if ( 0x0001 == wParam ) //为退出桌面热键Alt+Q
    {
            SendMessage(hwnd,WM_CLOSE,0,0);    
    }
    break;

default:
    return DefWindowProc(hwnd,uMsg,wParam,lParam);
  }
  return 0;
}

//创建虚拟桌面
void CrateVirtualDesk()
{
  //把新创建的虚拟桌面句柄存放在hvirtualDesk
  hvirtualDesk=CreateDesktop( "newdesk",
                NULL,
                NULL,
                DF_ALLOWOTHERACCOUNTHOOK,   
                GENERIC_ALL,     
                NULL);

}

//在虚拟桌面上运行一个计算器的实例
void RunCalc()
{
  STARTUPINFO si;   
  
  ZeroMemory( &si, sizeof(si) );  
  si.cb = sizeof(si);   
    si.lpDesktop = "newdesk";   
  
  ZeroMemory( &pi, sizeof(pi) );   
  
  if( !CreateProcess( NULL,                   
    "calc",                                       
    NULL,                       
    NULL,                      
    FALSE,                      
    0,                      
    NULL,                          
    NULL,                      
    &si,                       
    &pi ) )      
  {     
    MessageBox(NULL,"运行计算器失败","Error",0);     
    ExitProcess(1);     
  }

}

int WINAPI WinMain(
    HINSTANCE hInstance,      // handle to current instance
    HINSTANCE hPrevInstance,  // handle to previous instance
    LPSTR lpCmdLine,          // command line
     int nCmdShow              // show state
           )
{
  WNDCLASS wndcls;
  MSG msg;

hInst=hInstance;
  ZeroMemory( &wndcls,sizeof(wndcls) );
  wndcls.cbClsExtra=0;
  wndcls.cbWndExtra=0;
  wndcls.hbrBackground=(HBRUSH)GetStockObject(BLACK_BRUSH);
  wndcls.hInstance=hInstance;
  wndcls.lpfnWndProc=WinProc;
  wndcls.lpszClassName="hello";
  wndcls.lpszMenuName=NULL;
  wndcls.style=CS_HREDRAW | CS_VREDRAW;
  RegisterClass(&wndcls);
  
  hWnd=CreateWindow( "hello","hello",WS_OVERLAPPEDWINDOW,
    300,300,100,100,NULL,NULL,hInstance,NULL );
  
  //注册所需的热键,Alt+Q为退出创建的虚拟桌面
  if( !RegisterHotKey( hWnd,0x0001,MOD_ALT ,‘Q‘ ) )     
    {     
        //处理退出进程     
        return TRUE;     
    }

//创建虚拟桌面
  CrateVirtualDesk();
  
  //在虚拟桌面上运行一个计算器的实例
  RunCalc();

ShowWindow( hWnd,SW_SHOWNORMAL );
  UpdateWindow( hWnd );
  
  while( GetMessage( &msg,NULL,0,0 ) )
  {
    TranslateMessage(&msg);
    DispatchMessage(&msg);
  }

return msg.wParam;
}

程序运行后如下图

红框的virtualDesktop.exe就是代码创建的程序,calc.exe就是计算器的进程,大家可以看一下任务栏,是没有计算器的影踪的,证明是运行在另一个桌面上,从另一个角度来看,就是运行在后台(只要不切换到另一桌面)。

http://blog.csdn.net/newjueqi/article/details/4144544

时间: 2024-11-24 10:30:45

虚拟桌面技术的初步探讨的相关文章

VMware发布Linux虚拟桌面技术预览版

VMware发布Linux虚拟桌面技术预览版 在众多客户的一片呼吁声中,VMware在3月中旬发布了Linux虚拟桌面的技术预览版.从此,用户可以通过VMware Horizon View来建立.发布并管理Linux虚拟桌面了.抢鲜尝试连接: http://www.surveymethods.com/EndUser.aspx?DFFB978FDE988B88D4 (注意:如果直接点击上面的连接出错,可将其拷贝到浏览器里再打开) 本篇博客将讨论以下三点: 一.    VMware Linux虚拟桌

使用vRealize Operations for Horizon,做高效的虚拟桌面系统管理员

目前越来越多的企业开始采用虚拟桌面技术来降低企业IT系统的TCO(总拥有成本),VMware Horizon View作为业界领先的虚拟桌面产品开始被市场接受和欢迎.实施了虚拟桌面系统后,可以全面降低对IT硬软件采购/实施/维护方面的压力和预算,CIO自然很是高兴--提高整个企业的业务系统管理水平,增强办公移动化能力,同时保证很好的终端用户体验.随着企业员工规模和业务复杂度的增长,虚拟化桌面的需求数量也在不断增加.在运维方面,如何很好的监控虚拟桌面系统的整体性能和单个桌面的利用率,如何快速定位系

笔记本和Ipad访问虚拟桌面登录速度差异性的问题探讨

之前在某项目上遇见一个现象: 一个联通的无线上网设备作为最终的上行出口,使用有线从无线设备接入一台笔记本,使用WIFI接入一部Ipad,然后通过公网访问Citrix XenDesktop的虚拟桌面: 发现通过笔记本访问虚拟桌面登录的速度大约在半分钟.运行的流畅度差不多和在局域网内使用的相差不大: 通过Ipad访问虚拟桌面,其登录的速度很慢,加载桌面启动画面和加载用户配置都有很长的时间,整个登录速度大约在2分钟左右. 值得讨论的是: 为什么同样是使用该台无线设备,其有线连接的笔记本和使用WIFI连

云计算和大数据时代网络技术揭秘(十四)虚拟桌面

云计算应用——虚拟桌面 Virtual Desktop Infrastructure是一种基于服务器的计算模型,VDI概念最早由VMware提出,目前已经成为标准的技术术语. 使用虚拟桌面可以在数据中心对资源进行统一管理,同时保证用户获得完整PC的使用体验.目前延迟是影响其发展的最大问题. 图 虚拟桌面示意图

虚拟桌面发展的下一个里程碑,构建在CWC之上的软件定义工作空间

1969年7月20日,当阿波罗-11号宇宙飞船的航天员阿姆斯特朗率踏上月球那荒凉而沉寂的土地时,他说出了此后在无数场合常被引用的名言:"这是个人迈出的一小步,但却是人类迈出的一大步." 在桌面虚拟化领域,同样也有那么一些时候能被我们所铭记,也会被载入史册.例如1989年Citrix公司开创的ICA协议,例如1995年Citrix协助微软开发了第一个多用户版本的Windows Server操作系统(NT4.0)并延续至今,2000年全世界第一款桌面虚拟化软件面世等.今天,在桌面虚拟化领域

虚拟桌面安全策略:网络隔离方案

在传统的桌面方案中网络隔离方面大多使用物理隔离(如隔离卡方案.双PC模式)以及逻辑隔离(如基于ACL/VLAN的网络策略)来实现网络的隔离. 此外也可以借此如网络准入操作简称NAC的方式来实现网络的逻辑隔离NAC的方式支持多种模式 基于802.1x(与网络交换机联动当发现用户终端不符合安全策略时将用户终端隔离到特定VLAN). 基于网关模式的NAC(如VPN模式当NAC设备放在用户需要访问的服务器的前端如公司内网门户用户访问后端服务时客户的流量因为需要经过NAC设备所以可以强制用户的设备做安全检

虚拟桌面 VDI

什么是VDI(Virtual Desktop Infrastructure): 通过对于本企业的服务器进行整合,使用VMware进行虚拟机部署,利用服务器资源,实现由一个物理机实现多个虚拟机,解决资源浪费. Vmware VDI的优势源自于 VMware 服务器虚拟化的成功及其对 IT 的业经验证的优势.在 VDI 中,ESX Server 包含的不是一系列虚拟服务器,而是虚拟桌面,每个 VM 都是使用用户的操作系统和应用程序载入或动态供应的.它拥有熟悉的用户体验.这是一个VMware的解决方案

通过NSX和AppVolumes部署基于角色的安全虚拟桌面

随着"互联网+"的概念普及,越来越多的数据中心如雨后春笋般冒了出来,桌面和应用虚拟化因其可将操作系统.应用和数据置于数据中心的特点,也迅速在各种规模的企业中大行其道.虚拟化后,可以减少因设备丢失或损坏造成的数据丢失,减少设备上安装的敏感应用被他人访问,有助于高效.集中备份和漏洞修补.在财务部工作的Eva不需要再忍受脚下传统PC吵杂的风扇声和不定期的宕机,可以更加高效地工作.然而随着公司规模的扩大,部门越来越多,不同部门的业务人员要求定制化的桌面和应用的呼声越来越高,于是虚拟桌面管理员L

Windows 10体验:虚拟桌面任务栏变化

在当前桌面开启应用,对应在任务栏中的图标也会是点选状态. 但是Windows 10 技术预览版中,增加了Task View(虚拟桌面),如果在其他桌面中已经打开的应用,怎样通知用户呢,新Windows用了一种下沉式的点选状态,表示该应用已经在其他虚拟桌面打开了,这的确是个不错的方式.