- [TOOL] Chia sẻ phần mềm thay đổi thông tin cấu hình máy tính
- [C#] Hướng dẫn Export dữ liệu ra file Microsoft Word Template
- [C#] Chia sẻ source code tool kiểm tra domain website
- [C#] Hướng dẫn tạo file PDF sử dụng thư viện QuestPDF
- [C#] Hướng dẫn tạo ứng dụng dock windows giống Taskbar
- [C#] Chia sẻ source code sử dụng Object Listview trên Winform
- [VB.NET] Chia sẻ source code quản lý thu chi mô hình 3 lớp Winform
- [DATABASE] Xóa lịch sử danh sách đăng nhập tài khoản trên SMSS Sqlserver Management Studio
- [C#] Sử dụng FolderBrowserDialog Vista trên Winform
- [DEVEXPRESS] Chia sẻ tool Winform UI Templates Early Access Preview (EAP)
- [C#] Chia sẻ source code Spin Content (Trộn nội dung văn bản theo từ đồng nghĩa) trên Winform
- [VB.NET] Chia sẻ source code lịch âm dương và hẹn lịch nhắc việc
- [C#] Hướng dẫn đọc thông số thiết bị Thiết bị kiểm tra Pin (HIOKI BATTERY HiTESTER BT3562)
- [VB.NET] Hướng dẫn giải captcha sử dụng dịch vụ AZCaptcha API trên winform
- [C#] Hướng dẫn chứng thực đăng nhập ứng dụng bằng vân tay (Finger Print) trên máy tính
- [C#] Color Thief cách xuất màu sắc thiết kế từ hình ảnh
- [C#] Cách tạo bản quyền và cho phép dùng thử ứng dụng Winform
- [C#] Hướng dẫn sử dụng trình duyệt web Chrome convert HTML sang tập tin file PDF
- [C#] Kết nôi điện thoại Android, IOS với App Winform via Bluetooth
- [DATABASE] Cách query cộng trừ dồn dần trong Sqlserver
[C#] Hook Right context menu windows (ex: Pin and Unpin Taskbar)
Xin chào các bạn, bài viết hôm nay mình sẽ hướng dẫn các bạn cách Hook Menu chuột phải Context Menu của từng ứng dụng trên Windows Explorer C#.
[C#] Hook Right context menu windows (ex: Pin and Unpin Taskbar)
Cụ thể ở bài viết demo này chức năng Pin và UnPin một ứng dụng vào thanh taskbar Windows.
Trên từng item của mỗi menu trong windows explorer sẽ có một mã ID.
Vd:
pin to taskbar => 5386
Unpin from taskbar => 5387
Các bạn có thể tham khảo thêm các mã khác ở link sau:
http://www.win7dll.info/shell32_dll.html
Các bạn xem giao diện demo ứng dụng mình dưới đây:
Trong bài viết này các bạn nhìn hình ở trên khi mình right click chuột phải vào ứng dụng HOB 2015.exe, thì các bạn thấy được một danh sách treeview mình trả về giống hình bên tay phải các bạn.
Khi các bạn nhấn vào từng item node trên treeview này nó sẽ thực hiện hành động (action) giống như khi các bạn click vào menu trên windows explorer vậy.
Để pin được ứng dụng vào thanh taskbar, các bạn phải cần giả lập ứng dụng của bạn đang chạy là "Windows Explorer" thì nó mới cho phép.
Nên trong bài viết mình có để hàm sẵn trên là ChangeImagePathName()
và truyền vào là đường dẫn của Windows Explorer, nếu các bạn không thêm hàm này vào sẽ không thấy được menu Pin to Taskbar nhé.
Demo ứng dụng Pin and unPin taskbar C#:
Đầu tiên các bạn cần tạo một class Utils.cs, với nội dung như sau:
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace PinToTaskbar
{
static public class Utils
{
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
internal static extern IntPtr LoadLibrary(string lpLibFileName);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true, BestFitMapping = false, ThrowOnUnmappableChar = true)]
internal static extern int LoadString(IntPtr hInstance, uint wID, StringBuilder lpBuffer, int nBufferMax);
public static List<string> PinUnpinTaskbar(string filePath, bool pin, string action = "")
{
if (!File.Exists(filePath)) throw new FileNotFoundException(filePath);
int MAX_PATH = 255;
var actionIndex = pin ? 5386 : 5387; // 5386 is the DLL index for"Pin to Tas&kbar", ref. http://www.win7dll.info/shell32_dll.html
StringBuilder szPinToStartLocalized = new StringBuilder(MAX_PATH);
IntPtr hShell32 = LoadLibrary("Shell32.dll");
LoadString(hShell32, (uint)actionIndex, szPinToStartLocalized, MAX_PATH);
string localizedVerb = szPinToStartLocalized.ToString();
string path = Path.GetDirectoryName(filePath);
string fileName = Path.GetFileName(filePath);
dynamic shellApplication = Activator.CreateInstance(Type.GetTypeFromProgID("Shell.Application"));
dynamic directory = shellApplication.NameSpace(path);
dynamic link = directory.ParseName(fileName);
List<string> lists = new List<string>();
dynamic verbs = link.Verbs();
for (int i = 0; i < verbs.Count(); i++)
{
dynamic verb = verbs.Item(i);
var name = verb.Name;
lists.Add(name);
if (string.IsNullOrEmpty(action))
{
if (verb.Name.Equals(localizedVerb))
{
verb.DoIt();
}
}
else
{
if (verb.Name.Equals(action))
{
verb.DoIt();
}
}
}
return lists;
}
static string originalImagePathName;
static int unicodeSize = IntPtr.Size * 2;
static bool changed;
static void GetPointers(out IntPtr imageOffset, out IntPtr imageBuffer)
{
IntPtr pebBaseAddress = GetBasicInformation().PebBaseAddress;
var processParameters = Marshal.ReadIntPtr(pebBaseAddress, 4 * IntPtr.Size);
imageOffset = processParameters.Increment(4 * 4 + 5 * IntPtr.Size + unicodeSize + IntPtr.Size + unicodeSize);
imageBuffer = Marshal.ReadIntPtr(imageOffset, IntPtr.Size);
}
internal static void ChangeImagePathName(string newFileName)
{
IntPtr imageOffset, imageBuffer;
GetPointers(out imageOffset, out imageBuffer);
var imageLen = Marshal.ReadInt16(imageOffset);
originalImagePathName = Marshal.PtrToStringUni(imageBuffer, imageLen / 2);
var newImagePathName = Path.Combine(Path.GetDirectoryName(originalImagePathName), newFileName);
if (newImagePathName.Length > originalImagePathName.Length) throw new Exception("new ImagePathName cannot be longer than the original one");
var ptr = imageBuffer;
foreach (var unicodeChar in newImagePathName)
{
Marshal.WriteInt16(ptr, unicodeChar);
ptr = ptr.Increment(2);
}
changed = true;
Marshal.WriteInt16(ptr, 0);
Marshal.WriteInt16(imageOffset, (short)(newImagePathName.Length * 2));
}
internal static void RestoreImagePathName()
{
if (!changed) return;
IntPtr imageOffset, ptr;
GetPointers(out imageOffset, out ptr);
foreach (var unicodeChar in originalImagePathName)
{
Marshal.WriteInt16(ptr, unicodeChar);
ptr = ptr.Increment(2);
}
Marshal.WriteInt16(ptr, 0);
Marshal.WriteInt16(imageOffset, (short)(originalImagePathName.Length * 2));
}
public static ProcessBasicInformation GetBasicInformation()
{
uint status;
ProcessBasicInformation pbi;
int retLen;
var handle = System.Diagnostics.Process.GetCurrentProcess().Handle;
if ((status = NtQueryInformationProcess(handle, 0,
out pbi, Marshal.SizeOf(typeof(ProcessBasicInformation)), out retLen)) >= 0xc0000000)
throw new Exception("Windows exception. status=" + status);
return pbi;
}
[DllImport("ntdll.dll")]
public static extern uint NtQueryInformationProcess(
[In] IntPtr ProcessHandle,
[In] int ProcessInformationClass,
[Out] out ProcessBasicInformation ProcessInformation,
[In] int ProcessInformationLength,
[Out] [Optional] out int ReturnLength
);
public static IntPtr Increment(this IntPtr ptr, int value)
{
unchecked
{
if (IntPtr.Size == sizeof(Int32))
return new IntPtr(ptr.ToInt32() + value);
else
return new IntPtr(ptr.ToInt64() + value);
}
}
[StructLayout(LayoutKind.Sequential)]
public struct ProcessBasicInformation
{
public uint ExitStatus;
public IntPtr PebBaseAddress;
public IntPtr AffinityMask;
public int BasePriority;
public IntPtr UniqueProcessId;
public IntPtr InheritedFromUniqueProcessId;
}
}
}
Và dưới đây là source code của form chính:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace PinToTaskbar
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
string filename;
private void btn_pinTaskbar_Click(object sender, EventArgs e)
{
filename = @"C:Program Files (x86)HOABINH COMPANY LIMITEDHOB METRO UI 2018HOB 2015.exe";
List<string> list = new List<string>();
treeView.Nodes.Clear();
try
{
Utils.ChangeImagePathName(@"C:Windowsexplorer.exe");
list = Utils.PinUnpinTaskbar(filename, true);
}
finally
{
Utils.RestoreImagePathName();
}
foreach (var item in list)
{
TreeNode newNode = new TreeNode(item);
treeView.Nodes.Add(newNode);
}
}
private void btn_unpin_Click(object sender, EventArgs e)
{
Utils.ChangeImagePathName("explorer.exe");
List<string> list = new List<string>();
list.Clear();
list = Utils.PinUnpinTaskbar(filename, false);
treeView.Nodes.Clear();
foreach (var item in list)
{
TreeNode newNode = new TreeNode(item);
treeView.Nodes.Add(newNode);
}
}
private void treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
var text = e.Node.Text;
Utils.PinUnpinTaskbar(filename, false, text);
}
}
}
Thanks for watching!