I need to open PDF and DOC files within my C++ project, the only limitation I have I can not use ShellExecute and WinExeute for opening extension files.
Now, I tried to open the files with WMI queries and OpenProcess() , but both these procedures require the Handler application path along with the path of DOC/PDF file.
I can not give the default handler application path, Is there any way to open files directly without specifying the Handler Application Path ?
You can resolve which application is associated with file you need to open. A start point here and here. It may be tricky because of various details you may need to take into account but it's what ShellExecute does.
If you know which application you want to use then search it in known applications (HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths). This is useful only if you know which file type you're handling and which application you want to use.
A more easy method may be to execute cmd.exe, you won't call ShellExecute and it'll do the job for you (executing default verb):
cmd /c MyFile.txt
In code (just an example...):
CreateProcess("cmd.exe",
"/c c:\\MyFile.txt",
NULL,
NULL,
FALSE,
0,
NULL,
NULL,
&startupInfo,
&processInformation);
Related
I am trying to use ShellExecute to open a .txt file in the default browser.
I am currently using
ShellExecute(0, L"open", L"http://E:/path/to/file.txt", 0, 0, 1);
This correctly creates a new window in the browser but tries to open
E/path/to/file.txt (without the ":")
and then can not find the associated file. The file location is definitely correct as manually adding the ":" back in the browser opens the file as desired.
Option 1
Use AssocQueryString or IQueryAssocations to figure out the default browser, then launch that browser with your text file on the command line.
Option 2
Create a temporary .html file with a <meta> tag that redirects to a file:// URL that loads the text file. Then ShellExecute with your temporary .html file. Since the temp file is of type .html, it should load the user's default browser. The redirect will then cause the browser to load the text file.
The trick is figuring out when to clean up your temporary file. ShellExecute doesn't make it easy to get a handle to the launched process (and, in reality, the process you launch may just launch another process), so you don't have an easy way to know when the browser is done with your temporary file. You might just keep track of the temporary files you create and try to delete them when your application closes.
ShellExecute will open a txt file inside the default text viewer, which isn't a browser I suppose. To open inside a browser, explicitely run the browser and give the file as argument. For example:
ShellExecute(
0,
L"open",
L"C:\\Program Files\\Internet Explorer\\iexplore",
L"E:\\path\\to\\file.txt",
0,
1
);
I am trying to open a local html document using Shell Execute(). But, what i need is, Suppose if that particular document is already opened and if ShellExecute is triggered again, then that particular file should not be opened again instead bring the already opened file into foreground. Can you please suggest how can i do this?
void main()
{
ShellExecute(NULL, "open", "C:\\prograomgiles\\help.html",
NULL, NULL, SW_SHOWNORMAL);
}
It's nearly impossible, because it depends on which program processes the html files and how does it work. Suppose, that my OS opens html files by printing them directly on a printer. How would you bring opened file into foreground?
If you want to display HTML content in the way specified by you, write your own browser (It's quite easy, you can - for example - embed IE in C#.NET application) and run it instead of default system browser. You would have then full control on how your files are displayed.
Many web browsers respond to DDE messages, particularly the WWW_OpenURL message. Not sure about other browsers, but IE also responds to WWW_GetWindowInfo and WWW_Activate messages, which you could use to enumerate open windows and their URLs, and then activate a particular window.
What are the main differences between the two? I'm willing to run only another EXE from my (C++) application. Are there any differences when inheriting environments, security features etc?
The main difference between CreateProcess and ShellExecute is the following: CreateProcess is more oriented on low level and ShellExec on the high user lever which see the user in explorer.
For example using of CreateProcess one can use command line which length is more as MAX_PATH. It has 32,768 characters restriction. You can also use CreateProcess to start program (if you have enough permissions) on another windows desktop like on the Logon Screen.
Another example. You can use ShellExecute to start Control Panel or open any program which existed on the computer for editing of JPG filed for example. So you works with ShellExecute close to the corresponding actions in the Windows Explorer.
The main difference is in flexibility. ShellExecute is easier to use, but doesn't have a lot of flexibility. CreateProcess is a pain to use, but lets you do anything.
Just for example, with CreateProcess, you can specify handles (pipes or files) to use for the standard input/output/error streams in the child. ShellExecute doesn't give you want way to do that.
It's probably also worth noting that although ShellExecute can be used to start an executable directly, its primary intent is to "execute" document files -- for example, tell it to "execute" a "whatever.html", and it starts up your default web browser and loads the specified HTML file into it. You can do that using CreateProcess as well, but to do it, you (normally) start by calling FindExecutable to find the program associated with the data file in question, then execute that passing your data file as a parameter.
CreateProcess returns the handle and id for the started process and it's main thread in the PROCESS_INFORMATION structure
I'am planning to write a sample program which identifies a file (a dll file) locked by / used by some process.
How can we achieve this programmatically using WIN API (a C/C++ function)? Actually, when we are performing some software upgrade process some other process might be using the library which will interim fail the upgrade operation.
The best example I would like to bring here is the Unlocker tool which lists all the process/dll which are using a particular file.
You could try opening the file(s) yourself for exclusive access. If any other process has them open, this should fail.
I don't think it is possible to determine the processes without writing a driver. Fortunately, Russinovich's Handle tool includes such a driver; I suggest that you run this tool.
If you don't need to know which processes use the file in question, you can simply open the file for exclusive access using CreateFile.
::CreateFile(filename, 0, 0, 0, OPEN_EXISTING, 0, 0);
In Windows, a file is not 'locked' or 'unlocked'. If a file is open, the share mode specified when opening it determines if and under what circumstances other attempts to open the file succeed.
If the FILE_SHARE_NONE flag is specified, then the file is completely locked, and under no circumstances will any other attempt to open the file succeed. If FILE_SHARE_READ was specified, attempts to open the file with GENERIC_READ access will succeed, but GENERIC_WRITE will fail, for example. FILE_SHARE_WRITE allows other handles open for write access, and FILE_SHARE_DELETE the same for deletion.
Once you've decided which level of exclusion you consider to mean 'locked', you can just try to open each file with the relevant access and see if it fails with ERROR_SHARING_VIOLATION or not.
Seems to me the windows API provides EnumProcesses() to easily get a list of active processID and EnumProcessModules to get a list of module handles (that if EXE and DLL's associated with it) for each process; finally GetModuleFileNameEx() gives you the full path and filename of the loaded module.
Thus you could easily iterate through all the loaded DLL names and at least know which process was holding them if you detected a problem - and possibly automatically end that process.
I'm trying to make a small program that could intercept the open process of a file.
The purpose is when an user double-click on a file in a given folder, windows would inform to the software, then it process that petition and return windows the data of the file.
Maybe there would be another solution like monitoring Open messages and force Windows to wait while the program prepare the contents of the file.
One application of this concept, could be to manage desencryption of a file in a transparent way to the user.
In this context, the encrypted file would be on the disk and when the user open it ( with double-click on it or with some application such as notepad ), the background process would intercept that open event, desencrypt the file and give the contents of that file to the asking application.
It's a little bit strange concept, it could be like "Man In The Middle" network concept, but with files instead of network packets.
Thanks for reading.
The best way to do it to cover all cases of opening from any program would be via a file system filter driver. This may be too complex for your needs though.
You can use the trick that Process Explorer uses to replace itself with task manager. Basically create a key like this:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\taskmgr.exe
Where you replace 'taskmgr.exe' with the name of the process to intercept. Then add a string value called 'Debugger' that has the path to your executable. E.g:
Debugger -> "C:\windows\system32\notepad.exe"
Every a process is run that matches the image name your process will actually be called as a debugger for that process with the path to the actual process as an argument.
You could use code injection and API redirection. You'd start your target process and then inject a DLL which hooks the windows API functions that you want to intercept. You then get called when the target process thinks it's calling OpenFile() or whatever and you can do what you like before passing the call on to the real API.
Google for "IAT hooking".
Windows has an option to encrypt files on the disk (file->properties->advanced->encrypt) and this option is completely transparent to the applications.
Maybe to encrypt decrypt file portions of a disk you should consider softwares like criptainer?
There is this software as well http://www.truecrypt.org/downloads (free and open source) but I haven't tried it.
Developing a custom solution sounds very difficult.