Filesystem Hook for .doc open C# - c#

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).

Related

Update file, not replace or overwrite

this is more of a question because I am experimenting with this.
All over the internet I see how you can update a .txt file. Well that is all good and well, but lets say I have a .doxc or even an .exe or even a .dll file.
If we make a minor change to a file, do we really have to replace(overwrite) the whole file?
Is it possible to "update" the file so that we don't use too mush data (over the internet).
What I am trying to achieve is to create a FTP client with a FileSystemWatcher. This will monitor a certain folder on the Computer. If anything changes in this folder (even sub directories) then it uploads, deletes, renames, or changes the file. But at the moment I am wondering if I have, lets say, a 20MB .exe file or whatever, if it is possible to change something in that .exe, instead of just overwriting the whole thing... thus, sparing some cap.
In general, it's possible to update the remote file only partially, but not in your case.
What would work:
1) track the file change using a filesystem filter driver, which gives you information about what parts of the file have been updated.
2) use the protocol which allows partial upload or remote modification of the file (eg. SFTP).
As for your scenario:
Step 1 is not possible with FileSystemWatcher.
Step 2 is not possible with FTP protocol which doesn't support modification of file blocks.
Since your are experimenting, I can provide some pointers. But I dont know for sure if the below operations are just updates or replaced newly by the underlysing os calls
Have different cases for each file type. Try with a basic types first, a txt file, then a binary file etc.
You should have the entire copy of the current file somewhere, sine you "should" compare the old file to know what changes
Then when a change is made to the file compare it with the old file e.g) in a text file with 1 MB and the change is only 1 KB you will need to build a format like
[Text][Offset][[operation]
e.g) [Mrs.Y][40][Delete] then [Mr.X][40][Add]
Then your ftp client should be able to implement this format and make changes to the local copy on the client.
No it is not possible to only upload the changes to .exe file.we have to overwrite it.
#Frederik - It would be possible if FTP supports an updating of resource like HTTP's PUT command. Try exploring that angle. Let us know if you find something.

Is it considered good/acceptable practice to save a file in the temporary directory?

I am developing a WinForms application using C# 3.5. I have a requirement to save a file on a temporary basis. Let's just say, for arguments sake, that's it's for a short duration of time while the user is viewing a particular tab on the app. After the user navigates away from the tab I am free to delete this file. Each time the user navigates to the tab(which is typically only done once), the file will be created(using a GUID name).
To get to my question - is it considered good practice to save a file to the temp directory? I'll be using the following logic:
Path.GetTempFileName();
My intention would be to create the file and leave it without deleting it. I'm going to assume here that the Windows OS cleans up the temp directory at some interval based on % of available space remaining.
Note: I had considered using the IsolatedStorage option to create the file and manually delete the file when I was finished using it i.e. when the user navigates away from the tab. However, it's not going so well as I have a requirement to get the Absolute or Relative path to the file and this does not appear to be an straight-forward/safe chore when interacting with IsolatedStorage. My opinion is that it's just not designed to allow
this.
I write temp files quite frequently. In my humble opionion the key is to clean up after one self by deleting unneeded temp files.
In my opinion, it's a better practice to actually delete the temporary files when you don't need them. Consider the following remarks from Path.GetTempFileName() Method:
The GetTempFileName method will raise an IOException if it is used to
create more than 65535 files without deleting previous temporary
files.
The GetTempFileName method will raise an IOException if no
unique temporary file name is available. To resolve this error, delete
all unneeded temporary files.
Also, you should beaware about the following hotfix for Windows 7 and Windows Server 2008 R2.
Creating temp files in the temp directory is fine. It is considered good practice to clean up any temporary file when you are done using it.
Remember that temp files shouldn't persist any data you need on a long term basis (defined as across user sessions). Exaples of data needed "long term" are user settings or a saved data file.
Go ahead and save there, but clean up when you're done (closing the program). Keeping them until the end also allows re-use.

c#.net application which can opened while opening a folder

I would like to create a c# application which will open when i open a folder automatically.
My c# application is intended to be like a password system, so that the contents in the folder can only viewed after logging in to my application. Everything is ready..........
but i am confused how to open my application directly while opening the folder with a c# script?
I have now created a application which will ask the user for name and password while opening the application and now i want to make it open through the folder to be locked , how to do it?
Ok, first of all if you want the folder to be secure you should encrypt it otherwise all the user has to do to gain access is kill the process.
What i would recommend you do instead is create a encrypted file. For example a zip file. Then all you have to do associate the file with the program and to unpack it with the password. Then when the user is done delete it and overwrite the temporary folder. It's really important that you overwrite it otherwise the encryption is useless.
If you want to avoid conflict with other programs that work with zip files you can make your own file type it does not affect the content of the file in any way.
I hope this helps.
To make sure I understand... you want to build an application that will, when someone tries to open it, will only open after they supply a password. Hmmm... okay. A specific folder, or any folder? Local folders or folders on network shares? I initially was thinking a file system watcher approach, but that will only work on change events, like copying, renaming, deleting, etc. So that won't work. The closest would be to check last accessed time, but that is an alert ex post facto, so this must be rejected. I'm not sure how you could do this in C#. What is wrong with the robust security options MS has already established, like global groups. That provides flexible restrictions on access. Especially over large amounts of folders. Are users going to have one password per folder? Too cumbersome. One password per user? Use Windows authentication to lock it down. How is this app storing the passwords?
I recommend trying to leverage existing technology to solve problems before trying to re-invent the wheel. You have omitted the scope of this, and what you have already attempted, so we may not understand completely.

Programatically get path of open Excel/Word-document

Is there any way to get the path of documents currently open in Microsoft Word and Microsoft Excel?
I know how I can fetch the PID and the window handle for the running instance of Excel or Word, but I have no idea how to get the path of the open document. Is it even possible?
I am thinking that an API would be nice, but I doubt it even exists. Perhaps some kind of plugin that sends information to my application is a possibility? (But if any other way is possible, I'd like to avoid having to install plugins everywhere.)
I would prefer to do it using C#, but anything that can be compiled into an executable is alright.
And just in case someone thinks this sounds fishy, it is not to be used for anything remotely illegal. It is for a data collection system at work.
There is an API called Office Interop... it is basically a COM based interface for MS Office... and can be used from C# .
For Excel you can get the current file including path via Application.ActiveWorkbook.FullName.
For Word you can get the current file including path via Application.ActiveDocument.FullName.

Why do custom file properties, set using the DSOFile library, not persist after saving?

I am currently working on a plugin for AutoCAD that allows users to interact with a document versioning application, and in order to sync files between the remote repository and local machine, I had planned on using custom file properties. The properties would be set when a file is initially downloaded, and then persisted for as long as the file remains on the user's local drive. I am not really interested in an AutoCAD-specific solution, because my plugin will deal with files other than AutoCAD drawings (text files, image files, among others). Therefore, I want a library that can handle as many potential file types as possible.
When searching for how to implement this kind of thing in C#, I almost immediately came across the DSOFile library. Everything I read said it was designed for MS Office, but that it should work with any file, as long as the file system is NTFS (at least that's my understanding). I had no problem setting custom properties on files such as plain-text documents (.txt), AutoCAD drawings (.dwg), and images (.jpg, .tif, etc). However, I noticed that once any of these files were saved, the custom properties were wiped out. The only case in which I saw custom properties were persisted after saving, were on MS Office documents. I figured this issue was related to the application that I was using to save the files (AutoCAD, MS Paint, notepad, etc), but I can't be 100% sure of that. Before I decide to go with a solution other than using DSOFile, I wanted to see if anyone on SO had some insight in to this issue.
I tested using my own code and using the demo that comes with DSOFile, and saw the same result both times. Custom properties were wiped out after saving any type of file other than an MS Office (Word and Excel) document.
Here is an example similar to the code I would use to add a new custom property...
var docProperties = new OleDocumentProperties();
docProperties.Open("myfile.txt", false, dsoFileOpenOptions.dsoOptionDefault);
try
{
object value = "some value";
docProperties.CustomProperties.Add("MyCustomProp", ref value);
}
finally
{
docProperties.Close(true); // save and close
}
This may be too late but I've used this a bit or Autodesk Revit RFA files as well as PDF files and it works fine. You can't edit them while the RFA is open though.
Did you call docProperties.Save() at all?

Categories

Resources