If I have a file path (that might be later passed to the ShellExecute API) is there any way to tell if it points to an application?
I need this to work under Windows from a C++ program. Also, this path may contain start-up command line parameters.
You can use the SaferiIsExecutableFileType function in order to check if the file is executable.
So you really want to know if a string that represents a command line has the path to an executable as its first "part". How you go about this kind of depends on how accurate you want the information to be.
First, you have to parse the string to get the first argument. It's not as simple as just looking for the first space, because Windows paths can contain spaces. You'll have to handle things like "c:\program files\internet explorer\iexplore.exe" "http://stackoverflow.com".
Searching for a file is a rather complicated process that involves searching the directories in the PATH environment variable. The SearchPath API function can help.
Related
I m trying to open a file using shellexecute command my code is
ShellExecute(NULL,NULL,itemPath,NULL,NULL,SW_SHOW);
or
ShellExecute(NULL,L"open",itemPath,NULL,NULL,SW_SHOW);
I have used both ways but when I m giving path of a folder it opens a folder but when I m giving a full specified path of a file it doesn't work.
one thing more if I m giving a hardcode path like for example
ShellExecute(NULL,L"open",L"E:\\abc.xlsx",NULL,NULL,SW_SHOW);
than it opens this file. can any one explain why it is happening.
ShellExecute works correctly, and the defect can be found in your code. The only explanation that makes sense is that itemPath is not what you think it is. If it were indeed a pointer to null-terminated character array containing L"E:\\abc.xlsx" then ShellExecute would behave as you expect.
You can debug the problem by inspecting the content of itemPath to find out what it really contains. Were you to have provided an MCVE then we could have been more specific in the diagnosis of the problem.
Finally, ShellExecute is deprecated, largely because it provides no good means of reporting failure conditions. You should use ShellExecuteEx instead.
So, is there a possible way to move Test.txt to C:\ProgramData\CsD2\Tools\("Unknown Folder Name")\data\per Using command prompt?
using foxidrives solution for your previous question for detecting the correct directory, then just
move test.txt "%folder%\"
Short answer: yes. Not quite sure what the situation is that has left only the middle part of your path unknown, and the need to use the comnand line, but I have encountered similar cases on Linux and expect the algoirthm can be adapted to Windows commands. It's possible to do this by hand rather than writing a shell script, but it's up to you and your skills.
Permissions matter. Make sure you elevate yours enough to read and write in Tools before continuing.
First, change directory to C:\ProgramData\CsD2\Tools\
Presumably there are many items here. Some may be "hidden," so list the contents of this directory and be sure to include an option to show hidden files and folders. If you can, restrict the search to directories only.
It's tempting to display contents recursively in the above step. It's up to you, but I find it makes the output cluttered without a script to do the rest of the work.
Now it's time to search for the subfolder set that theoretically only exists in your target folder. Suppose Tools contains the directories fldr1, fldr2, and fldr3. Use your command to list a directory's contents with the path "fldr1\data\per", then use "fldr2\data\per", and so on until it doesn't return an error. Per may be empty, but that should look different from the path not found error.
Now you've found the name of your mystery folder. Write it down for future reference.
At thus point, you know the path to Test.txt, and the full path to the destination directory. Do a move command to relocate Test.txt, and you're done. I like to relist the contents of the target directory after to be comfortable that it arrived.
When defining an environment variable (on Windows for me, maybe there is a more general guideline)
set MY_TOOL=C:\DevTools\bin\mytool.exe
if the tool is located on a path with spaces
set MY_TOOL=C:\Program Files (x86)\Foobar\bin\mytool.exe
should the environment variable already contain the necessary spaces?
That is, should it read:
set MY_TOOL="C:\Program Files (x86)\Foobar\bin\mytool.exe"
instead of the above version without spaces?
Note: In light of Joeys answer, I really should narrow this question to the examples I gave. That is, environment variables that contain one single (executable / batch) tool to be invoked by a user or by another batch script.
Maybe the spaces should be escaped differently?
I'd say, do it without quotes and use them everywhere you use the variable:
set MY_TOOL=C:\Program Files (x86)\Foobar\bin\mytool.exe
"%MY_TOOL%" -someoption someargument somefile
Especially if you let the user set the value somewhere I guess this is the safest option, since they usually tend not to surround it with quotes rather than do so.
If there are plenty of places where you use the variable you can of course redefine:
set MY_TOOL="%MY_TOOL%"
which makes things more resilient for you. Optionally you could detect whether there are quotes or not and add them if not present to be totally sure.
When your variable represents only a path to a directory and you want to append file names there, then the "no quotes" thing is even more important, otherwise you'd be building paths like
"C:\Program Files (x86)\Foobar\bin"\mytool.exe
or even:
""C:\Program Files (x86)\Foobar\bin"\my tool with spaces.exe"
which I doubt will parse correctly.
The command shell can answer your question: type C:\Pro and hit the tab key.
Autocomplete will leave all spaces as-is and add quotes around the filename. So, this is what is "officially" expected.
(this assumes that autocomplete is turned on, I'm not sure whether the default is on or off, but most people have it on anyway, I guess)
Does anyone know a pure Win32 solution for renaming a file and only changing its capitalization, that does not involve intermediate renaming to a different name or special privileges (e.g. backup, restore).
Since the Win32 subsystem generally regards two file names differing only in capitalization as the same, I haven't been able to find any solution to the problem.
A test program I made with the MoveFile API seems to work. So does the rename command in cmd.exe. What have you tried, and what error are you getting?
This isn't relevant, but further testing shows that renaming a long filename in this way works but will change the short filename (alternating between ~1 and ~2 for example), incidentally.
Just use the normal MoveFile API. That call probably just turns into ZwSetInformationFile(..., FileRenameInformation,...) The docs for FILE_RENAME_INFORMATION states that you need DELETE access and the file can't be locked etc, but those restrictions will probably apply to other solutions also.
I do not believe there is a way to expose two files with identical names that differ only in spelling to the Win32 subsystem. Even if some how you were able to create these files, the most likely result would be that only one file would be accessible - defeating the purpose of staying soley in Win32.
If you want to go into the Native layer, you can create a file with NtCreateFile and InitializeObjectAttributes w/o OBJ_CASE_INSENSITIVE or you can pad the end with extra spaces (if you pad with extra spaces, the file will not be accessible from Win32 dos paths). See here: http://www.osronline.com/ddkx/kmarch/k109_66uq.htm . I'm pretty sure you were already aware but I included it incase you did not know.
So long as your file is not immediately needed by another program, you can use my solution.
When you rename the file, capitalize, and delete the last letter. Then rename again and return the letter.
:)
It looks like all EXE files begin with MZ when they are opened in ASCII mode, is there an ASCII identified for vbs, com and bat files as well? i can't seem to find a pattern...
Or maybe there's another way to identify them? aside from just the extension...
No, not really (Windows executables can have PE or PK at the beginning instead of MZ - see this for other possible formats).
For other types of files, there are certain heuristics you can use (e.g. GIF files start with "GIF89", Bash shell scripts usually start with #!/bin/bash, BAT files often execute #echo off at the beginning, VBS scripts use apostrophe at the start of line as a comment marker), but they aren't always 100% reliable (a file can be both a BAT script and a Bash shell script; or a file that's both a valid ZIP archive and a valid GIF image (like that stegosaurus image), for example).
See e.g. this article for further reading.
TrID seems to have a "standalone" application you could probably use and pass the file in and read the contents out and see what file it is. It prides itself on the ability to pass it a generic file (extension or without) and it uses the headers of the file to discover what file type it actually is.
See if this tutorial is helpful (How to detect the types of executable files 3 part series). He has even presented a step by step algorithm on how to do this.
Also see this post: How to determine if a file is executable?