Load an external .exe
by Katrina Rose · in Torque Game Engine · 08/09/2004 (6:50 am) · 16 replies
We need to open another program that we have previously developed using the Torque engine as the launch platform. I am currently using CreateProcess to do this but this method minimizes the game and then opens the other program.
Is there a way to bring up the external program on top of the Torque game engine without having it first disappear to the system tray?
Thanks
Steve Hurt
shurt@lsijax.com
Is there a way to bring up the external program on top of the Torque game engine without having it first disappear to the system tray?
Thanks
Steve Hurt
shurt@lsijax.com
About the author
#2
Thanks for the tip.
Running it in Windowed mode does fix the issues we were having.
Is there a way to create a window inside of Torque and run the other program inside this window? An example would be all of the dialog boxes that open inside Torque, as the ConsoleDlg.
Thanks again.
Steve Hurt
08/09/2004 (11:58 am)
I don't think there's a way to do this unless the torque engine is running windowed.Thanks for the tip.
Running it in Windowed mode does fix the issues we were having.
Is there a way to create a window inside of Torque and run the other program inside this window? An example would be all of the dialog boxes that open inside Torque, as the ConsoleDlg.
Thanks again.
Steve Hurt
#3
If it's a win32 console application, yes. You would need to create a pipe (details and examples are in the Win32 SDK Docs) to read the application's output from and write any input to. You'd also have to make a GUI to display/input the program. It's not that hard, really.
T.
08/09/2004 (12:55 pm)
If it's a GUI application, no ...If it's a win32 console application, yes. You would need to create a pipe (details and examples are in the Win32 SDK Docs) to read the application's output from and write any input to. You'd also have to make a GUI to display/input the program. It's not that hard, really.
T.
#4
I would really appreciate a little more direction here, as I am new to Torque and GarageGames.com.
Are you referring to docs on the GG site, or somewhere else?
Steve Hurt
08/10/2004 (5:15 am)
details and examples are in the Win32 SDK DocsI would really appreciate a little more direction here, as I am new to Torque and GarageGames.com.
Are you referring to docs on the GG site, or somewhere else?
Steve Hurt
#5
08/10/2004 (5:19 am)
I think he means the Microsoft Win32 SDK docs. You sohld be able to get them from the Microsoft website.
#6
08/11/2004 (7:54 pm)
Bear in mind that all of TGE's GUI rendering is done with OpenGL. Getting it to co-operate nicely with Win32 GDI rendering may be complicated.
#7
Yes, I did mean the Microsoft SDK docs. They're on msdn.microsoft.com/ somewhere, look for the Platform SDK. You can also read them online.
Ben, i was thinking just use a pipe to get the output (and perhaps provide input if neccessary) and render it using TGE's normal rendering stuff. GDI shouldnt really come into it.
T.
08/12/2004 (2:58 pm)
Sorry, I couldnt find this thread again when I realised I'd forgotten about it ...Yes, I did mean the Microsoft SDK docs. They're on msdn.microsoft.com/ somewhere, look for the Platform SDK. You can also read them online.
Ben, i was thinking just use a pipe to get the output (and perhaps provide input if neccessary) and render it using TGE's normal rendering stuff. GDI shouldnt really come into it.
T.
#8
08/12/2004 (10:32 pm)
Ah, you mean you want to wrap a console app? That's much simpler!
#9
-s
08/14/2004 (12:49 pm)
Let me know if you want to see an example app that uses pipes and redirects stdinput and output; just had to do one for school (pipes and filters pattern).-s
#10
Here is the code:
In Platform.h I added static bool openFile( const char* filename); to the public: variables.
In winWindow.cc I created a new method
bool Platform::openFile( const char* filename )
{
//Load the External program
SHELLEXECUTEINFO si = {0};
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.fMask = SEE_MASK_NOCLOSEPROCESS;
si.hwnd = NULL;
si.lpVerb = NULL;
si.lpFile = filename;
si.lpParameters = "";
si.lpDirectory = "";
si.nShow = SW_SHOW;
si.hInstApp = NULL;
ShellExecuteEx(&si);
//While the program runs, pause the game
WaitForSingleObject(si.hProcess, INFINITE);
return(true);
To use the new method, we assigned the key (-) to run the program.
When the user selects the - key we use a multiple step process:
1. To pause the game, we created a new...
new GuiControl(NewConsoleDlg)
{
profile = "GuiWindowProfile";
new GuiWindowCtrl()
{
profile = "GuiWindowProfile";
position = "0 0";
extent = "0 0";
text = "";
};
};]
then...
Canvas.PushDialog[NewConsoleDlg, 99];
2. To run the external program, openFile("External Program Name.exe");
3. To return control of the game back to the user after the external program closes, Canvas.popDialog[NewConsoleDlg];
That's all there is to it!
08/16/2004 (5:04 am)
I found another code snipett using ShellExecuteEx which works just the way I wanted. Using CreateProcess in FullScreen caused some undesireable effects, but using ShellExecuteEx we are able to use any screen resolution and the program loads as we were expecting.Here is the code:
In Platform.h I added static bool openFile( const char* filename); to the public: variables.
In winWindow.cc I created a new method
bool Platform::openFile( const char* filename )
{
//Load the External program
SHELLEXECUTEINFO si = {0};
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.fMask = SEE_MASK_NOCLOSEPROCESS;
si.hwnd = NULL;
si.lpVerb = NULL;
si.lpFile = filename;
si.lpParameters = "";
si.lpDirectory = "";
si.nShow = SW_SHOW;
si.hInstApp = NULL;
ShellExecuteEx(&si);
//While the program runs, pause the game
WaitForSingleObject(si.hProcess, INFINITE);
return(true);
To use the new method, we assigned the key (-) to run the program.
When the user selects the - key we use a multiple step process:
1. To pause the game, we created a new...
new GuiControl(NewConsoleDlg)
{
profile = "GuiWindowProfile";
new GuiWindowCtrl()
{
profile = "GuiWindowProfile";
position = "0 0";
extent = "0 0";
text = "";
};
};]
then...
Canvas.PushDialog[NewConsoleDlg, 99];
2. To run the external program, openFile("External Program Name.exe");
3. To return control of the game back to the user after the external program closes, Canvas.popDialog[NewConsoleDlg];
That's all there is to it!
#11
ConsoleFunction( openFile, bool, 2, 2, "openFile( filename )" )
{
//Load the External program
argc;
SHELLEXECUTEINFO si = {0};
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.fMask = SEE_MASK_NOCLOSEPROCESS;
si.hwnd = NULL;
si.lpVerb = NULL;
si.lpFile = argv[1]; //filename;
si.lpParameters = "";
si.lpDirectory = "";
si.nShow = SW_SHOW;
si.hInstApp = NULL;
ShellExecuteEx(&si);
//While the program runs, pause the game
WaitForSingleObject(si.hProcess, INFINITE);
return(true);
}
You can add this console function to winWindow.cc at the bottom of the code. This will prevent you from having to modify platform.h and avoid a lo-o-o-ong recompile.
You'd then call the openFile function as you would call something from the Start>Run prompt. For example:
openFile("notepad");
-Robert
01/08/2006 (4:06 pm)
I have dabbled with this and in Torque 1.3, you need to create a Console Function:ConsoleFunction( openFile, bool, 2, 2, "openFile( filename )" )
{
//Load the External program
argc;
SHELLEXECUTEINFO si = {0};
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.fMask = SEE_MASK_NOCLOSEPROCESS;
si.hwnd = NULL;
si.lpVerb = NULL;
si.lpFile = argv[1]; //filename;
si.lpParameters = "";
si.lpDirectory = "";
si.nShow = SW_SHOW;
si.hInstApp = NULL;
ShellExecuteEx(&si);
//While the program runs, pause the game
WaitForSingleObject(si.hProcess, INFINITE);
return(true);
}
You can add this console function to winWindow.cc at the bottom of the code. This will prevent you from having to modify platform.h and avoid a lo-o-o-ong recompile.
You'd then call the openFile function as you would call something from the Start>Run prompt. For example:
openFile("notepad");
-Robert
#12
Add this to the bottom of your winWindow.cc file. Please note that I commented out the line to pause the game. I decided to implement this differently in my game. I set $TimeScale = 0 to pause the game and then set it to $TimeScale = 1 to resume. After pausing, I brought up a custom GUI. This would allow me to resume the game when I was finished with the external EXE.
02/02/2006 (12:39 pm)
To get this to work in 1.4 I used a modified version of Robert's function (see below).ConsoleFunction( openFile, bool, 2, 2, "openFile( filename )" )
{
//Load the External program
argc;
//convert filename from LPCSTR to LPCWSTR
LPCSTR mFilename = argv[1];
LPWSTR m_wszBufferFilename;
int nLen = strlen(mFilename) + 1;
m_wszBufferFilename = new WCHAR [nLen];
mbstowcs(m_wszBufferFilename, mFilename, nLen);
LPCWSTR mWideFilename = (LPCWSTR)m_wszBufferFilename;
//convert parameters to wide string
LPCSTR mParameters = "";
LPWSTR m_wszBufferParameters;
nLen = strlen(mFilename) + 1;
m_wszBufferParameters = new WCHAR [nLen];
mbstowcs(m_wszBufferParameters, mFilename, nLen);
LPCWSTR mWideParameters = (LPCWSTR)m_wszBufferParameters;
//convert directory to wide string
LPCSTR mDirectory = "";
LPWSTR m_wszBufferDirectory;
nLen = strlen(mFilename) + 1;
m_wszBufferDirectory = new WCHAR [nLen];
mbstowcs(m_wszBufferDirectory, mFilename, nLen);
LPCWSTR mWideDirectory= (LPCWSTR)m_wszBufferDirectory;
//create a ShellExecuteInfo structure
SHELLEXECUTEINFO si = {0};
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.fMask = SEE_MASK_NOCLOSEPROCESS;
si.hwnd = NULL;
si.lpVerb = NULL;
si.lpFile = mWideFilename;
si.lpParameters = mWideParameters;
si.lpDirectory = mWideDirectory;
si.nShow = SW_SHOW;
si.hInstApp = NULL;
//Execute the file using the new structure
ShellExecuteEx(&si);
//Clear Buffers
delete [] mWideFilename;
delete [] mWideParameters;
delete [] m_wszBufferDirectory;
//While the program runs, pause the game
//WaitForSingleObject(si.hProcess, INFINITE);
return(true);
}Add this to the bottom of your winWindow.cc file. Please note that I commented out the line to pause the game. I decided to implement this differently in my game. I set $TimeScale = 0 to pause the game and then set it to $TimeScale = 1 to resume. After pausing, I brought up a custom GUI. This would allow me to resume the game when I was finished with the external EXE.
#13
I'm very new to c++ programming, when i compile your code it said that there are 2 error, this is the error log :
--------------------Configuration: Torque Demo - Win32 Debug--------------------
Compiling...
winWindow.cc
C:\Torque\SDK\engine\platformWin32\winWindow.cc(1585) : error C2664: 'delete[]' : cannot convert parameter 1 from 'const unsigned short *' to 'void *'
Conversion loses qualifiers
C:\Torque\SDK\engine\platformWin32\winWindow.cc(1586) : error C2664: 'delete[]' : cannot convert parameter 1 from 'const unsigned short *' to 'void *'
Conversion loses qualifiers
Error executing cl.exe.
winWindow.obj - 2 error(s), 0 warning(s)
Can you help me with this one ? thank you in advance.
09/12/2006 (8:20 pm)
Thanks James for the code for 1.4, I'm very new to c++ programming, when i compile your code it said that there are 2 error, this is the error log :
--------------------Configuration: Torque Demo - Win32 Debug--------------------
Compiling...
winWindow.cc
C:\Torque\SDK\engine\platformWin32\winWindow.cc(1585) : error C2664: 'delete[]' : cannot convert parameter 1 from 'const unsigned short *' to 'void *'
Conversion loses qualifiers
C:\Torque\SDK\engine\platformWin32\winWindow.cc(1586) : error C2664: 'delete[]' : cannot convert parameter 1 from 'const unsigned short *' to 'void *'
Conversion loses qualifiers
Error executing cl.exe.
winWindow.obj - 2 error(s), 0 warning(s)
Can you help me with this one ? thank you in advance.
#14
01/03/2008 (5:31 pm)
How do you attach argument to the exe?
#15
@gamer
modify ConsoleFunction( openFile, bool, 2, 2, "openFile( filename )" )
to ConsoleFunction( openFile, bool, 3, 3, "openFile( filename, arg )" )
modify
//convert parameters to wide string
LPCSTR mParameters = "";
LPWSTR m_wszBufferParameters;
nLen = strlen(mFilename) + 1;
m_wszBufferParameters = new WCHAR [nLen];
mbstowcs(m_wszBufferParameters, mFilename, nLen);
LPCWSTR mWideParameters = (LPCWSTR)m_wszBufferParameters;
to
//convert parameters to wide string
LPCSTR mParameters;
if(argc > 2)
mParameters = argv[2];
else
mParameters = "";
LPWSTR m_wszBufferParameters;
nLen = strlen( mParameters ) + 1;
m_wszBufferParameters = new WCHAR [nLen];
mbstowcs(m_wszBufferParameters, mParameters , nLen);
LPCWSTR mWideParameters = (LPCWSTR)m_wszBufferParameters;
thats all, build and on the console game type openFile("notepad","c:/mytext.txt")
:)
01/25/2008 (12:01 am)
Ok, problem solved.@gamer
modify ConsoleFunction( openFile, bool, 2, 2, "openFile( filename )" )
to ConsoleFunction( openFile, bool, 3, 3, "openFile( filename, arg )" )
modify
//convert parameters to wide string
LPCSTR mParameters = "";
LPWSTR m_wszBufferParameters;
nLen = strlen(mFilename) + 1;
m_wszBufferParameters = new WCHAR [nLen];
mbstowcs(m_wszBufferParameters, mFilename, nLen);
LPCWSTR mWideParameters = (LPCWSTR)m_wszBufferParameters;
to
//convert parameters to wide string
LPCSTR mParameters;
if(argc > 2)
mParameters = argv[2];
else
mParameters = "";
LPWSTR m_wszBufferParameters;
nLen = strlen( mParameters ) + 1;
m_wszBufferParameters = new WCHAR [nLen];
mbstowcs(m_wszBufferParameters, mParameters , nLen);
LPCWSTR mWideParameters = (LPCWSTR)m_wszBufferParameters;
thats all, build and on the console game type openFile("notepad","c:/mytext.txt")
:)
#16
The console function now accept 1 OR 2 parameters (and not 2 only).
Be carful if you use "\" in your path to double it : "\\".
Nicolas Buquet
www.buquet-net.com/cv/
02/15/2008 (9:16 am)
One more verson that is slightly corrected : ConsoleFunction( openFile, bool, [b]2, 3[/b], "openFile( filename, arg )" )
{
//convert filename from LPCSTR to LPCWSTR
LPCSTR mFilename = argv[1];
LPWSTR m_wszBufferFilename;
int nLen = strlen(mFilename) + 1;
m_wszBufferFilename = new WCHAR [nLen];
mbstowcs(m_wszBufferFilename, mFilename, nLen);
LPCWSTR mWideFilename = (LPCWSTR)m_wszBufferFilename;
//convert parameters to wide string
LPCSTR mParameters = "";
if( argc > 2) mParameters = argv[2];
LPWSTR m_wszBufferParameters;
nLen = strlen(mParameters) + 1;
m_wszBufferParameters = new WCHAR [nLen];
mbstowcs(m_wszBufferParameters, mParameters, nLen);
LPCWSTR mWideParameters = (LPCWSTR)m_wszBufferParameters;
//convert directory to wide string
LPCSTR mDirectory = "";
LPWSTR m_wszBufferDirectory;
nLen = strlen([b]mDirectory[/b]) + 1;
m_wszBufferDirectory = new WCHAR [nLen];
mbstowcs(m_wszBufferDirectory, [b]mDirectory[/b], nLen);
LPCWSTR mWideDirectory= (LPCWSTR)m_wszBufferDirectory;
//create a ShellExecuteInfo structure
SHELLEXECUTEINFO si = {0};
si.cbSize = sizeof(SHELLEXECUTEINFO);
si.fMask = SEE_MASK_NOCLOSEPROCESS;
si.hwnd = NULL;
si.lpVerb = NULL;
si.lpFile = mWideFilename;
si.lpParameters = mWideParameters;
si.lpDirectory = mWideDirectory;
si.nShow = SW_SHOW;
si.hInstApp = NULL;
//Execute the file using the new structure
ShellExecuteEx(&si);
//Clear Buffers
delete [] mWideFilename;
delete [] mWideParameters;
delete [] m_wszBufferDirectory;
//While the program runs, pause the game
WaitForSingleObject(si.hProcess, INFINITE);
return(true);
}The console function now accept 1 OR 2 parameters (and not 2 only).
Be carful if you use "\" in your path to double it : "\\".
Nicolas Buquet
www.buquet-net.com/cv/
Torque Owner Drew Hitchcock
Try running torque in a window. The only other option I can think of, depending on the type of program you're trying to run, is you could possibly write a frontend for it with torque's GUI system. That might be far-fetched, I don't know.