原文 Windows 7 taskbar and startmenu pin

在Windows 7上,用户可以将自己喜欢的软件“钉”在开始菜单或任务栏,使用起来更加方便。但有时候我们也需要用程序来将这个过程自动化,比如在IT环境里定制客户机,或者我们从一台Win7系统迁移到另一台Win7系统时。

怎么知道已有哪些软件被“钉”在开始菜单或任务栏:

当软件“钉”在开始菜单或任务栏后,系统会在"%appdata%\microsoft\internet explorer\Quick Launch\User Pinned"下的"StartMenu"和"TaskBar"目录内创建软件的链接。我们只要看这两个目录下分别有哪些有效链接就可以知道开始菜单和任务栏分别钉有哪些软件。对于每一个链接,我们可以知道它链接了那个程序,然后在目标系统上,我们就可以将这个程序钉在开始菜单或任务栏上(目标系统上也要有这个程序)。

如何把软件“钉”在开始菜单或任务栏:

需要注意的是只能将链接钉在开始菜单或任务栏,而且链接必须指向可执行程序,所以我们需要先为目标程序创建一个链接,然后调用ShellExecute,将链接钉住,钉完后这个链接可以删掉。任务栏上钉与解除时传递给ShellExecute的lpOperation参数是taskbarpin/taskbarunpin,而开始菜单的lpOperation参数是startpin/startunpin。

示例,将IE钉在任务栏上:

1. 在桌面上为IE创建链接IE.lnk

2. ShellExecute(NULL, "taskbarpin", "c:\users\username\Desktop\IE.lnk", NULL, NULL, 0)

以上有一个限制,就是不知道在任务栏上链接的顺序。

Windows XP 任务栏的遍历

2009-05-04 9:26

这里的方法可以找到XP下的任务栏,并对任务栏进行遍历,在其他系统上就需要相应的改动了。这里是先找到ToolbarWindow32这个窗口,然后再用通用的遍历Toolbar的方法查找各个按钮;这里有一点特别的是,要用到跨进程缓冲区(因为任务栏和遍历程序不是在同一个进程)。 
    在XP下有一个“分组相似任务栏按钮”特性,如果有一个新的进程窗口要在任务栏上显示,则系统会创建两个按钮,一个按钮有BTNS_DROPDOWN style,默认隐藏,在任务分组后显示(这个style指定它显示一个箭头图标);另一个按钮就是通常我们看到的任务栏按钮。 
    struct TBBUTTONDATA是从网上找到的,没有在微软的文档中发现,但在XP上验证是有效的。 
    在遍历按钮,SendMessage的时候,要注意是Zero-based index 还是 Command ID,现在一些网上的资料范例在需要传Command ID的时候传Zero-based index做参数,这是错误的。 
HWND GetTaskButtonHost(HWND hShellTrayWnd) 

    HWND hWnd = FindWindowEx(hShellTrayWnd, NULL, _T("ReBarWindow32"), NULL); 
    if (hWnd == NULL) 
        return FALSE; 
    hWnd = FindWindowEx(hWnd, NULL, _T("MSTaskSwWClass"), NULL); 
    if (hWnd == NULL) 
        return FALSE; 
    hWnd = FindWindowEx(hWnd, NULL, _T("ToolbarWindow32"), NULL); 
    return hWnd; 

//MSDN: To continue enumeration, the callback function must return TRUE; to stop enumeration, it must return FALSE. 
BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 

    TCHAR strClsName[MAX_PATH+1] = _T(""); 
    GetClassName(hwnd, strClsName, MAX_PATH+1); 
    if (_tcsicmp(strClsName, _T("Shell_TrayWnd")) == 0) 
    { 
        HWND hShellTrayWnd = GetTaskButtonHost(hwnd); 
        if (hShellTrayWnd) 
        { 
            HWND *pHwnd = (HWND *)lParam; 
            *pHwnd = hShellTrayWnd; 
            return FALSE; 
        } 
    } 
    return TRUE; 

struct TBBUTTONDATA 

    HWND hwnd; //the handle of the window on the taskbar 
    UINT uID; 
    UINT uCallbackMessage; 
    DWORD Reserved[2]; 
    HICON hIcon; 
}; 
//This solution works on XP. 
void EnumTasks() 

    HWND hWnd = NULL; 
    EnumWindows(EnumWindowsProc, (LPARAM)&hWnd); 
    if (hWnd == NULL) 
        return; 
    DWORD dwProcID = 0; 
    GetWindowThreadProcessId(hWnd, &dwProcID); 
    HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE, FALSE, dwProcID); 
    if (hProcess == NULL) 
        return; 
    LPTSTR pProcBuf = NULL; //pointer to the buffer allocated in another process 
    TBBUTTON tbb; 
    TBBUTTONDATA tbbData; 
    TCHAR strCaption[MAX_PATH+1] = _T(""); 
    pProcBuf = (LPTSTR)VirtualAllocEx(hProcess, NULL, sizeof(strCaption), MEM_COMMIT, PAGE_READWRITE); 
    if (pProcBuf == NULL) 
    { 
        CloseHandle(hProcess); 
        return; 
    } 
    DWORD nTaskCount = ::SendMessage(hWnd, TB_BUTTONCOUNT, 0, 0); 
    for (DWORD i = 0; i < nTaskCount; i++) 
    { 
        ZeroMemory(&tbb, sizeof(TBBUTTON)); 
        WriteProcessMemory(hProcess, pProcBuf, &tbb, sizeof(TBBUTTON), NULL); 
        SendMessage(hWnd, TB_GETBUTTON, i/*Zero-based index*/, (LPARAM)pProcBuf); 
        ReadProcessMemory(hProcess, pProcBuf, &tbb, sizeof(TBBUTTON), NULL); 
        //Group similar task-bar buttons(a feature of Windows): if the top-level window is 
        //shown on task-bar, Windows will create another dropdown button for each process. 
        if (tbb.fsStyle & BTNS_DROPDOWN) 
            continue; 
        ReadProcessMemory(hProcess, (LPCVOID)tbb.dwData, &tbbData, sizeof(TBBUTTONDATA), NULL); 
        DWORD nDesireLen = SendMessage(hWnd, TB_GETBUTTONTEXT, tbb.idCommand, 0); //length not including null terminator 
        if (nDesireLen >= sizeof(strCaption)) 
            continue; 
        ZeroMemory(strCaption, sizeof(strCaption)); 
        WriteProcessMemory(hProcess, pProcBuf, strCaption, sizeof(strCaption), NULL); 
        SendMessage(hWnd, TB_GETBUTTONTEXT, tbb.idCommand, (LPARAM)pProcBuf); 
        ReadProcessMemory(hProcess, pProcBuf, strCaption, sizeof(strCaption), NULL); 
        OutputDebugInfo(L"%s\n", strCaption); 
    } 
    VirtualFreeEx(hProcess, pProcBuf, 0, MEM_RELEASE); 
    CloseHandle(hProcess); 
}

前一篇Windows XP 任务栏的遍历介绍了在XP下遍历任务栏的方法,可以精确遍历出任务栏的按钮;这篇博客介绍一种通用的遍历任务栏的方法(不仅限于XP),但可能结果不是太精确。 
对于什么样的窗口才会在任务栏上创建按钮,MSDN上的说法是:

The Shell creates a button on the taskbar whenever an application creates a window that isn't owned. To ensure that the window button is placed on the taskbar, create an unowned window with the WS_EX_APPWINDOW extended style. To prevent the window button from being placed on the taskbar, create the unowned window with the WS_EX_TOOLWINDOW extended style. As an alternative, you can create a hidden window and make this hidden window the owner of your visible window.

做了一些测试,总结的结果是:

1、如果窗口没有被其他窗口拥有(GetWindow(hwnd, GW_OWNER) == 0),那么默认情况下它会在任务栏中创建按钮,除非:

a). 窗口被隐藏了

或者:

b). 窗口有WS_EX_TOOLWINDOW风格,且没有WS_EX_APPWINDOW风格

2、如果窗口被其他窗口拥有,默认不会在任务栏创建按钮,除非:

a). 窗口可见,且有WS_EX_APPWINDOW风格

从1、2点可以得出结论,如果窗口可见,有WS_EX_APPWINDOW和WS_EX_TOOLWINDOW风格,那么,这个窗口是一个Tool window,且在任务栏上有按钮。

范例:

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) 

    LONG lExStyle = ::GetWindowLong(hwnd, GWL_EXSTYLE); 
    if (::IsWindowVisible(hwnd) && 
        ( (lExStyle & WS_EX_APPWINDOW) || 
          (GetWindow(hwnd, GW_OWNER) == NULL && (lExStyle & WS_EX_TOOLWINDOW) == 0) ) 
        ) 
    { 
        TCHAR strTitle[MAX_PATH+1] = _T(""); 
        GetWindowText(hwnd, strTitle, MAX_PATH+1); 
        OutputDebugInfo(L"%s\n", strTitle); 
    } 
    return TRUE; 

EnumWindows(EnumWindowsProc, NULL);

Vista UAC : 以管理员权限运行程序

2009-04-25 20:21

在Windows Vista启用UAC后,程序启动后默认没有管理员权限,

即使当前的用户属于管理员组。如果要使程序获得管理员权限,还需要一些额外的工作。可以从两个角度来看待: 
一、从程序用户的角度: 
1、用鼠标右击某个应用程序(例如cmd.exe), 再选择"Run As Administrator"(在旧版本里是"Run Elevated")来以管理员权限运行它 
2、在程序(或其快捷方式)的属性Compatibility中选择Run this program as an administrator来运行 
3、在程序的安装目录,添加一个Manifest文件,使程序以管理员权限运行 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0"> 
<trustinfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
<security> 
<requestedprivileges> 
<requestedexecutionlevel level="requireAdministrator" uiaccess="false"> 
</requestedexecutionlevel> 
</requestedprivileges> 
</security> 
</trustinfo> 
4、有编程经验的用户也可以写脚本来运行程序,如: 
objShell = new ActiveXObject("Shell.Application"); 
objShell.ShellExecute(app, args, "", "runas"); 
C#示例: 
ProcessStartInfo startInfo = new ProcessStartInfo(); 
startInfo.FileName = "cmd.exe"; 
startInfo.Arguments = "/c c:\\test\\script.cmd"; 
startInfo.UseShellExecute = true; 
startInfo.Verb = "RunAs"; 
Process process = new Process(); 
process.StartInfo = startInfo; 
process.Start();

C/C++, 可调用ShellExecute或ShellExecuteEx, 把lpOperation/lpVerb设成"RunAs"就可以

二、从开发人员角度: 
1、在应用程序RC中加入MANIFEST类型资源. 
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestversion="1.0"> 
<trustinfo xmlns="urn:schemas-microsoft-com:asm.v3"> 
<security> 
<requestedprivileges> 
<requestedexecutionlevel level="requireAdministrator" uiaccess="false"> 
</requestedexecutionlevel> 
</requestedprivileges> 
</security> 
</trustinfo> 
2、以上几种方法都使得程序刚运行就要求管理员权限,要在程序运行中动态要求管理员权限则可以使用COM Elevation Moniker。可参考:http://msdn2.microsoft.com/en-us/library/ms679687.aspx

Windows 7 taskbar and startmenu pin的更多相关文章

  1. Change the Windows 7 Taskbar Thumbnail and List Mode

    Manually in Registry Editor 1. Open the Start Menu, then type regedit in the search boxand press Ent ...

  2. Scott Hanselman's 2014 Ultimate Developer and Power Users Tool List for Windows -摘自网络

    Everyone collects utilities, and most folks have a list of a few that they feel are indispensable.  ...

  3. Windows 7 Shortcuts (完整兼具分类有序,想我所想,赞!)

    Original Link: http://www.shortcutworld.com/en/win/Windows_7.html Table of Contents: Managing 'Windo ...

  4. Windows Server 2008 R2 小技巧 (转)

    一些 Windows Server 2008 R2 的小技巧,包括启用「God Mode (上帝模式)」.添加「快速启动」工具栏.启用桌面「个性化」服务.停用「密碼複雜性」要求,对老程序员熟悉新版的 ...

  5. .net Framework Class Library(FCL)

    from:http://msdn.microsoft.com/en-us/library/ms229335.aspx 我们平时在VS.net里引用的那些类库就是从这里来的 The .NET Frame ...

  6. win7下Chrome有两个图标的解决方法

    摘抄自:http://www.sevenforums.com/browsers-mail/238406-windows-7-taskbar-creating-double-google-chrome- ...

  7. 卸载oracle删除注册表脚本

    一.前言 在我们操作系统中,有时要卸载oracle数据库,每一次都要去删除win下的注册表,为了方便删除注册表的信息,下面通过一种删除注册表快捷的脚本. 二.脚本信息 Windows Registry ...

  8. MFC程序运行流程

    ->进入入口函数_tWinMain() 程序首先进入文件AppModul.cpp,找到_tWinMain()函数运行,调用其中的AfxWinMain()函数. 由于为了支持UNICODE,C运行 ...

  9. Oracle11g的注册表清理

    每次卸载了oracle总是有一堆注册表没有清理,麻烦,特地在网上找了一个较为完整的,全文复制过来,存自己这里,如下: <<< Windows Registry Editor Vers ...

随机推荐

  1. ubuntu ~/.bash_history

    sudo apt-get update sudo apt-get install python-pip sudo pip install Django==1.7.1 sudo apt-get inst ...

  2. 多种EDA软件的鼠标增强工具EDAHelper

    最新版本(unicode版本,各种语言环境显示中文)下载地址:http://www.jyxtec.com/edahelper/EDAHelper-2.1.13.7z 繁体版:http://www.jy ...

  3. MFC基础,MFC自绘控件学习总结.---转

    前言:从这学期开始就一直在学习自绘控件(mfc),目标是做出一款播放器界面,主要是为了打好基础,因为我基础实在是很烂....说说我自己心得体会以及自绘控件的方法吧,算是吐槽吧,说的不对和不全的地方,或 ...

  4. uva--11991 - Easy Problem from Rujia Liu?(sort+二分 map+vector vector)

    11991 - Easy Problem from Rujia Liu? Though Rujia Liu usually sets hard problems for contests (for e ...

  5. 密钥登录linux

    一.linux 主机A登录linux主机B 在/etc/hosts文件下加入:(做硬解析) 192.168.1.60 u60 #设置u60为主机名 在节点A上创建RSA秘钥:(A上生成A主机密钥) # ...

  6. ThinkPHP - Widget 工具

    提出问题:widget能实现什么功能? 显示右侧博文: 1.首先在Home目录下新建Widget文件夹,之后建立对应文件 2.拿最热Hot新闻来举例: 在Tpl目录下Common公共文件夹里的righ ...

  7. B站开源播放框架ijkplayer(iOS版)使用教程

    最近在关注直播这块儿,开始时直接用ffmpeg写了一个,写得比较烂,卡顿很严重,后来听说了B站开源播放框架ijkplayer,于是就去试试看这是链接 ,一用之下果然不错,逢人便向人安利,可总是有部分同 ...

  8. 第一篇:GCD的使用

    一.主队列介绍 主队列是和主线程相关的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行. 提示:如果把任务放到主队列进行处理,那么不论处理函数是异步的还是同步的都 ...

  9. 实战nginx 基础知识总结(一)1.1

    squid Squid是一个缓存Internet数据的软件,其接收用户的下载申请,并自动处理所下载的数据.当一个用户想要下载一个主页时,可以向Squid发出一个申请,要Squid代替其进行下载,然后S ...

  10. [转] Ant 编译 Android 项目为 Apk 实战, 常见问题解决

    补充,自行安装Ant, 配置ant环境变量, 在android 项目 根目录下使用 android update project 可以自动生成 build.xml 和 local.peoperties ...