I've read some posts about my issue, but I haven't find a right solution.
I would have a complete list of current files in use, for example:
*.mp3 files opened by Windows Media Player
*.txt files opened by Notepad.exe
*.avi files opened by VLC etc...
With FileWatcher system I can get files that are created/modified/updated or deleted, but not opened.
How I can do it?
You can use the Process Explorer tool from Sysinternals to obtain that information, but I don't think you can easily do the same by code (short of reimplementing Process Explorer itself).
Most you can achieve with simple code is iterate over all Processes and read their Title - most programs will put the current file in use inside their title e.g. Notepad will have window title of "TextFile.txt - Notepad".
If you like I can pull together some quick example.
To achieve exactly what you want though, you'll have to "hook" into the processes in some low level way and see their internals - Frédéric Hamidi reply pretty much covers this.
I'd suggest the simplest method would be to use the Handle command-line tool from the same people as Process Explorer.
You could maybe invoke the process from your code, and then parse the output, which is basically just a big list of open files (and registry entries) divided into sections with the process that opened the file as the header.
I think that under the hood Handle uses the NT Object Manager API, so that may be worth looking into if you need to do the whole thing yourself.
Related
I'm writing an application that needs to be notified of every doc file that is opened, I've tried using the FileSystemWatcher but it seems that these days NotifyFilter.LastAccess is disabled due to a large overhead.
There is LastWrite which I suppose I could use but it would mean I'd need to try and figure out the original file name from the temporary file that word creates when it opens a document.
I also need to keep watch on 4 directories so ideally I don't want to be polling them.
I'm aware I could write a WordAddin which is one option but that means another deployment to manage, another codebase and another product to support along with the problem that many users always see addins as a source of slowdowns.
Is there a straightforward way to tell windows Vista upward that I want to know about doc or docx that is opened?
One thing I was wondering about is if I could alter the default program associated with .doc to mine, which is running as a service and then passing the details through it to mine to be opened? This seems like a bit of a hack so I was wondering if there was an easy way to hook into these sorts of file open?
UPDATE
From talking it through with various people here the most reliable way(and most resource effective) would seem to be to replace the existing file association for .doc. & .docx to my own program and then use Microsoft.Office.Interop.Word to launch word and then hook into the DocumentOpen event.
That way I get the file name thats being opened along with any future documents that are open in word.
If I recall correctly, the temporary file that is created in the same folder has the file name format of ~$ + filename, for example:
~$very_important_file.doc
It contains the name of the user that opened the file. Note that the file has the hidden attribute set.
This makes it quite easy to figure out which document is actually open and by whom.
Such tasks are usually accomplished using filesystem filter drivers. Procmon works this way. You can create your own filter driver or use the precreated one (eg. our CallbackFilter).
I was always pretty impressed by those programs that you could install by executing one installer file, which would then extract all the other required files to run the actual program.
And even now im still wondering how you would code a program that extracts files that are literally still inside the program ( so not in some kind of zip) , i've seen tons of installers for games who have this. I need this cause I want to extract a file on the right moment without giving the person who uses the program the ability to delete the file before its extracted, this may seem vague, but I hope i've informed you enough.
I'm just going to say that building an installer is difficult.
I'd recommend using NSIS: http://nsis.sourceforge.net/Main_Page
As for creating a file the user can't access, create a temp file with the correct read/write permissions, extract the data to the temp file, then copy the file where it needs to go.
Extract happens without the user interfering, and copy protection is handled by the OS.
What about changing the build action for the file you want to hide to Embedded Resource, or something like that that compiles the file inside the dll/exe?
Executable program is just file, So you can append any data at you executables. (works for my c++ compiled program)
$ cat executables some_blob_data > new_executables
Since argv[0] of main() is name of your file, you can use this to acess data in this file itself (works for c or c++ and likley for other languages to)
A really simple way to do this is to use your archive tool or one of the dozens of already made installers. WinRar, WinZip and most others allow the creation of self extracting exe files. I know you've said that is not what you want but if you make sure to make it auto exec your installer app and remove all of the temporary files when you're done it really can be very fool proof and professional looking. Obviously, the various installer applications are able to do what you're wanting.
If you really want to do this yourself the easy solution is going to most likely be dependant on your IDE software and language. The generic answer is that you'll need a compression library which can accept a stream as input. Then you'll want to make your actual files into resources inside your installer app. At that point it's just a matter of telling the compression library to read from a stream which is pointed at the resource. How that is done varies greatly from language to language.
I am using a Lucene.Net index and want to give the user an option to move the index, but am having trouble closing it down so the directory/contents can be moved (I keep getting access denied exceptions). I need to be able to have some more information so I can debug this problem, such as being able to tell what files are currently open, and as much information about each use as possible.
Alternatively, is there any way to simply force close a bunch of files so they can be moved? This would make things a lot easier to solve.
You can use Process Explorer to find out which process has opened a file.
Hi does anyone know how to get windows explorer to pass multiple files / folders through to an external app (c#) referenced in the registry?
I am current able to act upon a single file / folder using the %1 syntax but not sure how to get explorer to pass through multiple items.
Does anyone know how to do this?
When you select multiple files in Explorer, your shell context menu extension's IShellExtInit::Initialize method will be called and pdtobj contains the selection.
Note writing managed shell extension is not supported.
I don't think this is possible.
When you open multiple files using Explorer, it will launch a separate copy of your program for file. I don't think it's possible to override this behavior.
EDIT: I forgot about shell extensions. This is possible.
To work around this, you could make the subsequent copies communicate with the first one, then exit. Detailed instructions for this are beyond the scope of this answer.
In order to do this reliably you would need to write a shell extension, most likely a sendto implementation.
I haven't written one since vb6 but you can find what looks to be a good managed example here
Or you could use a freeware utility
Is there a way to modify the behavior of the OpenFileDialog so that it looks inside the files in the folder it opens to and then ignores certain ones based on their content?
One example would be to open to a folder full of Zip files but only show the ones that contain a certain file.
From the documentation, there's the HookProc but I'm not exactly sure how I'd use it.
Please note that if it is possible, I realize that it'll be a relatively slow operation. At the moment I'm not concerned about performance.
Thanks!
I wouldn't dismiss the complexity of the OpenFileDialog. It's not so easy to build one that really works. When you do build your own, it's not the "normal" dialog and as a result it confuses users. This is true even if you do it well, which is difficult. So I'd suggest you stick to extending what is already there, rather than writing something new.
Check this article for an extension of OFD that might/could be tweaked to do exactly what you want. There's a callback that you write in C# that responds to path selection.
Related: FolderBrowserDialogEx is a similar extension on FolderBrowserDialog. Despite the name, you can configure it to search for files, as well as folders. There's a callback that gets invoked when something (a folder, a file) is selected, and within that callback you can do what you need to do. For example, peek inside the files within a folder and populate the list of files to display with only those files.
Another option you might consider is the dialog library from Ookii. This is an open source implementation of the OpenFileDialog, and it includes COM wrappers for all the new dialog stuff in Vista. Using that library you can pop a Vista OpenFileDialog and receive events from the IFileDialogEvents interface, in C# code. One such event is OnFolderChange(). Within the handler you could call IFolder.GetFolder() which will get you an IShellItem, which gives you the folder the user is changing to. The next step would be to itemize and potentially filter the set of files, which is an exercise I will leave to the reader...
No, you would have to implement your own functionality for that. But to be honest, the OpenFileDialog really doesn't do a whole lot anyway. To be honest, yeah, you probably could hook into it, but you'd be doing a lot of work for nothing when the real work is to inspect the content of the files and then you can write your own simple OpenFileDialog class on top of that.
You might find this question helpful regarding listing contents of zip files:
How to list the contents of a .zip folder in c#?
(Note, you could potentially thread it to improve performance, just don't span many threads)
You can probably use the Windows API Code Pack (comes with the source). The Common File dialogs feature exposes a lot more functionality of file dialogs than the versions in Winforms/WPF.
http://code.msdn.microsoft.com/WindowsAPICodePack