How can I execute a program from my VS2008/C++ application in windows that replaces the caller and runs on xp/vista/7? - c++

My application downloads updates from a server. After downloading it runs updater.exe (which is set to run with administrative rights) so it can copy the update foo.exe over my application. Since you can't replace the file while it runs the helper application is necessary.
I am making the following system call to run it:
result=_execl(updaterexe,updaterstr,updateFilestr,exeFilestr,exeFilestr,NULL);
The parameters contained:
c:\program files\foo\updater.exe "c:\program files\foo\updater.exe" "c:\downloads\newfoo.exe" ""c:\program files\foo\foo.exe"
Under vista this works as expected.
Under windows 7 it returns error code 22 which is invalid parameter. I have also tried quoting the first parameter to no avail. Suspecting that maybe the old _execl was not supported on windows 7 I tried adjusting all the parameters and calling _wexecl but with no change in behaviour.
Can anyone suggest a correction to the call I'm making or suggest a different system call that will work consistently between versions of windows?

There are plenty of other alternatives, any of which would work from Windows 95 up:
CreateProcess() // Recommended Win32 API
ShellExecute ()
system ()

Related

The Windows SDK sample (Namespace Extension) does not run correctly on Windows 11

I want to implement a Namespace Extension and custom column filtering.
I tried to run this sample from Windows SDK 7.1, in Windows 11:
ExplorerDataProvider
This sample implements a Shell Namespace Extension including custom categorizers.
I made some changes to fix the missing IID_IItemCategorizer and an Access Violation when LoadString() is called.
I debugged the code of Category.cpp and I realized that all expected functions are not being called.
The functions should be run in below sequence:
CFolderViewImplCategoryProvider::GetCategoryForSCID
CFolderViewImplCategoryProvider::CreateCategory
CFolderViewImplCategorizer_Name::GetCategory
CFolderViewImplCategorizer_Name::GetCategoryInfo
But, after successfully running the first 3 functions, GetCategoryInfo() is not being called.
Is it because of Windows 11? Is the SDK not updated? Or did I make a mistake? How can I fix this?

Run MPI Application from Visual Studio 2017 with each process in a different cmd window

Using Visual Studio 2017 I am trying to run a MPI Application which resembles a Spades game. Upon running it I want to open a cmd terminal for each of the 4 players so that each of them can input his card choice upon his turn to act.
I tried a ton of options, including going to Project Properties -> Debugging and changing the Command to $(MSMPI_BIN)\mpiexec and Command Arguments to -np 4 "$(TargetPath)" - see link below:
Command and Command Arguments
but, apart from getting 4 processes to run at the same time I still get a single terminal open which doesn't react to any of my keyboard input.
Is there any way to open 4 terminals using the Visual Studio debug? Or any other way? running "mpiexec.exe -np 4 MyExec.exe" in a cmd / bash provides the same result as above.
Thanks in advance
I think this is not possible.
I have tried to use AllocConsole() on an mpi test program and each process returns an error because it considers that there is already a console attached to it.
In a way it seems logic because mpiexec will launch the processes and every stdout will directed to the same output (file or console), as for stdin you have to choose which process will handle it (judging by the manual https://www.open-mpi.org/doc/v3.0/man1/mpiexec.1.php -stdin option).
These redirections being surely managed by the process manager (https://wiki.mpich.org/mpich/index.php/Frequently_Asked_Questions)
As #Evg said judging by "the Spades game" allusion I think MPI is not what you need. Maybe more unix domain socket. But they are other ways to do inter-process com (https://en.wikipedia.org/wiki/Inter-process_communication)

Run a console application and then close the console and run in background in C++

I want to make a console application in C++ and then when the information is displayed, close the console and run in background. Is this possible? Is another way to do that? Python maybe?
You will have to either close the console window while the process is still running, which is system dependent, or start another process, and even though the standard library offers the system function to do that, its argument is a system dependent command line.
So the upshot is: this is system dependent.
In Windows the full-version of Microsoft's Visual Studio IDE has always, as far back as I can remember, used a peculiar approach for this, with two executable files devenv.com and devenv.exe. The former is a console subsystem executable, which by default runs the latter, which is a GUI subsystem executable:
[C:\]
> where devenv
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.com
C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\devenv.exe
[C:\]
> _
The basic idea here is that for historical reasons the command interpreter's search for an executable finds the .com file first, so the command devenv just works, either for starting the IDE or just getting the help text via the /? option.
Yes, this is possible with a small variant:
fork another process. But this is heavily system dependent:
posix/linux allow to simply clone the process;
windows requires new process to be created from an executable. You then have to communicate the state. Its less trivial as explained in this article, in the paragraph on porting fork())
then exit the program (it's the only way to give back control to the console).
On Windows use ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false) to hide the console window. It will still be running in the background and is not visible on the taskbar.
However you will have to run a task manager like Taskmgr.exe to find it and shut it down.
#include <windows.h>
#include <iostream>
using namespace std;
int main () {
cout<<"Some information is displayed.. \n\n";
Sleep(5000);
cout<<"wait.. the console is going to hide and run in background.. \n";
Sleep(5000);
ShowWindow(FindWindowA("ConsoleWindowClass", NULL), false);
while(true) {
// Do your hidden stuff in here
}
return 0;
}
The other answers given here overcomplicate things. The most easy way to close the console window in Windows is to simply detach from it. Once the last user of a console window datached, the console window gets closed.
If you start a program from a CLI (e.g. cmd.exe) then this CLI is also attaches to to the console and thus the console window will not close.
Anyway, detaching from a console is as simple as calling
FreeConsole();
… done!
Also you can attach to a newly created console at any time using AttachConsole, which takes a process ID. Now in a CLI situation the parent will usually be the CLI shell, so you may want to attach to the console of that.

Firebreath plugin on windows fails to load in chrome

I am busy converting by existing firebreath plugin here to use gpgme instead of making calls via the OS and the gpg binary.
I have managed to get the code to compile in windows using VS 2010 on a x32 system but after loading the plugin into chrome I can not access the npapi code at all. Even simple version calls fails.
When loading the plugin I get no visible errors but when using sawbuck log viewer for chrome I get the erorr messages below.
.\renderer\webplugin_delegate_proxy.cc 347 PluginMsg_Init returned false
..\plugins\npapi\webplugin_impl.cc 271 Couldn't initialize plug-in
I have tried to use my code with both firebreath 1.4 and 1.6 and neither versions work. After some simple debugging it seems that using any code provided by gpgme (whether its called or not) causes the plugin to break.
I came to this conclusion by doing the following.
Created a new project with firebreath (versions 1.4 and 1.6)
Add the gpgme.h headers to gmailGPGAPI.cpp and changed nothing else aside from adding the required reference paths to the project.
Build the project to create the dll (this generates the dll fine).
Replace the existing ddl in my project with the dll in step 2 and test it with the following piece of code
plugin = document.createElement('object'); plugin.id = 'plugin';
plugin.type = 'application/x-gmailtest';
document.body.appendChild(plugin);
console.log("my plugin returned: "+ plugin.valid);
console.log("my plugin returned: " + plugin.version);
This returns valid = true and the version returns what ever i set it to.
I then modified gmailGPGAPI.cpp to now return the gpg version by calling gpgme_check_version(NULL) in the version method. I used that method because its probably the simplest returning function that I could test with.
Build the plugin and copy dll to chrome extension as in step 3-4. The plugin builds fine again as expected.
Load the plugin and try to execute the code in step 4 at which point it now just returns undefined for any property or method i try to access on the plugin. No errors are printed to the console or anywhere else in chrome except for the error logged to sawbuck.
I have got no idea where to look or what to try since I cant seem to get an actionable error to work against. I have also reduced by test code to the point where its just a new project with a one line change to make it easier to find the problem.
I should note the code in the repo builds fine in linux/OSX and loads into chrome correctly so I know at some level my code does work.
Two possible paths:
You may have a DLL dependency that isn't available which keeps the plugin from loading; if you run regsvr32 on it in the state where it doesn't work on chrome, does it work?
Your plugin may be loading and then crashing. Start chrome with --plugin-startup-dialog and then when it pops up a dialog warning you that a plugin is about to be loaded attach to that process and see if the process crashes. At this point you can also set breakpoints to try to figure out how far it gets.
Double check your metadata in PluginConfig.cmake as well; sometimes unusual characters in some fields can cause issues like this.

DOS-reported error: Bad file number

I have a batch file that tries to compile a static library using Borland C++ Builder 6.0
It is called from Borland make (makefile created with bpr2mak) which is called from a .bat file (used to compile the whole project with Visual Studio and some Borland C++ Builder legacy projects), which is called from a bash shell script running inside Cygwin.
When I run the .bat file directly from a Cygwin shell, it runs OK, but when its being run from a Program calling cygwin with Boost::Process::launcher I'm getting this error:
C:\ARQUIV~1\Borland\CBUILD~1\Bin\..\BIN\TLib /u bclibs.lib #MAKE0000.###
DOS-reported error: Bad file number
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation
opening 'MAKE0000.###'
** error 1 ** deleting bclibs.lib
It's a complicated scenario, but this Program which calls cygwin is run whenever we need to build our software package which needs to be build for various Linux distos and Windows 32 and 64-bit.
Note: It's the only Borland Project failing, the other compile just fine (it's the only static library using borland also, so it can be some problem with the TLib tool.
The problem was that TLib does not like to have his output redirected (seen here) without having an input pipe as well. Solved by creating an input pipe to in the Boost::Process::launcher using set_stdin_behavior
I'm just guessing here, but this may have to do with long filenames and/or spaces in paths.
1) Modify your makefile so it would save current environment to a file, immediately before executing the failing command (set > d:\env.txt & echo CD=%CD% >> d:\env.txt). Then run it both ways (directly and via program) and compare the environments of good run and bad run.
2) Using filemon from Sysinternals, capture logs of disk access in both cases (these logs are going to be huge, though you can uncheck everything except Open in the filter to reduce the size). Again, compare and check for clues...
3) Try instaling everything involved to paths conforming to 8.3 scheme.
This error is not related to C++ itself. It happens when your build script opens too much files (more than defined in DOS command processor environment). To resolve this issue try to set value of files variable to 253. For Windows XP this variable defined in the file %WINDIR%\system32\config.nt.
files=253
Seems it is known bug in Borland C++ tools. Here is description and possible workaround for this issue:
Problem: Some static Lib projects will
not link correctly when compiled. You might see something
like this :
J:\Borland\CBUILD~1\bin\..\BIN\TLib /u debug\jpegD.lib #MAKE0000.###
DOS-reported error: Bad file number
TLIB 4.5 Copyright (c) 1987, 1999 Inprise Corporation
opening 'MAKE0000.###'
** error 1 ** deleting debug\jpegD.lib
MAKE failed, returned : 1
Workaround : In some cases (where the "Bad file number" error is seen) it may be possible to work around this by specifying -tDEFLIB.BMK in the BPR2MAKE Options field, and Turning off the "Capture Make Output" option.
I have not tested it, but I hope that helps.