Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations gkittelson on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Submitting a file to MSE with ShellExecute

Status
Not open for further replies.

dkean4

Programmer
Feb 15, 2015
282
US
On one of the recent updates, Microsoft removed the setting on the Context menu to submit individual files to the MSE... (checking for viruses, trojans etc... on selected files) So, I am trying to build an app, which will let me drag a file to a VFP app to do the same. When I use the Run command it works just fine. But trying to implement the ShellExecute I seem to run into briers. In the code below I use both techniques.

Code:
*  Test file for viruses and bugs with MSE, now that they removed the right click ability to test individual files.
? FileVirusCheck()

FUNCTION FileVirusCheck
	LPARAMETERS cFileName, cDirectory, cOptions, pathFile, resultFilePath
	LOCAL cOpts 

	DECLARE INTEGER ShellExecute IN shell32.dll ; 
	  INTEGER hndWin, ; 
	  STRING cAction, ; 
	  STRING cFileName, ; 
	  STRING cParams, ;  
	  STRING cDir, ; 
	  INTEGER nShowWin

	cAction 		= "open" 
	cFileName 		= "C:\Program Files\Microsoft Security Client\MpCmdRun.exe "
	cDirectory 		= ""
	cOptions 		= "-Scan -ScanType 3 -File " 
	pathFile 		= "C:\Users\Dennis\Desktop\CH341SER.EXE "
	resultFilePath	= " > "+SYS(5)+ CURDIR()+"FileVirusCheck.danny"   &&  LOCAL path where the result file should be created 
	cOpts= cOptions + pathFile + resultFilePath

	CMD = cDirectory + cFileName + cOpts
	RUN &CMD        &&  THIS WORKS FINE
	
	ShellExecute(0,cAction,cFileName,cOpts,cDirectory,1)    &&  THIS FAILS NO MATTER WHAT I TRY

	*MODIFY FILE safetyTest.danny

	RETURN FILETOSTR(SYS(5)+ CURDIR()+"FileVirusCheck.danny")
ENDFUNC

As I said, the RUN Command works just fine.

On the ShellExecute line I get this error which appears for a fleeting moment and I had to use a camera to catch the error:
ERROR said:
Bad Command Line - Command Line - Option should start with '-' or '/'

CmdTool: Failed with hr = 0x80070667. Check C:\Users\Dennis\AppData\Local\Temp\McmdTool.log for more information:
CmdTool: Invalid command line argument

So like a good boy I go to that log file and fetched the log recording of the failed command, whose command line is supposedly invalid.

Log file listing said:
-------------------------------------------------------------------------------------
MpCmdRun: Command Line: "C:\Program Files\Microsoft Security Client\MpCmdRun.exe" -Scan -ScanType 3 -File C:\Users\Dennis\Desktop\CH341SER.EXE > F:\A_A\FileVirusCheck.danny
Start Time: ‎Thu ‎Nov ‎17 ‎2016 16:31:57

MpCmdRun: End Time: ‎Thu ‎Nov ‎17 ‎2016 16:31:57
-------------------------------------------------------------------------------------

The funny thing is that if I take that Command Line as it is recorded in the Log file and run it into the CMD window to test how it fails, IT WORKS PERFECT! And, yes, I am piping the result to a file called F:\A_A\FileVirusCheck.danny.

Trump was right... It is all fixed behind the curtains... [ponder].

Please help...

Dennis Kean

Simplicity is the extreme degree of sophistication.
Leonardo da Vinci
 
Redirecting is something that cmd.exe does. MPCmdRun.exe does not know how to pipe. When you're using the command prompt, or VFP's RUN command, you're executing cmd.exe, but when you're using the ShellExecute method, you're just running MPCmdRun.exe, and passing to it the options it can handle (and that must start with - or /).
 
I agree with Atlopes. Think of ShellExecute() as doing what its name indicates: it executes Windows Shell operations. It's the programmatic equivalent of right-clicking on an object in the Windows shell (typically a file or a directory), and selecting an action (such as Run, Open, Print, Edit) from the resulting context menu. The object is the cFileName parameter, and the action is the cAction parameter.

Clearly, you can't introduce piped output (the string beginning with the ">" character) to that scenario. There is nowhere for the results of the action to go.

As far as I can see, your only option is to revert to the RUN command.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Dennis, if we can go back to the original problem .....

Is there any special reason why you need to implement this functionality? Are you aware that MSE scans files and directories in the background, and there is rarely any reason to have it scan an explicit file?

If you do have a good reason to scan specific files, have you tried to restore the right-click functionality? I don't know if there is an "official" way of doing that, but you could always revert back to a previous update. As far as I can make out from a quick perusal of the Microsoft site, it was update 4.10.205.0 that took the right-click feature away. If you could revert to the update before that, it should solve the problem. On the other hand, there is a good argument for always keeping MSE up to date, so you might prefer not to do that.

Or have you considered using a different AV program? I know that AVG (including the free version) has a scan option on the context menu. No doubt others do too.

Of course, you might have other reasons for creating your own tool in VFP. That's always a good option.

Mike

__________________________________
Mike Lewis (Edinburgh, Scotland)

Visual FoxPro articles, tips and downloads
 
Don't implement any API call half only. ShellExecute has a result and that has a meaning, either it says everythings right >32 and its a hinstance handle, or it's an error number. So if ShellExecute fails, well, look into its result, it'll have a meaning.

MSDN said:
If the function succeeds, it returns a value greater than 32. If the function fails, it returns an error value that indicates the cause of the failure. The return value is cast as an HINSTANCE for backward compatibility with 16-bit Windows applications. It is not a true HINSTANCE, however. It can be cast only to an int and compared to either 32 or the following error codes below.

Well, and the below list is in there, in the MSDN description of the function. All reference is there, you just have to look into it.

Bye, Olaf.
 
Besides, we already had in detail, what Run means, it means calling whatever is specified in %COMSPEC%, and that's cmd.exe. When you start a windows executable you better use RUN /N to directly run the MpCmdRun.exe.

What could be he case is, that RUN is giving you a false positive run, you succeed in running cmd.exe, but it fails in the same way, just not reporting any error back as that happens in cmd.exe, but you succeeded in running cmd.exe.

In detail vfp runs cmd.exe with /k parameter to let cmd.exe do the rest of the command, which can therefore also be a shell command, a cmd implemented in the cmd.exe, not any further EXE call. It's useless to go through cmd.exe, if what you want to execute is already an exe itself. RUN /N is for starting that directly without going through cmd.exe or any API function.

Bye, Olaf.
 
Atlopes and Mike,

It makes perfect sense. I'm getting old and silly. I was not using my head. Ha ha ha... [blush]. Thank you for setting me straight.

Mike, in answer to your question, I am building an automation device which will do lots of things on its own Emailing receiving Emails and Downloading. Downloading includes extracting and running files from the download. I don't want to have hands on, in this process until a future time. So, figuring out what went wrong per each download is essential. The error info from MSE is great. It lends itself to this process so well. So, it can react to everything which is different from normal, set the file aside and I can look at it later.

Again, thank you for setting me straight.




Dennis Kean

Simplicity is the extreme degree of sophistication.
Leonardo da Vinci
 
Olaf,

First, thanks for thinking with me, on this. The error from the MSE is more specific and more informative. That is why I want to harvest it. This is an automation device for downloading and getting Email attachments which need to be extracted and tested for viruses, so I can make a list for when I get back home and want to see which files are available for further processing by me. And no, actually I do get the proper MSE warning... (if or not the file is free of bugs or not.) It is explicit and fits nicely in a list with the file name and location etc... I am getting true positives. The messages go straight into the piped file.

While your idea is useful, I need the result from MSE to know how to proceed, when I am ready to look at it.

Thanks for your concerns. As always good thinking, Olaf...

Dennis Kean

Simplicity is the extreme degree of sophistication.
Leonardo da Vinci
 
I don't understand what you address. I was never questioning your use of MSE, just your use of ShellExecute and RUN vs the right choice of RUN /N. And if you still want to go for ShellExecute and want to find out why it does not work, look at the result you get from the ShellExecute call. That's all to it.

Bye, Olaf.
 
Olaf,

And you cleared it up. Thank you for that. I got it.




Dennis Kean

Simplicity is the extreme degree of sophistication.
Leonardo da Vinci
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top