How Can I Get My File Association to Open Multiple Files in a Single Program Instance? - windows

I have set up a file extension in the Registry for my program as Windows requires.
In the Registry, under shell/open/command, I've got:
"C:\MyProgramPath\MyProgram.exe" "%1"
This works fine for me. When someone clicks on one or more files associated with my application, my application correctly opens the file(s) but each one is opened in a separate program instance.
Is there any way I can do this and open up all files in one program instance?

This is a rather common question, and it has really nothing to do with Windows file extensions. When you doubleclick a file of your program's custom type, Windows will start the associated application MyProgram.exe and pass the file name %1 as a command-line argument.
Now, if you want only a single instance of your application, you need to do this:
When your program (MyProgram.exe) starts, it should check if there is already an instance of it running.
If there is a previous instance, the new instance of MyProgram.exe should send a message (of some kind, not necessarily a windows message) to the old instance telling it to open the file %1.
The new instance should now terminate itself.
A very simplistic approach
There are several ways of accomplishing this. One of the simplest ways is to set a registry key/value each time your application starts, and remove it when the application exists. Then, when (a new instance of) your application starts, prior to setting this key/value, it should check if it is already set. If, so, follow the steps (2) and (3) above. This might not be the most stable approach (in fact it is a very bad idea, since you cannot guarantee that the app will remove the key/value when it exists if it does so abnormally), but it will give you the basic idea. Other, perhaps better ways, include FindWindow and, even better, the use of mutexes.
Step two might be implemented by sending a windows message (maybe WM_COPYDATA), or by setting a registry value, or, by writing a file, or ... There are many ways of communication between different processess.
The details
Since this is a rather common question, it has been dealt with before. See, for instance, this Delphi-specific article.

You can when using DDE. See http://cc.embarcadero.com/Item/17787 for an example in Delphi.
EDIT:
The link you gave talks about another method: using IDropTarget. This might fit better with your already running drag and drop capabilities.

Related

Write to file in use by another program

I'm creating a program (doesn't really matter the objective but it happens to be purely to mess around and learn more about windows) which reads and writes to a file which is in use by another program (for example notepad or word).
Obviously I'm having trouble deleting it as I'm getting an access denied error because the file is in use.
My first idea was I should use CloseHandle (kernel32.dll) to close the handle to that file, but I have no clue how to find that handle in the first place.
Any ideas? I'm doing this in Rust, so if there are any language-specific suggestions that would be best but if not, that's more than fine too.
On another note, what would happen to the program after the handle has been closed? Would word or notepad still be able to edit it or would a subsequent save delete the changes made by my program or perhaps it wouldn't even save?
This behaviour you observe is not related to Rust or to any other programming language, since this is system-specific.
The CreateFileA() win32 call offers, thanks to its third parameter (dwShareMode), a means to explicitly specify how sharing could happen with the open file.
Unfortunately (for you) this call is performed beforehand by the other program you try to hijack, not yours; your program cannot do anything, it's too late once the file is open.
Not that on UNIX the situation is different because the path to the file in the file-system is just a reference to the content of this file, as an open() operation is.
Thus, if you remove (rm) the file indicated by this path, you just remove the reference (unlink()) but not its actual content if it is still referenced by an open file descriptor.
The actual deletion of the file content only happens when no reference to it exists anymore.

Custom URL Protocol for Chrome as workaround for file:

I want to create a workaround for the URL protocol file: in Chrome, as it's security doesn't allow you to open certain files or locations. This would be for a small app of mine that I designed.
I searched around, and while I've found a lot of potentially good answers (such as this answer), I don't fully understand what each line should do, and whether it would actually work in my application.
The end-result that I want for this is to have a protocol like ih-link: that would allow me to open up links in Windows Explorer or elsewhere, similar to how you can do so in say, Outlook or Microsoft Word (if you create local or network shortcuts to a folder or file, it'll open it up without issue). Attempting this in Google Chrome gives varied results, either a browser-generated directory, or an error ususally.
I'd like to know, assuming the answer I linked to would work for me...
Is "URL Protocol"="" where I'd define the name of the protocol, so I'd use "URL Protocol"="ih-link", or something like that? I remember reading something about leaving that blank, so would I replace IntranetFileLauncher with whatever protocol name I want (in this case, it'd be ih-link?)
The next part that references explorer.exe seems to just reference the icon.
After that, what do the following two lines do?
[HKEY_CLASSES_ROOT\IntranetFileLauncher\shell]
[HKEY_CLASSES_ROOT\IntranetFileLauncher\shell\open]
The last lines of that script appear to just have it strip the protocol from the URL and pass the file path to explorer.. am I correct on this? I take it I would need to format the path as I would do for windows (using \ instead of /)?
I'm afraid to experiment without knowing more, mainly because I know that many things with the registry can be very dicey, so any clarification on this would be helpful.
Reading the actual documentation is better than trying to guess what some random code sample does.
URL Protocol is just a marker, it does not need a value. The default value (#) is where the name of your protocol is stored.
Yes, that entry (incorrectly) specifies the icon.
Those two lines are pointless. They create two empty keys but only the ...\shell\open\command line is required to properly build that registry path.
Yes, you might have to change / to \, add: call set url=%url:/=\% to the command.
Using cmd.exe to parse untrusted input is not ideal, it would be better to write a custom application.

Innovative Persistent Registry Entry Methods

Prepping for a CEH certification test. My question goes along these lines:
Situation: When attempting to add persistence to Windows malware, if the programmer chooses not to use one of the many existing RUN, AUTORUN, RUNONCE, etc. Windows registry entries ...
Question: Can he create an entirely new registry entry similar to \HKLM\SOFTWARE\My_Rootkit_Program\RUN and have it run automatically ... simply because it's named RUN?
Follow-On Question: Is the "magic" (repeatability) inherent in all registry entries named "RUN", OR does Windows use a concept similar to a PATH variable to locate and run those entries in registries named RUN (or similar)?
Follow-On Observation: If this latter hypothesis is correct, it follows that meddling with that registry PATH statement would be an advanced technique allowing programmers to build persistence into backwater places with names like \HKLM\SOFTWARE\CLASSES\7z\Updated_Compression_Routines.
Please forgive me (1) if this has been asked before and my searches didn't find the Q&A string (2) or I've misused specific terms.
Thanks ... Allen.
No, you cannot create your own runkey wherever you like. The valid runkeys are listed here. Of course, you also have the service keys at HKLM\SYSTEM\CurrentControlSet\Control\... which can be used to start drivers on boot. This can be used by rootkits, but generally malware will just use a normal runkey (or even place itself in the startup folder of the start menu).
Hope this helps.

How to let Windows know that a file is "being used" by my application?

I'm making a simple VB.net application, which basically asks the user for multiple files and later it will need to access the selected files and modify them.
Right now, I'm saving the full paths of the selected files, and in the future, the application will iterate through each path, open the file from such path, and modify it.
The problem with that is that the user could select a file (so the full path is saved) and then they delete or move the file before my application modifies it.
Normally, I'd throw an error saying "File not found", but I'm under the impression that Windows had a feature that would disallow you from deleting/moving/renaming a file because "a program was using it" - which is a feature that would fit way better for my application.
I'm not very advanced with VB.NET, but I suppose that if I "open" a file using my application (with some IO thing), the feature I mentioned earlier would indeed trigger and the user would be unable to modify the file because it is "opened" by my application.
However, since my only desire is to "reserve" files, it seems to be quite wasteful to actually open them when I don't really need to (yet). Is there a way to tell Windows I need a certain file to be intact?
Opening files (with specifying desired sharing mode) is the way to do that.
I don't believe there is anything really wrong with opening multiple files (also you still will not be able to do anything for cases like removing of removable drive). In old times there were restrictions on number of opened files per process, but I it no longer practical limitation - Pushing the Limits of Windows: Handles
There is an easy solution: open each file in exclusive mode.
It should look like this:
Sub test()
Dim FS = System.IO.File.Open("path", IO.FileMode.Open, IO.FileAccess.ReadWrite, IO.FileShare.None)
End Sub
But beware: You have opened a file handle and if you code responsible for closing files fails without terminating the application files will still be locked for very long (till app shuts down).
You can use a using clause or a try/catch/finally clause - I don't know enough about your program to recommend anyone.

NSFileCoordinator correct usage

when writing a file using NSFileCoordinator i need to specify the correct NSFileCoordinatorWritingOptions. Although they are explained in detail, I am not sure when to use which one. The available options are:
NSFileCoordinatorWritingForDeleting
NSFileCoordinatorWritingForReplacing
NSFileCoordinatorWritingForMoving
NSFileCoordinatorWritingForMerging
For example, what option is the correct one if I want to create a file (a plist for example)?
Wich one when I modify a file?
Can someone explain the NSFileCoordinatorWritingOptions for a better understanding?
I agree, documentation is not complete on that front, and hard to understand. And no sample code is available even for basic operations like these.
I try to think of these options in the perspective of other apps that have that specific file open, that helps getting the whole picture.
Pass no option (0) to simply update the file and notify others of your changes.
Let's say you are deleting a file that TextEdit currently displays, by providing the NSFileCoordinatorWritingForDeleting option, you're telling TextEdit to close the file as it does not exist anymore (or it could propose to save it to another place if it's in memory). It acts because of deletion.
If you're overwriting a file (as opposed to updating a file), you want about that same behavior for other apps. That's NSFileCoordinatorWritingForReplacing.
NSFileCoordinatorWritingForMoving says other apps to track the file to it's new location, so that it can be later updated.
NSFileCoordinatorWritingForMerging asks other processes to first commit their changes so that you can then merge your own changes with those.
To answer your question, you should use NSFileCoordinatorWritingForReplacing when creating a new file (even when no file exists, as it was to appear in the mean time from another app, you'd be replacing it with your own, unrelated contents). And NSFileCoordinatorWritingForMerging should be used when updating an existing file with new data, as it allows integrating the latest changes to that file immediately (instead of doing later with conflict resolution).

Resources