none
如何获取桌面项目名称并监控桌面文件变化? RRS feed

全部回复

  • 你好,

    感谢你在这里发帖。

    桌面其实也是文件夹,监控文件夹内文件变动就行了,主要利用ReadDirectoryChangesW这个函数,你可以尝试下底下这段代码。

    #include <iostream>
    #include <windows.h>
    #include <tchar.h>
    #include <iomanip>
    
    using namespace std;
    
    void fileWatcher();
    
    int main()
    {
    	fileWatcher();
    	return 0;
    }
    
    void fileWatcher()
    {
    	DWORD cbBytes;
    	char file_name[MAX_PATH]; //设置文件名;
    	char file_rename[MAX_PATH]; //设置文件重命名后的名字;
    	char notify[1024];
    	int count = 0; //文件数量。可能同时拷贝、删除多个文件,可以进行更友好的提示;
    	const TCHAR* dir = TEXT("C:\\Users\\xxxx\\Desktop");//要监控的桌面目录
    
    	HANDLE dirHandle = CreateFile(dir,
    		GENERIC_READ | GENERIC_WRITE | FILE_LIST_DIRECTORY,
    		FILE_SHARE_READ | FILE_SHARE_WRITE,
    		NULL,
    		OPEN_EXISTING,
    		FILE_FLAG_BACKUP_SEMANTICS,
    		NULL);
    
    	if (dirHandle == INVALID_HANDLE_VALUE) //若网络重定向或目标文件系统不支持该操作,函数失败,同时调用GetLastError()返回ERROR_INVALID_FUNCTION
    	{
    		cout << "error" + GetLastError() << endl;
    	}
    
    	memset(notify, 0, strlen(notify));
    	FILE_NOTIFY_INFORMATION* pnotify = (FILE_NOTIFY_INFORMATION*)notify;
    
    	cout << "Start Monitor..." << endl;
    
    	while (true)
    	{
    		if (ReadDirectoryChangesW(dirHandle, &notify, 1024, true,
    			FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_SIZE,
    			&cbBytes, NULL, NULL))
    		{
    			//转换文件名为多字节字符串;
    			if (pnotify->FileName)
    			{
    				memset(file_name, 0, strlen(file_name));
    				WideCharToMultiByte(CP_ACP, 0, pnotify->FileName, pnotify->FileNameLength / 2, file_name, 99, NULL, NULL);
    			}
    
    			//获取重命名的文件名;
    			if (pnotify->NextEntryOffset != 0 && (pnotify->FileNameLength > 0 && pnotify->FileNameLength < MAX_PATH))
    			{
    				PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pnotify + pnotify->NextEntryOffset);
    				memset(file_rename, 0, sizeof(file_rename));
    				WideCharToMultiByte(CP_ACP, 0, p->FileName, p->FileNameLength / 2, file_rename, 99, NULL, NULL);
    			}
    
    			//设置类型过滤器,监听文件创建、更改、删除、重命名等;
    			switch (pnotify->Action)
    			{
    			case FILE_ACTION_ADDED:
    				count++;
    				cout << "count  = " << count << endl;
    				cout << setw(5) << "file add:" << setw(5) << file_name << endl;
    				break;
    
    			case FILE_ACTION_MODIFIED:
    				cout << "file modified:" << setw(5) << file_name << endl;
    				break;
    
    			case FILE_ACTION_REMOVED:
    				count++;
    				cout << count << setw(5) << "file removed:" << setw(5) << file_name << endl;
    				break;
    
    			case FILE_ACTION_RENAMED_OLD_NAME:
    				cout << "file renamed:" << setw(5) << file_name << "->" << file_rename << endl;
    				break;
    
    			default:
    				cout << "UNknow command!" << endl;
    			}
    		}
    	}
    
    	CloseHandle(dirHandle);
    }

    Best Regards,

    Suarez Zhou


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。


    2019年11月14日 6:35
  • 感谢您的及时解答!

    对于一个用户桌面上的图标,它们应该是来源于该用户对应的目录“c:\Users\xxx\Desktop”和公共目录“C:\Users\Public\Desktop”(还有其他目录吗?),也就是说,我如果要监控桌面变化,需要监控多个目录的变化,对吧

    2019年11月14日 6:49
  • 你好,

    >>“C:\Users\Public\Desktop”

    这点我没有考虑到,确实也是需要考虑进来。其实思考一下发现我的电脑和回收站也算是桌面图标,但这两个没有属性页面,也不在桌面文件夹内,但它确实存在于桌面上的,似乎无法通过上述方法来监控这两个的变动。不清楚你的程序是否需要监控我的电脑和回收站的变动。

    Best Regards,

    Suarez Zhou


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。


    2019年11月14日 7:05
  • 对于这些系统图标也是需要的,这样好像是有些问题,比如我删掉“我的电脑”图标,通过上述方法就没办法了。所以我很想知道Windows是否提供有其他接口能知道桌面变化,比如:文件变化、子文件夹变化(因为子文件夹内容变化图标会变化)、系统图标变化。如果您了解这块,还烦请给些意见。
    • 已编辑 jimmy_q 2019年11月14日 7:16
    2019年11月14日 7:15
  • 你好,

    微软并没有提供专门对桌面监控的接口,也没有提供对图标变换监控的接口,所以你想要实现的东西很难很难。

    Best Regards,

    Suarez Zhou


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。


    2019年11月14日 8:09
  • 是的,确实很麻烦,或者这样,不知道有没有办法能知道桌面有哪些系统程序。
    • 已编辑 jimmy_q 2019年11月14日 8:21
    2019年11月14日 8:20
  • 你好,

    通过获取进程的可执行程序的路径和桌面快捷程序的路径做比较就可以知道快捷方式是否指向的是系统程序,这些都是可以通过C++获取的,但老实说很繁琐,而且也有特殊情况,例如程序的安装路径就是桌面,那就没有快捷方式了,又需要额外的鉴别方式。或者你能说明下你最后想实现的效果吗?或许有什么其他的方式可以帮助到你。

    Best Regards,

    Suarez Zhou


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。


    2019年11月14日 8:56
  • 我想要隐藏桌面所有的图标,然后自己创建窗口显示这些图标。

    对于直接操作桌面图标还好办,但是如果是在桌面文件夹(desktop目录)里操作,比如删除某个文件,那我的桌面就需要知道这个操作并从我的窗口删除对应的图标。

    对于操作桌面上的文件夹里面的文件,桌面上的文件夹图标因为预览效果,是会有一点变化的,这个我也需要知道有这个操作,去重新获取这个文件夹的图标。主要就是这样的想法,您看有什么建议?

    2019年11月14日 9:34
  • 可以用SHChangeNotifyRegister监听文件变化。前提是执行文件变化的程序有调用SHChangeNotify。一些安装程序即使在桌面创建了快捷方式也是不会去调用SHChangeNotify的。


    Visual C++ MVP

    2019年11月14日 14:02
    版主
  • 是的,但是这个好像对于我监控桌面没发去搞,比如回收站从空变成非空
    2019年11月15日 1:46
  • 对于监控文件变化,我想 第一位提出的方法应该就可以做到,主要麻烦是对于系统图标,比如“我的电脑”、“控制面板”等,这些的变化
    2019年11月15日 1:49
  • 你好,

    回收站在系统盘也有地址,你打开文件夹选项,取消勾选隐藏受保护的操作系统文件,即可看到回收站的文件夹,名字各个版本的系统都不一样,但基本都带有Recycle字眼。

    Best Regards,

    Suarez Zhou


    如果您对Visual Studio 或Microsoft Azure相关产品感兴趣,请点击此链接,或扫描以下二维码注册获取相关信息。

    2019年11月15日 1:58
  • 很感谢您的耐心解答!

    我打算分两块去实现,一是监控桌面文件夹,这对于用户的文件和文件夹都能监控到;二是监控系统程序,我的麻烦就在这。我知道“桌面图标设置”中可以控制这些系统图标的显示和隐藏,不知道做这些设置变化时,是否有通知?

    2019年11月15日 3:46
  • 会有WM_SETTINGCHANGE通知,LPARAM的值是ShellState。


    Visual C++ MVP

    2019年11月15日 4:29
    版主