I am using FMX. Does anyone know how I can run an .exe
file in a button click? There is not enough resources on this issue.
I am trying
extern DELPHI_PACKAGE NativeUInt __fastcall FileOpen('Console\app.exe');
But honestly, I wasn't able to see a working example.
UPDATE: The full code is this:
#include <fmx.h>
#pragma hdrstop
#include <shellapi.h>
#include "MainStartWindow.h"
#include "LandingWindow.h"
#include "Login.h"
#include "Register.h"
#include "TempDashboard.h"
#pragma package(smart_init)
#pragma resource "*.fmx"
TLandingWin *LandingWin;
__fastcall TLandingWin::TLandingWin(TComponent* Owner)
: TForm(Owner)
{
}
void __fastcall TLandingWin::FormClose(TObject *Sender, TCloseAction &Action)
{
// if LandingWin gets closed by X, startWin gets closed as well
startWin->Close();
}
void __fastcall TLandingWin::landingLoginButtonClick(TObject *Sender)
{
LoginWin->Show();
RegisterWin->Close();
//LandingWin->Hide();
}
void __fastcall TLandingWin::landingRegisterButtonClick(TObject *Sender)
{
RegisterWin->Show();
LoginWin->Close();
}
void __fastcall TLandingWin::guestLoginButton2Click(TObject *Sender)
{
HINSTANCE result = ShellExecuteW(Handle, NULL, L"\\Console\\app.exe", NULL, NULL, SW_SHOW);
if (int(result) > 32)
{
// success...
}
else
{
// error...
}
LandingWin->Hide();
}
Any idea why I get this error?
shellapi.h(88): candidate function not viable: no known conversion from 'Fmx::Types::TWindowHandle *' to 'HWND' (aka 'HWND__ *') for 1st argument
CodePudding user response:
In C , 'Console\app.exe'
is a multi-byte character literal, not a string literal. Unlike in Delphi, which uses '...'
for both character literals and string literals, in C you need '...'
for character literals and "..."
for string literals. And, in both cases, you need to escape the \
character used in literals in C (you don't need to in Delphi), eg: "Console\\app.exe"
.
Now, that said, you stated that you want to "run" another program. FileOpen()
is not the way to accomplish that. It just opens the file so you can access its raw data.
On Windows, use the Win32 CreateProcess()
function instead, eg:
#ifdef _Windows
#include <windows.h>
#else
// include other platform headers as needed...
#endif
void __fastcall TForm1::Button1Click(TObject *Sender)
{
#ifdef _Windows
STARTUPINFOW si = {};
si.cb = sizeof(si);
// populate other fields as needed...
PROCESS_INFORMATION pi = {};
WCHAR szCmdLine[] = L"Console\\app.exe";
if (CreateProcessW(NULL, szCmdLine, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
// success...
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
else
{
// error...
}
#else
// handle other platforms as needed...
#endif
}
Or, you can use the ShellExecute()
/ShellExecuteEx()
function instead, eg:
#ifdef _Windows
#include <windows.h>
#include <shellapi.h>
#include <FMX.Platform.Win.hpp>
#else
// include other platform headers as needed...
#endif
void __fastcall TForm1::Button1Click(TObject *Sender)
{
#ifdef _Windows
HINSTANCE result = ShellExecuteW(
Fmx::Platform::Win::FormToHWND(this),
NULL, L"Console\\app.exe", NULL, NULL, SW_SHOW);
if (reinterpret_cast<INT_PTR>(result) > 32)
{
// success...
}
else
{
// error...
}
#else
// handle other platforms as needed...
#endif
}
#ifdef _Windows
#include <windows.h>
#include <shellapi.h>
#include <FMX.Platform.Win.hpp>
#else
// include other platform headers as needed...
#endif
void __fastcall TForm1::Button1Click(TObject *Sender)
{
#ifdef _Windows
SHELLEXECUTEINFOW sei = {};
sei.cbSize = sizeof(sei);
sei.hwnd = Fmx::Platform::Win::FormToHWND(this);
sei.lpFile = L"Console\\app.exe";
sei.nShow = SW_SHOW;
// populate other fields as needed...
if (ShellExecuteExW(&sei))
{
// success ...
}
else
{
// error...
}
#else
// handle other platforms as needed...
#endif
}
CodePudding user response:
ShellExecute API (assuming you actually want to execute the file).
#include <shellapi.h>
ShellExecute(0,L"open",L"app.exe",0,0,SW_SHOWNORMAL);