Open files...

Given a Process (Process ID, whatnot), is it possible to establish what files are currently in use / locked by that process?

I've looked all over but I can't find a good example of this. A lot of talk about internal windows APIs (getNth something or other) immediately followed by dire warnings that you shouldn't use those. Fine. But then what SHOULD you use?

Please, a simple example in VB.NET, if you don't mind. C# at a push, but preferably VB.NET

Thank you kindly.
LVL 4
WernerVonBraunAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

ste5anSenior DeveloperCommented:
Well, as you want it simple: Imho there's no simple solution.

Especially that this task requires a kernel driver. For details see Listing Used Files.
0
anarki_jimbelSenior DeveloperCommented:
As ste5an told there are no simple solution. Again, it depends on your task what solution you may use. Read this for a VB.Net example: [URL="http://www.xtremevbtalk.com/showthread.php?t=297132"]Determine if File is in Use[/URL]
0
WernerVonBraunAuthor Commented:
Ugh.... seriously?
0
Cloud Class® Course: Microsoft Windows 7 Basic

This introductory course to Windows 7 environment will teach you about working with the Windows operating system. You will learn about basic functions including start menu; the desktop; managing files, folders, and libraries.

ste5anSenior DeveloperCommented:
Yup. It's time to get the C/C++ from the attic and free it from all the dust :)

When you really need it: then there is imho no other solution than setting up a secondary C/C++ solution (e.g. a Windows service) and IPC with it.

Another approach: use Handle. But this requires a complex setup, cause you're imho not allowed to distribute it.
0
WernerVonBraunAuthor Commented:
I just tried "Handle" but it doesn't work. For example, I opened an excel spreadsheet, and then ran "Handle excel". It gave me a list of DLLs it was using, which is lovely, but the .xlsx file that I had just opened was not among the list of files...

Maybe I'm barking up the wrong tree altogether. Here's the actual situation I need to deal with:

We have created an Outlook Add-in. This Add-in stores messages from outlook into our repositories, by saving them out as .msg files. When someone opens a message, the system checks whether that message is already stored in the system. This is where the pain starts.

If we were just looking at messages in Outlook, it would be so easy. All we would need to do in that case is get the sender's SMTP address and the date/time on which the message was sent, and use that as a "key" in our database, in order to check whether information about that message is already stored. Now Outlook doesn't even make your life easy there, but thankfully there is a product called "Redemption" that works around some of those limitations, and it pretty much always works.

But if you're outside Outlook, all you have is the .msg file. When you launch that, it starts Outlook alright, but the message in question won't have an EntryID. Now I worked around THAT problem  by moving the MailObject into the Deleted Items folder, which is equivalent to making it part of Outlook's actual message store rather than an external .msg file, at which point it does get an EntryID.

But now I have found a number of scenarios in which even then I am unable to establish the sender's SMTP address. Even Redemption is powerless to help, here. So if only I know which .msg file was opened.... I have a "MSG Reader" class that can open .MSG files and read information out of them. But do you think Outlook exposes something like a ".filename" property on the MailItem object? Mwahhaaahahahahahaahahahahah [twitching eyelid]

So I thought "you know what, all I need to do is find out which files have been opened by Outlook"

But obviously that is a non-runner as well.


gngngngngng


*pop* goes the aneurysm
0
ste5anSenior DeveloperCommented:
First of all: Please define "message"?

In the common sense this means e-mail. Thus you need not the senders address, but the message-id. When it's not present, I would use a hash of the entire message. Especially as the pair sender's SMTP address and the date/time is not guaranteed to be unique.

I'm not sure whether I understand your .msg-file approach, but when you're dealing with files: use a hash of the file as identifier.
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
WernerVonBraunAuthor Commented:
Well, now. First of all, SMTP address + sent date/time is pretty much unique. None of our customers will ever be archiving SPAM, and other than that I can see no conceivable scenario in which the same sender would send more than one message at the same second.

Having said that, the "hash" scenario can't work either. What would I be "hashing" when I'm in an actual Outlook message? There is no guarantee that the "hash" would be the same if: a) a user saves the message more than once or (even worse) b) two different recipients save the same message.
0
WernerVonBraunAuthor Commented:
The problem is that there are so many different ways to access what to the human looking at it would be "the same message". A user could have the message sitting in their Inbox in outlook. Another user could open the saved .msg from our software's "message store". Even the latter is not consistent. One user could open the saved .msg from our message store through our software, another one could bypass our software and navigate directly to it. A third user could manually save the message into their own file system and open it from there. In all these scenarios it should accurately identify that message as having already been stored. Hilarious *sob*
0
ste5anSenior DeveloperCommented:
First of all, SMTP address + sent date/time is pretty much unique. None of our customers will ever be archiving SPAM, and other than that I can see no conceivable scenario in which the same sender would send more than one message at the same second

Yes and no. Write mails off-line and go online again. tada.

Having said that, the "hash" scenario can't work either. What would I be "hashing" when I'm in an actual Outlook message? There is no guarantee that the "hash" would be the same if: a) a user saves the message more than once or (even worse) b) two different recipients save the same message.

Hash the entire message. In a clean OOP architecture you have already your own class encapsulating messages. Thus use the GetHash() method of this class. Implement GetHash(). For Outlook messages it's afaik quite simple: Each message has a path according to its storage. Use this path (Namespace (name or StoreID) and Folder(EntryID or FolderPath)).

a) When the hash differs, the message differs. Why ignoring those differences?
b) When the hash is the same, then the messages are the same. Why does the recipient play a role?
0
WernerVonBraunAuthor Commented:
> Use this path (Namespace (name or StoreID) and Folder(EntryID or FolderPath))

No can do. Imagine an organisation X, in which person A sends an e-mail to persons B, C and D

Person B simply leaves the message in his or her Inbox
Person C has a rule set up that moves the message to some other Outlook folder
Person D saves the message to their hard drive as a .msg file (people do silly things)

Person B opens the message and uses our Add-in to store it in our repository. Obviously, when Person B opens the message a second time it should tell him or her that the message is stored in our repository.

When person C opens the message from their different location, the Add-in must identify the message as having already been stored in the repository. So, by the way, must it be when the sender (Person A) of the message opens the message from their Sent Items folder. And when person D double-clicks on the .msg file.... you guessed it.
0
ste5anSenior DeveloperCommented:
That's exactly what I've described. You load a message into your class. The source is not important. Your class implements GetHashCode(). The actual loading and the actual GetHashCode() is implemented with the strategy pattern. The strategy depends on the source type and is provided by a builder. After loading it, you can query your add-ins store for messages with the same hash. Thus disabling further processing.
0
WernerVonBraunAuthor Commented:
ok, I'm afraid that went way over my head.

> "Your class" - what class?

> GetHashCode()
Well, as far as I understand this, Hashing processes binary data and produces from that a short "hash", a string or whatnot, that is almost guaranteed to be unique. Well, this is the problem, isn't it? MAYBE, and I wouldn't even count on THAT, Outlook would produce identical Binary objects when it loads the various copies of the message from A's Sent Item folders and from B and C's Outlook folders. But I'm pretty damn sure that it will not produce an identical Binary object from opening D's ".msg" copy of the e-mail.

What *might* work is this: I could take the .Body (text) from the MailItem object, and produce a Hash from that.
0
ste5anSenior DeveloperCommented:
"Your class" - what class?

Okay, let's talk about OOP:

You said that you store messages in your own add-in, right? How do you do this?

Object oriented programming tells use to encapsulate entities in classes. Thus there should be a class Message in your source tree. Does such a class exist?
0
WernerVonBraunAuthor Commented:
Okay, let's talk about Outlook Add-ins.....

Messages are presented to me, through the magic Voodoo of Outlook, as so-called MailItem objects. Where they come from and where they go is a mystery to confound. All we can do in our data repository is store metadata about said objects. We do not store the objects themselves, nor is the software retrieving them from our data repository. Outlook does all that. We're at its mercy. And it's a sea of pain we're swimming in.
0
ste5anSenior DeveloperCommented:
So you have an open handler where your add-in hooks into?
How do you read and store the meta-data?
0
WernerVonBraunAuthor Commented:
Outlook exposes events for its "Explorer"s (which are, essentially, the outlook folders such as "Inbox", "Sent Items", "Deleted Items" and so on, and for its "Inspector"s (which are the "windows" that host the message when it's displayed to the user. When that event triggers you can, in your "Add-in" code, do things like ask Outlook to give your Explorer's Selected Items or your Inspector's CurrentItem, which may (or may not) be an object of type Outlook.MailItem (it can also be an Appointment or a number of other object types).

For example, when a user double-clicks on a .msg file, the Add-in would register that a new Inspector object is loaded, and then access its CurrentItem object, cast it to an Outlook.MailItem and then discover that is has no EntryID or that it's impossible to establish the SMTP address for the MailItem's Sender.
0
WernerVonBraunAuthor Commented:
I read data directly from the MailItem object by accessing its properties, or in some cases I have to use "Redemption" - for example when I want to get the SMTP address for an Exchange sender (if you get the Address directly from Outlook itself it'll give you some insanely formatted mail address in Exchange format, which makes no sense to anyone).

We store the mail items by using the .SaveAs function to create a ".msg" copy, and then storing that copy away. But the user doesn't see that, nor do they care. They may still see the message in Outlook and open it from there.
0
WernerVonBraunAuthor Commented:
We need the .msg copy because - to continue with the above example - while the e-mail is still happily sitting in A's Sent Items, B's Inbox and C's personal folder, D may well have deleted the message from Outlook and then access it again through our application's repository, or it could even be a case of E (another person in the organisation who was never involved in the e-mail exchange) finding the message in our application and launching it from there.
0
ste5anSenior DeveloperCommented:
I read data directly from the MailItem object by accessing its properties,

How and where do you store this values? These values should be stored in one object per MailItem. And the GetHashCode of this class is your key. Additionally as you said you store the .msg file, the hash of the file is also a property of this class
0
WernerVonBraunAuthor Commented:
[bashes head against desk]

Please... it's *outlook*. Outlook is a Microsoft product. We have NO control over how Microsoft handles its MailItem objects internally, how it creates them from its own storage and how it stores them. We have NO control over how Microsoft saves an Outlook MailItem object when the user chooses "Save As" and decides to save it as a .msg file on their own hard disk. All we can do is consume the MailItem objects if and when Microsoft deigns to expose these to us.
0
ste5anSenior DeveloperCommented:
Sorry, but I have to give up...

Seems that the data from Outlook tunnels to your add-in...
0
WernerVonBraunAuthor Commented:
Yup. Let me tell you something. If somebody ever suggests to you that you should develop an Outlook Add-in for them, RUN. RUN LIKE THE WIND. And don't look back. LOL - but seriously, it's friggin' evil. It's like Microsoft have gone out of their way to make a developer's life hell.

Thanks for trying to help though. It's appreciated.
0
WernerVonBraunAuthor Commented:
However, while this is ugly and by no means foolproof, your idea of Hashing is not a bad one. It's just that I may have to do it with something that is not likely to change, for example the message subject and the message body, in combination with the sent date/time. I might apply that as a "fallback" for when Outlook and Redemption fail to generate an intelligible SMTP Address from the MailItem object. It's not ideal, but it's better than a kick in the teeth. So I'll give you the poinks for that.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Visual Basic.NET

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.