windows虚拟多桌面技术
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虚拟多桌面技术相关推荐
- windows虚拟多桌面常用软件调研
适用于win7的软件有: Dexpot Shock4Way3D(我常用的是这种) Windows Sysinternals Desktops Yod'm 3D VirtuaWin
- 桌面虚拟云终端技术研究
欢迎使用聚锐网出品的博客离线编辑及群发工具[×××] 云计算的应用有许多方面,我们可以举出iPhone.iPad.手机视频等云计算的具体应用,但是唯独最早带我们进入信息化时代的笔记本和台式机,我们却很 ...
- VMware发布Linux虚拟桌面技术预览版
VMware发布Linux虚拟桌面技术预览版 在众多客户的一片呼吁声中,VMware在3月中旬发布了Linux虚拟桌面的技术预览版.从此,用户可以通过VMware Horizon View来建立.发布 ...
- windows虚拟桌面_在Windows中使用虚拟桌面的最佳免费程序
windows虚拟桌面 If you often open a lot of applications at once, a virtual desktop program can help you ...
- windows虚拟桌面_如何在Windows 10中使用虚拟桌面
windows虚拟桌面 Windows 10 finally added virtual desktops as a built-in feature. If you keep a lot of ap ...
- windows虚拟桌面_如何在Windows 10的新虚拟桌面中打开应用程序或文件
windows虚拟桌面 Microsoft has finally added virtual desktops as a built-in feature to Windows 10. Virtua ...
- windows 10 win10 桌面窗口消失 任务栏图标消失 虚拟桌面 快速 隐藏 桌面程序 和 任务栏的图标
https://superuser.com/questions/1075953/windows-10-how-to-hide-window-without-closing 在windows电脑上工作的 ...
- 桌面虚拟化中RDS、VDI、IDV、VOI主流的云桌面技术比较(转载)
对于非技术人员来说,要搞清楚所有种类的云桌面,确实有点难度.况且网上铺天盖地都是商家做的软文,这时如果肚子里没点墨水,真的很容易被人忽悠.今天小微从方案原理.优缺点和市场趋势跟大家梳理一下目前市场上主 ...
- OpenStack虚拟云桌面在携程呼叫中心的应用
声明:本文为CSDN原创投稿文章,未经许可,禁止任何形式的转载. 作者:刘科,携程系统研发云平台桌面虚拟架构师,多年从事分布式计算.通信系统平台设计.开发.本文为刘科在第六期[携程技术微分享]中的分享 ...
最新文章
- 定时任务 Cron表达式
- 灵活、高效的云原生集群管理经验:用 K8s 管理 K8s
- python去掉列表的括号和逗号_在每行之后显示没有逗号,括号等的python 2d...
- 查找这个接口的调用_事务处理不当,线上接口又双叒内存泄漏了!(附图解问题全过程)...
- mysql 定时器概念_MySQL 定时器
- java gif_使用Java来处理GIF图片
- Matplotlib - 饼图、环形图 pie() 多重饼图 subplots() 所有用法详解
- 我的世界基岩版json_(1.8.0.13+)我的世界Minecraft【BE】基岩版 /function 使用教程
- Oracle解锁scott账号
- 说出来你可能不信,谷歌一年要给苹果交200亿保护费。
- Cards and Joy CodeForces - 999F (贪心+set)
- pytorch学习笔记(十九):二维卷积层
- pdf转图片,汉字不显示No glyph for 23495(CID 0969) in font SimSun
- Pycharm使用小Tips
- python发邮件被认定为垃圾邮件_【Python】垃圾邮件识别
- python操作txt找到最便宜的素菜_Python線性模型學習筆記
- UG NX二次开发(C#)-装配-删除阵列矩阵
- 11 Daemonset:忠实可靠的看门狗
- CSS 列表样式 (ul)
- 上网行为管理agent(开源产品deskvideosys代理)