Use VB to write monitoring programs

Source: Internet
Author: User

Published in QQ space in the first half of last year. Move it over and talk about it again

Only monitoring in user mode makes no sense, and many other things can be found online. But you can see it.

Some days ago, I encountered a message asking me about the monitoring software. Said that a netizen needs such information. Before that
I checked related information on the Internet and wrote a simple monitoring program with VC (MFC), but it was not saved. After the system is redone, it will be gone.
(Because it was only an experiment at the time, the folder of the MFC project was directly built on the C drive by default). Therefore, it was just a simple response to his
You can use the shchangenotifyregister API. Afterwards, I suddenly felt that I should write this as a component.
In the future, you do not need to write these things repeatedly. I was prepared to use VC for writing, because a large number of APIs and their declarations are required.
However, because I do not use VC to write ActiveX, I have to choose a familiar v B.

Windows has more than one method to monitor folders.
You can use findfirstchangenotification, combined with waitformultipleobjects, and findnextchangenotification
.
You can also use this article to introduce de shchangenotifyregister. Of course, I prefer shchangenotifyregister.
Shchangenotifyregister is the core of the entire monitoring folder, so before introducing it to Ha, you must first understand its specific content.
Shchangenotifyregister declares this statement on msdn.
Ulong shchangenotifyregister (hwnd,
Int fsources,
Long fevents,
Uint wmsg,
Int centries,
Shchangenotifyentry * pfsne
);
The first parameter does not need to be described in detail. The old ghost knows that this is a window handle, indicating the form in which the message is sent when the change is captured.
The second parameter on msdn seems to have a problem (of course, I may understand it ).
The third parameter mentioned in msdn is the same as farting. Therefore, it is excluded that I will discuss ha again on msdn.
The second parameter indicates the data format returned to the address location pointed to by wparam in the form processing function.
It can be shcnf_idlist (0x0000) // lpitemidlist
You can also run shcnf_patha (0x0001) // path name
If shcnf_idlist is used, the address to which wparam points is lpitemidlist (Windows namespace ID)
If it is shcnf_patha, the address to which wparam points is stored as a path.
Of course, the path here is a string like "C:/ABC. But what is namespace.
Namespace is a directory management concept introduced in windows. It works the same as the path. Of course you will ask, it works the same way as the path.
So what should we do. Use the path. Of course, Microsoft is not a sb. It naturally plays a role in making this thing. Although the path is
We are common, but in fact Windows does not use paths to manage tree directories. The usage path is only used to be compatible with DOS.
It is easy to understand. The namespace is used to manage the Windows tree directory.
Anyone who has used computers knows. It is basically impossible to use a path to access all directories in windows.
At least you cannot access the directory like control panel, online home, or recycle bin.
But in fact, you can access them. If you cannot access them using a path, what access does it use.
Of course, that is the namespace.
After talking about this, what is the namespace. It is actually very simple. The namespace is the name space, which is all
Directory and file name and a set of constraints (rules.
Each directory and file in Windows has a unique name. This name is not as easy to remember and understand as the path. This name is
A 32-bit number.
Of course, to facilitate the explanation, we also need to use the concept of path.
Such as C:/ABC/text/test.txt. The information is.
"C:/ABC/text/test.txt" is the full path of "test.txt. Test.txt is the name of the file.
Among them, "C:/ABC" is the full path of the folder "ABC" (note that the folder is not the directory here -- folder is the concept of the path system, while the Directory
It is the concept in the namespace. Of course, we will often mix them. It doesn't matter, it doesn't affect understanding)
ABC is the name of the folder "C:/ABC/text" is the full path of the folder "text", and text is the name of the S folder.
Text is a sub-folder of ABC. Test.txt is stored in the text folder.
C: It is a drive letter name.
The above concepts should be clear. If you do not understand it, you should build a wall.
We started to map the HA surface one by one.
C: In the namespace, it is represented as feab2346 (of course, this is a hypothesis, which may be something else in reality)
Similarly, ABC can also have a namespace that represents ea123456.
Continue the corresponding text-> aaaa3dab
Test.txt-> 12345678
Therefore, in order to facilitate reading and writing all the information on the HA Surface
C:-> feab2346
ABC-> ea123456
Text-> aaaa3dab
Test.txt-> 12345678
We can understand the corresponding introduction. In the namespace, if you want to access drive C, you must use feab2346 (this is not correct ).
However, to understand this, we will explain it later)
What should I do if I want to access C:/ABC? In fact, it is the same. In the path system, a/can be used to separate the representation.
Tree structure. It is more convenient in The namespace.
Directly add the abc id to the end of C: ID. So
C:/the full address of ABC in The namespace is
Feab2346
Ea123456
Similarly, C:/ABC/text is
Feab2346
Ea123456
Aaaa3dab
In other cases, we will not continue to push data. Of course, we must understand that what we have just said is. The namespace and path do not correspond one to one.
The namespace can be accessed in a wider range, and it must be clarified. The path is based on the drive letter. The root of the namespace is the desktop.
Its structure is like ha.
Desktop
-- Recycle Bin
-- Network neighbors
-- Control Panel
.........
-- C:
---- ABC
------ Text
--------Test.txt
.........
-- N:
Now we should know why feab2346 is not used to access the full address of drive C. Real full address Hai
You should add a desktop before it.

Of course, after reading the above instructions, you will have an impulse to beat people. There is no way to do this. The expression of Wo is just like this.
However, if you want to continue looking at Ha, you will see it later.
The third parameter refers to the event type to be captured. Here we capture all the events of shcn_allevents (0x7fffffff) or shcn_interrupt (0x7fffffff.
The fourth message indicates the message to be sent to the form. Of course, this message must be customized.
Here we define it as wm_sh1_y = & h401
Although I write this statement here, we recommend that you use the WM _ *** = wm_user + n method.
The fifth parameter is an integer and used with the sixth parameter.
For better explanation, we will first introduce the sixth parameter.
The sixth parameter is a pointer to a struct. First, let's look at its definition.
Typedef struct {
Lpcitemidlist pidl;
Bool frecursive;
} Shchangenotifyentry
It can be seen from the name that this is an entry structure. It indicates that we want to monitor the directory.
His first element is the pidl of the lpcitemidlist type. Do not be scared by such a long name. Actually
This is a pointer to the namespace ID we mentioned above.
The second element indicates whether to monitor sub-directories. If the value is true, the sub-directories are monitored. Otherwise, it is not monitored.
The fifth parameter is described in HA, because the sixth parameter and the fifth parameter are described in detail. In fact, the fifth parameter is the description.
The number of arrays in the sixth parameter may be a bit confusing. Isn't the sixth parameter a struct,
How does it become an array. Declare ha here. The sixth parameter is a struct. Because from the very beginning
The sixth parameter is a pointer to a struct. Of course, this description is not accurate. Here, it should be
Pointer to the struct array.
Okay. I have already finished talking about several parameters. Of course I can understand a lot of them with my presentation skills. So now we have a comprehensive
Description 1: ha.
Ulong shchangenotifyregister (hwnd,
Int fsources,
Long fevents,
Uint wmsg,
Int centries,
Shchangenotifyentry * pfsne
);
In fact, this function is used to monitor changes to a directory (File) or a group of directories (Files) indicated by centries and pfsne.
When these directories contain events within the event range described by fevents, A wmsg message is placed in the form hwnd
In the queue.
Now, the core functions have been introduced. Continue to go to ha.

------------------------------------------------------

Of course, we only know that this function cannot proceed.
If you really understand the above functions. You will find several things that must be solved at present.
The first is to monitor a directory. From the sixth parameter, we cannot pass a path, but must pass
The pointer to the namespace. So how can this be obtained.
The second is that the message loop cannot be directly written in VB as in the SDK. How can we get the custom message. After the problem is raised, the problem is solved one by one.
First.
There are many methods to achieve the first goal. You can use shgetspecialfolderlocation to get the pidl of the desktop.
And then enumerate them one by one. Until we find the folder to monitor.
Of course, this method is quite resource-consuming and basically won't be used.
So here we use these two methods. Use ishellfolder.
Because ishellfolder has a method, parsedisplayname, which can easily convert the path to pidl. Of course, the special
We can use shgetspecialfolderlocation to obtain the directory pidl, so that we can monitor any directory.
Ishellfolder is a COM object interface. Because VB does not support underlying development of COM. So here we
A. TLB file is required to let VB know the implementation layout of the ishellfolder interface.
Ha is the source program of VB. Here I put him in a method.
Public Function getpidl (PATH) as long
Dim ISF as ishellfolder
Dim temp as long
If succeeded (shgetasktopfolder (temp) then' succeeded is a method to determine whether the operation is successful.
Movememory ISF, temp, 4
End if
Dim pathlen as long
Dim pidl as long
ISF. parsedisplayname vbnull, 0, strconv (path, vbunicode), pathlen, pidl, vbnull
Getpidl = pidl
ISF. Release
'Enumpidl ISF, 1, using toppidl
End Function
The above process shows two API functions that have not been seen.
Shgetasktopfolder
Movememory
The declaration of these two functions on msdn is as follows: ha.
Hresult shgetasktopfolder (
Ishellfolder ** ppshf
);
This function receives the address of an instance pointer that stores the ishellfolder interface on the desktop.
Void movememory (
Pvoid destination,
Const void * source,
Size_t Length
);
This function is used to move data from memory.
The destination parameter is the address to be moved.
Source is the source address.
Length is the number of bytes to be moved.
Although from this declaration, destination and source are different. In fact, let's look at the pvoid statement.
Typedef void * pvoid;
As you can see, these two are the same. All pointer to the unknown type (note that it is not a null pointer), just a pointer
Is a constant.
After reading the above function explanation and combining the program, it is easy to understand the meaning of the above program.
Public Function getpidl (PATH) as long
Dim ISF as ishellfolder 'defines an ishellfolder object (actually a pointer-a long value in VB)
Dim temp as long defines a temporary variable used to store the pointer to the returned ishellfolder object
If succeeded (shgetasktopfolder (temp) then' succeeded is a method to determine whether the operation is successful.
Movememory ISF, temp, 4 if the pointer of ishellfolder is successfully moved to the address indicated by ISF.
End if
Dim pathlen as long
Dim pidl as long
ISF. parsedisplayname vbnull, 0, strconv (path, vbunicode), pathlen, pidl, vbnull' convert path to pidl
The converted pidl exists in the variable pidl.
Getpidl = pidl
ISF. Release 'release ISF.
'Enumpidl ISF, 1, using toppidl
End Function
The above process body may be easier to understand after being converted into an assembly.
Of course, the compilation below is just a pseudo-code, and the succeeded process call is canceled to simplify the process.
Shgetasktopfolder is always successful.
Isf dw? // Dim ISF as ishellfolder
Temp DW? // Dim temp as long
Pathlen DW? // Dim pathlen as long
Pidl DW? // Dim pidl as long
MoV eax, ADDR temp
Push eax
Call shgetasktopfolder // shgetasktopfolder (temp)
// At this time, the address corresponding to temp stores the pointer of the instance of the ishellfolder object (in fact, it should be a pointer
Vtable Pointer -- conjecture)
XOR eax, eax
MoV eax, temp
MoV dword ptr isf, eax // movemeory ISF, temp, 4
Note: The previous sentence is not actually the implementation of API movememory.
It is only a part of it.
Movememory adds the address conflict check based on it. However, the compiled mov does not care about this.
Here, unlike the above sentence, the call API in MASM is used to better describe the address movement.
The statements in the HA plane directly convert to the Assembly may require some assumptions. Therefore, the statements in the HA plane must be described first and then converted.
Of course, the operations in these instructions are all done by the compiler (or parser,
It is not generated into binary files (pcode ).
Let's take a look at the HA sentence.
ISF. parsedisplayname vbnull, 0, strconv (path, vbunicode), pathlen, pidl, vbnull
When the compiler (Interpreter) sees this sentence. The table is queried first. Find the ISF type as ishellfolder and
Based on the Interface layout declared by the referenced TLB file. Obtains the offset of parsedisplayname in the class instance struct. Here
Assume N. Then use the interface instance address pointed to in ISF (this address is bound later-through shgetasktopfolder)
Add n to obtain the virtual address of this method. Then call the address directly.
XOR eax, eax
MoV eax, ISF
Push null
Push ADDR pidl
Push ADDR pathlen
Push ADDR path // here the process of converting to unicode encoding is omitted
Push 0
Push null
Call [eax + N]
Note: Most Microsoft APIs use the stdcall call Convention. Parameters on the right are first added to the stack. Stack recovery is performed in the process.
After we can get pidl through the path, we can complete our program just now.
Assume that you only want to monitor a directory: C:/ABC
Dim pidl as long
Pidl = getpidl ("C:/ABC ")
Dim entry as shchangenotifyentry 'Of course, you must declare such a struct in VB first.
Some structures used by public functions can be directly declared using the API viewer of VB.
However, shchangenotifyregister is a function published only after Win 2000. When VB6 is released, it is also a non-public function.
Therefore, you cannot use the API viewer to view its VB declaration. It must be self-converted. Conversion is simple. Not described here
Entry. pidl = pidl
Entry. frecursive = true // set it to false if you do not want to monitor sub-Directories

Shchangenotifyregister (hwnd ,_
Shcnf_type or shcnf_idlist ,_
Shnning_allevents or shnning_interrupt ,_
Wm_shpolicy, 1, entry)

If you want to monitor two or more. Only slightly changed
Dim pidl as long, pidl1 as long
Pidl = getpidl ("C:/ABC ")
Pidl1 = getpidl ("C:/BCD ")
Dim entry (2) as shchangenotifyentry
Entry (0). pidl = pidl
Entry (0). frecursive = true // set it to false if you do not want to monitor sub-Directories
Entry (1). pidl = pidl1
Entry (1). frecursive = true // set it to false if you do not want to monitor sub-Directories

Shchangenotifyregister (hwnd ,_
Shcnf_type or shcnf_idlist ,_
Shnning_allevents or shnning_interrupt ,_
Wm_shpolicy, 2, entry (0 ))
The hwnd above. You can use me. hwnd in any form class in VB.
Through the above method, we can implement a wm_shnotify message when the C:/abc c:/BCD changes.
It is sent to the Message Queue of the hwnd form.
Of course, the third parameter can be used to set the event capture range, because we set the event capture range to shnning_allevents or shnning_interrupt.
Therefore, all events can be captured.
The HA problem is to process the message. So we have to solve the second problem mentioned at the beginning.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.