Windows C 監控共享資料夾變化

2021-09-23 18:19:23 字數 4216 閱讀 5239

最近由於專案需求,需要編寫乙個監控本機共享資料夾的變化的模組,經過查詢資料,找到並實現了乙個較為穩定的方式

專案實現是使用win32 c++的,測試平台是win 7 64和win 10 64,xp測試也是好使的。下面是具體實現

首先要獲取並監控系統共享資料夾的路徑,相關登錄檔路徑為 hkey_local_machine\system\currentcontrolset\services\lanmanserver\share ,他的值的格式為如圖所示,

型別為 reg_multi_sz, 所以我們需要列舉獲取所有型別為reg_multi_sz的項。然後它的值的具體內容如圖所示,

我們可以看的項為path=e:\sharetest 裡就有我們所需要的共享資料夾路徑,所以獲取共享資料夾路徑的就可以開始編寫了,具體實現如下。

bool getsharedfolderslist(map&thelist)

tchar szvalue[max_value_name] = ;

dword dwvaluesize = max_value_name;

int index = 0;

dword dwbuffersize = 255;

dword dwtype;

tchar *szvalbuffer = null;

dword dwsize;

while (error_no_more_items != regenumvalue (

hkey, index, szvalue, &dwvaluesize, null, &dwtype, null, &dwbuffersize))

int j = 0;

cstring tmpvalue;

for(int i = 0;szvalbuffer[i] != '\0' ;i += j + 1)

//如果找到共享路徑,則直接放入容器,然後進行下乙個路徑的查詢

if (tmpvalue.find(_t("path=")) == 0)

tmpvalue = _t("");

}delete szvalbuffer;

szvalbuffer = null;

break;

}//其他型別跳過

default:

}dwvaluesize = max_value_name;

dwbuffersize = 255;

index ++;

} bflag = true;

}while(false);

if (hkey != null)

return bflag;

}

接下來就是監控共享資料夾登錄檔的變化了,win 32 給我們提供了監控登錄檔的相關api regnotifychangekeyvalue ,使用很方便,所以我們只需建立乙個執行緒去專門監控一下對應登錄檔的變化,如果登錄檔變化了,我們需要和之前的列表進行比較一下,然後進行對應的更新(新增監控/刪除監控)。具體監控執行緒實現如下。

//監控登錄檔項以更新共享資料夾列表

dword winapi sharedmonitor::refreshthread(lpvoid lpparam)

if (null == (hevent = createevent(null, true, false, null)))

if (error_success != regnotifychangekeyvalue (hkey, true, dwfilter, hevent, true))

if (wait_failed == waitforsingleobject (hevent, infinite))

bflag = true;

}while(false);

regclosekey (hkey);

closehandle (hevent);

//如果監控失敗,則重新再來

if (!bflag)

//等待系統將登錄檔訊息發放完畢,否則有時候新增或刪除的登錄檔項無法被列舉到

sleep(200);

//進行共享列表列舉和比較

mapthenewlist;

//獲取新列表

pthis->getsharedfolderslist(thenewlist);

map&theoldlist = pthis->getlistinstance();

bool bfindnew = false;

//比較兩個列表

//新增舊列表中沒有的共享

for (map::iterator it = thenewlist.begin();

it != thenewlist.end(); ++it)

}//mydebug(_t("---------start delete--------"));

//需要刪除的列表,map不支援迴圈刪除多個元素

vectorthedeletelist;

//刪除舊列表中已經取消的共享

for (map::iterator it = theoldlist.begin();

it != theoldlist.end(); ++it)

//將執行緒占用的共享目錄控制代碼釋放

if (gs_mpdirhandlelist[it->first])

closehandle(it->second);

thedeletelist.push_back(it->first);

}} mydebug(_t("-----------deletelist-------------"));

//刪除舊列表中的過期共享

for (vector::iterator it = thedeletelist.begin();

it != thedeletelist.end(); ++it)

//如果有新的共享

if (bfindnew)

}return 0;

}

//監控執行緒

dword winapi atsharedmonitor::monitorthread(lpvoid lpparam)

//將目錄控制代碼放到執行緒對應容器中

gs_mpdirhandlelist[szrootpath] = hroothandle;

// output_param_debuga("the currentthread:%x", getcurrentthread());

szrootpath += _t("\\");

wchar_t notify[1024];

zeromemory(notify, 1024);

dword dwbytes;

file_notify_information *pnotify = (file_notify_information *)notify;

//過濾同乙個檔案的操作

cstring szlastfile = _t("");

while (true)

//刪除

// case file_action_removed:

//

//修改..略過資料夾的修改,過濾同乙個檔案的修改

case file_action_modified:

break;

}//新建檔案獲取

case file_action_added:

break;

}default:

}} }

return 0;

}

最後來列舉一下這種方法的優缺點。

優點:1.由於是訊息響應機制,能夠完全的獲取到共享資料夾的所有變化,包括 檔案修改/新增/刪除/重新命名

2.可以監控登錄檔檢視共享資料夾的變化,自動實現對共享資料夾的建立監控和取消監控

缺點:0.由於訊息響應原理所限,乙個執行緒只能監控乙個共享資料夾,所以有多少個共享資料夾就需要多少個執行緒去監控。

1.由於是單執行緒訊息響應,如果在同時有大量檔案被操作,則訊息是一起過來的,如果你沒能及時處理,則會導致漏掉一些訊息

2.訊息是作業系統非同步通知的,所以只能做到監控而已,無法實現攔截之類的功能

3.由於監控原理所致,當向指定共享資料夾進行大檔案的操作時(持續寫入操作),會觸發多次修改訊息

共享資料夾

分成4種情況,win win對映 linux linux對映 linux win win linux。這裡只介紹後面兩種情況。虛擬機器可以安裝vmware tools,開啟資料夾共享 利用ubuntu 共享 安裝samba,按照以下步驟 關閉firewall service ufw stop 臨時關...

nanopi 共享資料夾

apt get install samba apt get install smbclient 2 修改samba配置檔案 samba配置檔案的路徑是 etc samba smb.conf a 備份配置檔案 cp etc samba smb.conf etc samba smb.conf.bakb ...

VMware共享資料夾

如何能將檔案在虛擬機器和win7 在這裡以win7為例,winxp操作一樣 下實現互傳。方法有很多種。今天,我們就介紹其中一種方法,通過vmware的共享資料夾來實現虛擬機器ubuntu與win7的檔案傳輸。第一步 啟動ubuntu 12.04 其他版本的ubuntu操作差不多 1.在vmware虛...