Windows 10 发布后,微软终于在自家的操作系统里面内置了虚拟桌面功能,而这是 macOS 上早已标配的功能。

这个功能确实有很强的需求,在没有虚拟桌面之前,对于主力设备是 Windows 的我来说,经常要频繁切换浏览器、日历软件、任务管理软件、聊天软件和邮件客户端……的窗口。窗口之间的重合交叠让人感到「邋遢」和不爽:

可以用windows的SysinternalsSuite工具包里面的Desktops.exe进行虚拟桌面的创建:

虚拟桌面能干什么

每个虚拟桌面可以被看成是一个独立的工作空间(Workspace)。

每创建一个虚拟桌面,就像打开了一个新的工作空间。在新的空间中,你能够开启一套完全不同的任务,而不用担心和以前的任务窗口混杂陈列。

创建的每个桌面是相互隔离的,也就是说如果一个程序如果实在无法隐藏程序界面,可以单独创建一个桌面并将程序的界面Switch过去即可,这样就可以“偷偷”在后台工作了。当然我们在做windows本地桌面应用的时候也可以利用多桌面技术,比如可以开辟一个干净的“桌面”进行一些私密的工作(比如玩游戏),之后可以快速的切换回来假装什么都没做 :)

话不多说,下面是windows多桌面创建的代码:

// desktop.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"#include <string>
#include <Windows.h>
#include <wininet.h>
#include <shlobj.h>
#include <AclAPI.h>
#include <UserEnv.h>
#include <WtsApi32.h>
#include <Sddl.h>#define VIR_DESKTOP  L"VirDesktop"
#define SYSTEM_DEFAULT_DESKTOP  L"default"#define I_WALLPAPER_STYTLE_NO_CHANGE    -1
#define I_WALLPAPER_STYTLE_CENTER       0   //居中
#define I_WALLPAPER_STYTLE_TILE         1   //平铺
#define I_WALLPAPER_STYTLE_STRETCH      2   //拉伸bool set_desktop_picture(const std::wstring& str_img_path, int i_option, bool b_save)
{HRESULT hr = S_FALSE;hr = CoInitialize(NULL);bool b_inited_ok = false;if (hr == S_OK){b_inited_ok = true;}IActiveDesktop* pIAD = NULL;hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&pIAD);if (FAILED(hr)){if (b_inited_ok)CoUninitialize();return false;}hr = pIAD->SetWallpaper(str_img_path.c_str(), 0);if (FAILED(hr)){pIAD->Release();if (b_inited_ok)CoUninitialize();return false;}if (i_option > 0){WALLPAPEROPT wp = { 0 };wp.dwSize = sizeof(WALLPAPEROPT);wp.dwStyle = i_option;hr = pIAD->SetWallpaperOptions(&wp, 0);}if (b_save){hr = pIAD->ApplyChanges(AD_APPLY_ALL);}else{hr = pIAD->ApplyChanges(AD_APPLY_REFRESH);}if (FAILED(hr)){pIAD->Release();if (b_inited_ok)CoUninitialize();return false;}pIAD->Release();if (b_inited_ok)CoUninitialize();return true;
}bool set_desktop_picture(const std::wstring& str_img_path, std::wstring& str_old_img_path, int& i_old_option, int i_option, bool b_save)
{i_old_option = I_WALLPAPER_STYTLE_NO_CHANGE;str_old_img_path.clear();HRESULT hr = S_FALSE;bool b_inited_ok = false;hr = CoInitialize(NULL);if (hr == S_OK){b_inited_ok = true;}IActiveDesktop* pIAD = NULL;hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&pIAD);if (FAILED(hr)){if (b_inited_ok)CoUninitialize();return false;}wchar_t img[4096] = { 0 };hr = pIAD->GetWallpaper(img, 4096, AD_GETWP_LAST_APPLIED);if (FAILED(hr)){pIAD->Release();if (b_inited_ok)CoUninitialize();return false;}str_old_img_path = img;WALLPAPEROPT wp = { 0 };wp.dwSize = sizeof(WALLPAPEROPT);hr = pIAD->GetWallpaperOptions(&wp, 0);i_old_option = wp.dwStyle;hr = pIAD->SetWallpaper(str_img_path.c_str(), 0);if (i_option > 0){WALLPAPEROPT wp = { 0 };wp.dwSize = sizeof(WALLPAPEROPT);wp.dwStyle = i_option;hr = pIAD->SetWallpaperOptions(&wp, 0);}if (b_save){hr = pIAD->ApplyChanges(AD_APPLY_ALL);}else{hr = pIAD->ApplyChanges(AD_APPLY_REFRESH);}if (FAILED(hr)){pIAD->Release();if (b_inited_ok)CoUninitialize();return false;}pIAD->Release();if (b_inited_ok)CoUninitialize();//set_destop_picture_by_reg(str_img_path);return true;
}bool get_desktop_picture(std::wstring& str_img_path, int& i_option)
{i_option = I_WALLPAPER_STYTLE_NO_CHANGE;str_img_path.clear();HRESULT hr = S_FALSE;bool b_inited_ok = false;hr = CoInitialize(NULL);if (hr == S_OK){b_inited_ok = true;}IActiveDesktop* pIAD = NULL;hr = CoCreateInstance(CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, IID_IActiveDesktop, (void**)&pIAD);if (FAILED(hr)){if (b_inited_ok)CoUninitialize();return false;}wchar_t img[4096] = { 0 };hr = pIAD->GetWallpaper(img, 4096, AD_GETWP_LAST_APPLIED);if (FAILED(hr)){pIAD->Release();if (b_inited_ok)CoUninitialize();return false;}str_img_path = img;WALLPAPEROPT wp = { 0 };wp.dwSize = sizeof(WALLPAPEROPT);hr = pIAD->GetWallpaperOptions(&wp, 0);i_option = wp.dwStyle;pIAD->Release();if (b_inited_ok)CoUninitialize();return true;
}bool set_destop_picture_by_reg(const std::wstring& str_img_path, bool b_save)
{// Change the wallpaper.UINT ui = SPIF_SENDWININICHANGE;if (b_save){ui = ui | SPIF_UPDATEINIFILE;}SystemParametersInfo(SPI_SETDESKWALLPAPER, 0, (void*)str_img_path.c_str(), ui);return true;
}// bool  set_desktop_path(const std::wstring& str_path, std::wstring& str_old_path)
// {
//  QRegEdit reg;
//  str_old_path.clear();
//  if (reg.OpenDir(L"Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders", true, HKEY_CURRENT_USER, KEY_READ | KEY_WRITE))
//  {
//      reg.GetStr(L"Desktop", str_old_path);
//      return reg.SetStr(L"Desktop", str_path);
//  }
//
//  return false;
// }int create_desktop(const std::wstring& _str_desk_name)
{std::wstring str_desk_name = _str_desk_name;if (str_desk_name.empty()){str_desk_name = SYSTEM_DEFAULT_DESKTOP;}SECURITY_ATTRIBUTES attributes = { sizeof(SECURITY_ATTRIBUTES), 0, TRUE };HDESK hdesktop = OpenDesktopW(str_desk_name.c_str(), DF_ALLOWOTHERACCOUNTHOOK, TRUE, GENERIC_ALL);if (hdesktop == NULL){hdesktop = CreateDesktopW(str_desk_name.c_str(), NULL, NULL, 0, GENERIC_ALL, &attributes);if (hdesktop == NULL){return -1;}BOOL bRet = FALSE;PSECURITY_DESCRIPTOR SecDes = NULL;bRet = ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT("S:(ML;;NW;;;LW)"), SDDL_REVISION_1, &SecDes, NULL);if (bRet){BOOL bSaclDefaulted = FALSE;BOOL bSaclPresent = FALSE;PACL SecACL = NULL;bRet = GetSecurityDescriptorSacl(SecDes, &bSaclPresent, &SecACL, &bSaclDefaulted);if (bRet){SetSecurityInfo(hdesktop, SE_WINDOW_OBJECT, 0x10, NULL, NULL, NULL, SecACL);}}}CloseDesktop(hdesktop);return 0;
}int create_desktop_no_close(HDESK& hdesk_ret, const std::wstring& _str_desk_name)
{hdesk_ret = NULL;std::wstring str_desk_name = _str_desk_name;if (str_desk_name.empty()){str_desk_name = SYSTEM_DEFAULT_DESKTOP;}SECURITY_ATTRIBUTES attributes = { sizeof(SECURITY_ATTRIBUTES), 0, TRUE };HDESK hdesktop = OpenDesktopW(str_desk_name.c_str(), DF_ALLOWOTHERACCOUNTHOOK, TRUE, GENERIC_ALL);if (hdesktop == NULL){hdesktop = CreateDesktopW(str_desk_name.c_str(), NULL, NULL, 0, GENERIC_ALL, &attributes);if (hdesktop == NULL){return -1;}BOOL bRet = FALSE;PSECURITY_DESCRIPTOR SecDes = NULL;bRet = ConvertStringSecurityDescriptorToSecurityDescriptor(TEXT("S:(ML;;NW;;;LW)"), SDDL_REVISION_1, &SecDes, NULL);if (bRet){BOOL bSaclDefaulted = FALSE;BOOL bSaclPresent = FALSE;PACL SecACL = NULL;bRet = GetSecurityDescriptorSacl(SecDes, &bSaclPresent, &SecACL, &bSaclDefaulted);if (bRet){SetSecurityInfo(hdesktop, SE_WINDOW_OBJECT, 0x10, NULL, NULL, NULL, SecACL);}}}hdesk_ret = hdesktop;return 0;
}int change_to_desktop(const std::wstring& _str_desk_name)
{std::wstring str_desk_name = _str_desk_name;if (str_desk_name.empty()){str_desk_name = SYSTEM_DEFAULT_DESKTOP;}HDESK hdesktop = OpenDesktopW(str_desk_name.c_str(), DF_ALLOWOTHERACCOUNTHOOK, TRUE, GENERIC_ALL);if (hdesktop == NULL){create_desktop_no_close(hdesktop, str_desk_name);}if (hdesktop != NULL){if (SwitchDesktop(hdesktop)){CloseDesktop(hdesktop);return 0;}else{CloseDesktop(hdesktop);return -2;}}else{return -3;}return -4;
}int change_thread_to_desktop(const std::wstring& _str_desk_name)
{std::wstring str_desk_name = _str_desk_name;if (str_desk_name.empty()){str_desk_name = SYSTEM_DEFAULT_DESKTOP;}HDESK hdesktop = OpenDesktopW(str_desk_name.c_str(), DF_ALLOWOTHERACCOUNTHOOK, TRUE, GENERIC_ALL);if (hdesktop == NULL){create_desktop_no_close(hdesktop, str_desk_name);}if (hdesktop != NULL){if (SetThreadDesktop(hdesktop)){CloseDesktop(hdesktop);return 0;}else{CloseDesktop(hdesktop);return -2;}}return -3;
}int  run_exe(const std::wstring& str_img_path, const std::wstring& _str_desk_name)//str_desk_name为空表示切换到系统默认桌面
{std::wstring str_desk_name = _str_desk_name;if (str_desk_name.empty()){str_desk_name = SYSTEM_DEFAULT_DESKTOP;}HDESK hdesktop = OpenDesktopW(str_desk_name.c_str(), DF_ALLOWOTHERACCOUNTHOOK, TRUE, GENERIC_ALL);if (hdesktop == NULL){create_desktop_no_close(hdesktop, str_desk_name);}if (hdesktop != NULL){PROCESS_INFORMATION pInfo = { 0 };STARTUPINFO sInfo = { 0 };wchar_t name[1024] = { 0 };wcscpy_s(name, 1024, str_desk_name.c_str());sInfo.cb = sizeof(sInfo);sInfo.lpDesktop = name;sInfo.dwFlags = STARTF_USESHOWWINDOW;sInfo.wShowWindow = SW_SHOW;wchar_t cmd[2048] = { 0 };wcscpy_s(cmd, 2046, str_img_path.c_str());BOOL bRet = CreateProcess(NULL, cmd, NULL, NULL, TRUE,NULL, NULL, NULL, &sInfo, &pInfo);//MSDN上面说pszCurDir [in] Not supported; set to NULL,不然的话如果cmd参数传入多个参数,就会进程创建失败CloseDesktop(hdesktop);if (bRet == FALSE){return -2;}return 0;}return -3;
}

windows虚拟多桌面技术相关推荐

  1. windows虚拟多桌面常用软件调研

    适用于win7的软件有: Dexpot Shock4Way3D(我常用的是这种) Windows Sysinternals Desktops Yod'm 3D VirtuaWin

  2. 桌面虚拟云终端技术研究

    欢迎使用聚锐网出品的博客离线编辑及群发工具[×××] 云计算的应用有许多方面,我们可以举出iPhone.iPad.手机视频等云计算的具体应用,但是唯独最早带我们进入信息化时代的笔记本和台式机,我们却很 ...

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

    VMware发布Linux虚拟桌面技术预览版 在众多客户的一片呼吁声中,VMware在3月中旬发布了Linux虚拟桌面的技术预览版.从此,用户可以通过VMware Horizon View来建立.发布 ...

  4. windows虚拟桌面_在Windows中使用虚拟桌面的最佳免费程序

    windows虚拟桌面 If you often open a lot of applications at once, a virtual desktop program can help you ...

  5. windows虚拟桌面_如何在Windows 10中使用虚拟桌面

    windows虚拟桌面 Windows 10 finally added virtual desktops as a built-in feature. If you keep a lot of ap ...

  6. windows虚拟桌面_如何在Windows 10的新虚拟桌面中打开应用程序或文件

    windows虚拟桌面 Microsoft has finally added virtual desktops as a built-in feature to Windows 10. Virtua ...

  7. windows 10 win10 桌面窗口消失 任务栏图标消失 虚拟桌面 快速 隐藏 桌面程序 和 任务栏的图标

    https://superuser.com/questions/1075953/windows-10-how-to-hide-window-without-closing 在windows电脑上工作的 ...

  8. 桌面虚拟化中RDS、VDI、IDV、VOI主流的云桌面技术比较(转载)

    对于非技术人员来说,要搞清楚所有种类的云桌面,确实有点难度.况且网上铺天盖地都是商家做的软文,这时如果肚子里没点墨水,真的很容易被人忽悠.今天小微从方案原理.优缺点和市场趋势跟大家梳理一下目前市场上主 ...

  9. OpenStack虚拟云桌面在携程呼叫中心的应用

    声明:本文为CSDN原创投稿文章,未经许可,禁止任何形式的转载. 作者:刘科,携程系统研发云平台桌面虚拟架构师,多年从事分布式计算.通信系统平台设计.开发.本文为刘科在第六期[携程技术微分享]中的分享 ...

最新文章

  1. 定时任务 Cron表达式
  2. 灵活、高效的云原生集群管理经验:用 K8s 管理 K8s
  3. python去掉列表的括号和逗号_在每行之后显示没有逗号,括号等的python 2d...
  4. 查找这个接口的调用_事务处理不当,线上接口又双叒内存泄漏了!(附图解问题全过程)...
  5. mysql 定时器概念_MySQL 定时器
  6. java gif_使用Java来处理GIF图片
  7. Matplotlib - 饼图、环形图 pie() 多重饼图 subplots() 所有用法详解
  8. 我的世界基岩版json_(1.8.0.13+)我的世界Minecraft【BE】基岩版 /function 使用教程
  9. Oracle解锁scott账号
  10. 说出来你可能不信,谷歌一年要给苹果交200亿保护费。
  11. Cards and Joy CodeForces - 999F (贪心+set)
  12. pytorch学习笔记(十九):二维卷积层
  13. pdf转图片,汉字不显示No glyph for 23495(CID 0969) in font SimSun
  14. Pycharm使用小Tips
  15. python发邮件被认定为垃圾邮件_【Python】垃圾邮件识别
  16. python操作txt找到最便宜的素菜_Python線性模型學習筆記
  17. UG NX二次开发(C#)-装配-删除阵列矩阵
  18. 11 Daemonset:忠实可靠的看门狗
  19. CSS 列表样式 (ul)
  20. 上网行为管理agent(开源产品deskvideosys代理)

热门文章

  1. 【.NET 基础】——CLR、BCL、DLL、Assembly
  2. 限制文本框输入的内容
  3. TTL电平、CMOS电平的区别
  4. android 自定义照相机
  5. Java Iterator 详解
  6. 读余秀华《摇摇晃晃的人间》
  7. Java 多组时间取交集、并集、合并
  8. 人脸识别在opencv下作人脸检测
  9. LeetCode笔记:Biweekly Contest 55(补发)
  10. 阿里巴巴校园招聘内推C++研发岗位电话面试