Alaska Software Inc. - Run an App Asynch
Username: Password:
AuthorTopic: Run an App Asynch
Carlos a Beling Run an App Asynch
on Tue, 14 Nov 2017 09:47:54 -0200
Good morning.
I am trying to run a program in asynch mode without the ugly black 
screen of RunShell().
For to do this I am using ShellExecuteA() but it runs only synch.
Does anyone know how to this and post here an example?
TIA

Fraternally
Beling
Pascal BoivinRe: Run an App Asynch
on Tue, 14 Nov 2017 16:51:44 +0100
Hi

I would use CreateProcess

https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396

Never tried from xbase, but i beleive you can pass 3 strings and let
the other parameters to zero.

ProcessID := CreateProcess(AppName, CmdLine, 0, 0, 0, 0, 0, StartDir,
0, 0)

Another way would be to call ShellExecute from another thread so you
still have a way to know when it is done, but don't need to wait.
Carlos a Beling Re: Run an App Asynch
on Tue, 14 Nov 2017 17:06:47 -0200
Hello Pascal.
Good afternoon.
Many thanks.
Unforunatelly it seems only to run synch.

Fraternally
Beling


Em 14/11/2017 13:51, Pascal Boivin escreveu:
> Hi
>
> I would use CreateProcess
>
> https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
>
> Never tried from xbase, but i beleive you can pass 3 strings and let
> the other parameters to zero.
>
> ProcessID := CreateProcess(AppName, CmdLine, 0, 0, 0, 0, 0, StartDir,
> 0, 0)
>
> Another way would be to call ShellExecute from another thread so you
> still have a way to know when it is done, but don't need to wait.
>
Jim LeeRe: Run an App Asynch
on Wed, 15 Nov 2017 00:21:25 +0100
> Unforunatelly it seems only to run synch.
how do you use it ?
have a look for Pablos "TRunProcess"

p.s. what do you try to do ?





TRunProcess.zip
Carlos a Beling Re: Run an App Asynch
on Wed, 15 Nov 2017 11:38:53 -0200
Hi Jim:
good morning.
I only want that the application executes a program and waits until it 
finishes before running again.

I will give a try in the example that you posted here.

Fraternally
Beling

Em 14/11/2017 21:21, Jim Lee escreveu:
>> Unforunatelly it seems only to run synch.
> how do you use it ?
> have a look for Pablos "TRunProcess"
>
> p.s. what do you try to do ?
>
>
>
Carlos a Beling Re: Run an App Asynch
on Wed, 15 Nov 2017 12:53:46 -0200
Good afternoon.
I am trying to use CreateProcess() according Jim's advice and I wrote a 
test program (attached) but it crashes any way I try.
Can someone point to me what is wrong?
TIA

Fraternally
Beling


Em 14/11/2017 21:21, Jim Lee escreveu:
>> Unforunatelly it seems only to run synch.
> how do you use it ?
> have a look for Pablos "TRunProcess"
>
> p.s. what do you try to do ?
>
>
>


Test.zip
Jim LeeRe: Run an App Asynch
on Wed, 15 Nov 2017 19:37:15 +0100
hi,

> Can someone point to me what is wrong?

you are not using "TRunProcess" which NEED STRUCTURE  _TRunProcess_base
Carlos a Beling Re: Run an App Asynch
on Thu, 16 Nov 2017 10:04:19 -0200
Hello Jim:
good morning.
Again many thanks.
I need studying "TRunProcess" before to use it because I have not OT4Xb 
installed (there many things that I need to know in advance before to 
use it), what will waste a time taht I have not right now .
Because of this I searched for "CreateProcess" pointed by mr Pascal 
Boivin in this thread in 14.11.2017 that shows to me to be easier to 
make it working; but unfortunately it is crashing.
I posted a testing program that is not working and, if someone could to 
correct it I will to attend my current need, and I can leave to study 
OT4Xb later because it is very powerful and has many utilities that we 
can need day by day.

Fraternally
Beling

Em 15/11/2017 16:37, Jim Lee escreveu:
> hi,
>
>> Can someone point to me what is wrong?
>
> you are not using "TRunProcess" which NEED STRUCTURE  _TRunProcess_base
>
>
>
>
Jim LeeRe: Run an App Asynch
on Thu, 16 Nov 2017 17:57:43 +0100
> Because of this I searched for "CreateProcess" pointed by mr Pascal Boivin
> in this thread in 14.11.2017 that shows to me to be easier to

the link from Pascal show Parameter of "CreateProcess" but as i say it use
Structure !

lpStartupInfo [in]
A pointer to a STARTUPINFO or STARTUPINFOEX structure.

lpProcessInformation [out]
A pointer to a PROCESS_INFORMATION structure that receives identification
information about the new process.

have a look at older Msg von Pascal "Re: Waiting for DLLCall?" (14. Mrz
2005, archived.generic)
Carlos a Beling Re: Run an App Asynch
on Thu, 16 Nov 2017 15:56:19 -0200
Hello Jim.
Good afternoon.
Again many thanks.
The error seems to be in the parameter lpStartupInfo.
The problem is that I do not know how to create it because of its 
parameters.
I attached again the testing program indicating an empty reference to 
lpStartupInfo and I include a test for execution error in the call of 
CreateProcess().
Executing the function it does not crash and does not return error.
Unfortunately I have not the NG archived messages and they do not appear 
in the subscriptions news groups.

Fraternally
Beling

Em 16/11/2017 14:57, Jim Lee escreveu:
>> Because of this I searched for "CreateProcess" pointed by mr Pascal Boivin
>> in this thread in 14.11.2017 that shows to me to be easier to
>
> the link from Pascal show Parameter of "CreateProcess" but as i say it use
> Structure !
>
> lpStartupInfo [in]
> A pointer to a STARTUPINFO or STARTUPINFOEX structure.
>
> lpProcessInformation [out]
> A pointer to a PROCESS_INFORMATION structure that receives identification
> information about the new process.
>
> have a look at older Msg von Pascal "Re: Waiting for DLLCall?" (14. März
> 2005, archived.generic)
>
>
>
Pascal BoivinRe: Run an App Asynch
on Thu, 16 Nov 2017 20:30:01 +0100
Carlos a Beling wrote:

> Hello Jim.
> Good afternoon.
> Again many thanks.
> The error seems to be in the parameter lpStartupInfo.
> The problem is that I do not know how to create it because of its
> parameters.  I attached again the testing program indicating an empty
> reference to lpStartupInfo and I include a test for execution error
> in the call of CreateProcess().  Executing the function it does not
> crash and does not return error.  Unfortunately I have not the NG
> archived messages and they do not appear in the subscriptions news
> groups.
> 
> Fraternally
> Beling
> 
> Em 16/11/2017 14:57, Jim Lee escreveu:
> > > Because of this I searched for "CreateProcess" pointed by mr
> > > Pascal Boivin in this thread in 14.11.2017 that shows to me to be
> > > easier to
> > 
> > the link from Pascal show Parameter of "CreateProcess" but as i say
> > it use Structure !
> > 
> > lpStartupInfo [in]
> > A pointer to a STARTUPINFO or STARTUPINFOEX structure.
> > 
> > lpProcessInformation [out]
> > A pointer to a PROCESS_INFORMATION structure that receives
> > identification information about the new process.
> > 
> > have a look at older Msg von Pascal "Re: Waiting for DLLCall?" (14.
> > März 2005, archived.generic)
> > 
> > 
> > 

12 years ago I said it will not be easy to call CreateProcess from
xbase! I give a C sample. The newsgroup still there. use the thread
trick I gave you in the other reply, it is easier to use.

---
Call the API CreateProcess, it is not easy from XBase.  Here's a C
sample
void RunAndWait(char *cProgname, char *cParameter)
{
   STARTUPINFO si;
   PROCESS_INFORMATION pi;
   char CmdLine[1024];

   memset(CmdLine, 0, 1024);
   memset(&si, 0, sizeof(si));
   memset(&pi, 0, sizeof(pi));
   si.cb = sizeof(si);
   sprintf(CmdLine, "\"%s\" \"%s\"", cProgname, cParameter);
   if( !CreateProcess( NULL, CmdLine, NULL, NULL, FALSE,
       0, NULL, NULL, &si, &pi ) )
   {
       //Error!
       MessageBox(NULL, CmdLine, "Error!", MB_OK);
   }
   else
   {
        Wait until child process exits.
       WaitForSingleObject( pi.hProcess, INFINITE );

        Close process and thread handles.
       CloseHandle( pi.hProcess );
       CloseHandle( pi.hThread );
   }
}
Carlos a Beling Re: Run an App Asynch
on Fri, 17 Nov 2017 15:49:51 -0200
Hello Pascal.
Good afternoon.
Many thanks to you and all the people that helped me in this task.
I think that I solved the problem and may be that it can interest to 
someone.
Please see tne attached Test.zip where I made the changes.
Many thanks to all those that helped me.

Fraternally
Beling


Em 16/11/2017 17:30, Pascal Boivin escreveu:
> Carlos a Beling wrote:
>
>> Hello Jim.
>> Good afternoon.
>> Again many thanks.
>> The error seems to be in the parameter lpStartupInfo.
>> The problem is that I do not know how to create it because of its
>> parameters.  I attached again the testing program indicating an empty
>> reference to lpStartupInfo and I include a test for execution error
>> in the call of CreateProcess().  Executing the function it does not
>> crash and does not return error.  Unfortunately I have not the NG
>> archived messages and they do not appear in the subscriptions news
>> groups.
>>
>> Fraternally
>> Beling
>>
>> Em 16/11/2017 14:57, Jim Lee escreveu:
>>>> Because of this I searched for "CreateProcess" pointed by mr
>>>> Pascal Boivin in this thread in 14.11.2017 that shows to me to be
>>>> easier to
>>>
>>> the link from Pascal show Parameter of "CreateProcess" but as i say
>>> it use Structure !
>>>
>>> lpStartupInfo [in]
>>> A pointer to a STARTUPINFO or STARTUPINFOEX structure.
>>>
>>> lpProcessInformation [out]
>>> A pointer to a PROCESS_INFORMATION structure that receives
>>> identification information about the new process.
>>>
>>> have a look at older Msg von Pascal "Re: Waiting for DLLCall?" (14.
>>> März 2005, archived.generic)
>>>
>>>
>>>
>
> 12 years ago I said it will not be easy to call CreateProcess from
> xbase! I give a C sample. The newsgroup still there. use the thread
> trick I gave you in the other reply, it is easier to use.
>
> ---
> Call the API CreateProcess, it is not easy from XBase.  Here's a C
> sample
> void RunAndWait(char *cProgname, char *cParameter)
> {
>     STARTUPINFO si;
>     PROCESS_INFORMATION pi;
>     char CmdLine[1024];
>
>     memset(CmdLine, 0, 1024);
>     memset(&si, 0, sizeof(si));
>     memset(&pi, 0, sizeof(pi));
>     si.cb = sizeof(si);
>     sprintf(CmdLine, "\"%s\" \"%s\"", cProgname, cParameter);
>     if( !CreateProcess( NULL, CmdLine, NULL, NULL, FALSE,
>         0, NULL, NULL, &si, &pi ) )
>     {
>         //Error!
>         MessageBox(NULL, CmdLine, "Error!", MB_OK);
>     }
>     else
>     {
>          Wait until child process exits.
>         WaitForSingleObject( pi.hProcess, INFINITE );
>
>          Close process and thread handles.
>         CloseHandle( pi.hProcess );
>         CloseHandle( pi.hThread );
>     }
> }
>


Test.zip
Carlos a Beling Re: Run an App Asynch - Sorry
on Sat, 18 Nov 2017 11:38:39 -0200
Good morning.
Sorry by my anxiety.
I was debuging the program and I did not see that 'WaitForSingleObject' 
called in line 155 in Test.prg is returning the error 0xffffffff what 
means that it failed.
Its syntax and handle seems to be correct.
GetLastError()  does not receive the possible error code.
Please does anyone know waht is happening?

Fraternally
Beling



Em 17/11/2017 15:49, Carlos a Beling escreveu:
> Hello Pascal.
> Good afternoon.
> Many thanks to you and all the people that helped me in this task.
> I think that I solved the problem and may be that it can interest to
> someone.
> Please see tne attached Test.zip where I made the changes.
> Many thanks to all those that helped me.
>
> Fraternally
> Beling
>
>
> Em 16/11/2017 17:30, Pascal Boivin escreveu:
>> Carlos a Beling wrote:
>>
>>> Hello Jim.
>>> Good afternoon.
>>> Again many thanks.
>>> The error seems to be in the parameter lpStartupInfo.
>>> The problem is that I do not know how to create it because of its
>>> parameters.  I attached again the testing program indicating an empty
>>> reference to lpStartupInfo and I include a test for execution error
>>> in the call of CreateProcess().  Executing the function it does not
>>> crash and does not return error.  Unfortunately I have not the NG
>>> archived messages and they do not appear in the subscriptions news
>>> groups.
>>>
>>> Fraternally
>>> Beling
>>>
>>> Em 16/11/2017 14:57, Jim Lee escreveu:
>>>>> Because of this I searched for "CreateProcess" pointed by mr
>>>>> Pascal Boivin in this thread in 14.11.2017 that shows to me to be
>>>>> easier to
>>>>
>>>> the link from Pascal show Parameter of "CreateProcess" but as i say
>>>> it use Structure !
>>>>
>>>> lpStartupInfo [in]
>>>> A pointer to a STARTUPINFO or STARTUPINFOEX structure.
>>>>
>>>> lpProcessInformation [out]
>>>> A pointer to a PROCESS_INFORMATION structure that receives
>>>> identification information about the new process.
>>>>
>>>> have a look at older Msg von Pascal "Re: Waiting for DLLCall?" (14.
>>>> März 2005, archived.generic)
>>>>
>>>>
>>>>
>>
>> 12 years ago I said it will not be easy to call CreateProcess from
>> xbase! I give a C sample. The newsgroup still there. use the thread
>> trick I gave you in the other reply, it is easier to use.
>>
>> ---
>> Call the API CreateProcess, it is not easy from XBase.  Here's a C
>> sample
>> void RunAndWait(char *cProgname, char *cParameter)
>> {
>>     STARTUPINFO si;
>>     PROCESS_INFORMATION pi;
>>     char CmdLine[1024];
>>
>>     memset(CmdLine, 0, 1024);
>>     memset(&si, 0, sizeof(si));
>>     memset(&pi, 0, sizeof(pi));
>>     si.cb = sizeof(si);
>>     sprintf(CmdLine, "\"%s\" \"%s\"", cProgname, cParameter);
>>     if( !CreateProcess( NULL, CmdLine, NULL, NULL, FALSE,
>>         0, NULL, NULL, &si, &pi ) )
>>     {
>>         //Error!
>>         MessageBox(NULL, CmdLine, "Error!", MB_OK);
>>     }
>>     else
>>     {
>>          Wait until child process exits.
>>         WaitForSingleObject( pi.hProcess, INFINITE );
>>
>>          Close process and thread handles.
>>         CloseHandle( pi.hProcess );
>>         CloseHandle( pi.hThread );
>>     }
>> }
>>


Test.zip
Jim LeeRe: Run an App Asynch
on Sun, 19 Nov 2017 01:27:54 +0100
hi,

> I think that I solved the problem and may be that it can interest to
> someone.
> Please see tne attached Test.zip where I made the changes.
> Many thanks to all those that helped me.

i think your "Structure" is still "to easy" ...
sStartupInfo := (L2Bin(18 * 4) + Replicate(Chr(0), (17 * 4)))

you are right that STARTUPINFOEX o:_SizeOf()_ is 72 but looking into Pablos 
Code

BEGIN STRUCTURE  _TRunProcess_base_
   GWSTSKIPBYTES( 4 )  DWORD   cb
   GWSTSKIPBYTES( 4 )  LPTSTR  lpReserved
   MEMBER LPSTR     lpDesktop DYNSZ cDesktop
   MEMBER LPSTR     lpTitle   DYNSZ cTitle
   MEMBER DWORD     dwX
   MEMBER DWORD     dwY
   MEMBER DWORD     dwXSize
   MEMBER DWORD     dwYSize
   MEMBER DWORD     dwXCountChars
   MEMBER DWORD     dwYCountChars
   MEMBER DWORD     dwFillAttribute
   MEMBER DWORD     dwFlags
   MEMBER WORD      wShowWindow
   GWSTSKIPBYTES( 2 )  WORD   cbReserved2
   GWSTSKIPBYTES( 4 )  LPBYTE lpReserved2
   MEMBER HANDLE    hStdInput
   MEMBER HANDLE    hStdOutput
   MEMBER HANDLE    hStdError
    ----------------
   MEMBER POINTER32 lpAttributeList   STARTUPINFOEX  Vista or higher

it seems me "more" ... not to forget all Property

    ----------------   constants for wShowWindow
   DYNAMIC PROPERTY swHide             IS CONSTANT 0
   DYNAMIC PROPERTY swShowNormal       IS CONSTANT 1
   DYNAMIC PROPERTY swNormal           IS CONSTANT 1
   DYNAMIC PROPERTY swShowMinimized    IS CONSTANT 2
   DYNAMIC PROPERTY swShowMaximized    IS CONSTANT 3
   DYNAMIC PROPERTY swMaximize         IS CONSTANT 3
   DYNAMIC PROPERTY swShowNoActivate   IS CONSTANT 4
   DYNAMIC PROPERTY swShow             IS CONSTANT 5
   DYNAMIC PROPERTY swMinimize         IS CONSTANT 6
   DYNAMIC PROPERTY swShowMinNoActive  IS CONSTANT 7
   DYNAMIC PROPERTY swShowNA           IS CONSTANT 8
   DYNAMIC PROPERTY swRestore          IS CONSTANT 9
   DYNAMIC PROPERTY swShowDefault      IS CONSTANT 10
   DYNAMIC PROPERTY swForceMinimize    IS CONSTANT 11
    ----------------   masks for dwFlags
   DYNAMIC PROPERTY lUseShowWindow    IS MASK 0x0001 OF dwFlags
   DYNAMIC PROPERTY lUseSize          IS MASK 0x0002 OF dwFlags
   DYNAMIC PROPERTY lUsePosition      IS MASK 0x0004 OF dwFlags
   DYNAMIC PROPERTY lUseCountChars    IS MASK 0x0008 OF dwFlags
   DYNAMIC PROPERTY lUseFillAttribute IS MASK 0x0010 OF dwFlags
   DYNAMIC PROPERTY lRunFullScreen    IS MASK 0x0020 OF dwFlags
   DYNAMIC PROPERTY lForceOnFeedback  IS MASK 0x0040 OF dwFlags
   DYNAMIC PROPERTY lForceOffFeedback IS MASK 0x0080 OF dwFlags
   DYNAMIC PROPERTY lUseStdHandles    IS MASK 0x0100 OF dwFlags
    ----------------

END STRUCTURE

so i recommend to use Pablos CLASS TRunProcess which have all you need.
Carlos a Beling Re: Run an App Asynch
on Sun, 19 Nov 2017 12:22:13 -0200
Hello Jim.
Good afternoon.
Unfortunately I do not understand anything that is written, but I will 
study for to accomplish it as soon as I have time.
Many, many thanks by your help.

Fraternally
Beling

Em 18/11/2017 22:27, Jim Lee escreveu:
> hi,
>
>> I think that I solved the problem and may be that it can interest to
>> someone.
>> Please see tne attached Test.zip where I made the changes.
>> Many thanks to all those that helped me.
>
> i think your "Structure" is still "to easy" ...
> sStartupInfo := (L2Bin(18 * 4) + Replicate(Chr(0), (17 * 4)))
>
> you are right that STARTUPINFOEX o:_SizeOf()_ is 72 but looking into Pablos
> Code
>
> BEGIN STRUCTURE  _TRunProcess_base_
>     GWSTSKIPBYTES( 4 )  DWORD   cb
>     GWSTSKIPBYTES( 4 )  LPTSTR  lpReserved
>     MEMBER LPSTR     lpDesktop DYNSZ cDesktop
>     MEMBER LPSTR     lpTitle   DYNSZ cTitle
>     MEMBER DWORD     dwX
>     MEMBER DWORD     dwY
>     MEMBER DWORD     dwXSize
>     MEMBER DWORD     dwYSize
>     MEMBER DWORD     dwXCountChars
>     MEMBER DWORD     dwYCountChars
>     MEMBER DWORD     dwFillAttribute
>     MEMBER DWORD     dwFlags
>     MEMBER WORD      wShowWindow
>     GWSTSKIPBYTES( 2 )  WORD   cbReserved2
>     GWSTSKIPBYTES( 4 )  LPBYTE lpReserved2
>     MEMBER HANDLE    hStdInput
>     MEMBER HANDLE    hStdOutput
>     MEMBER HANDLE    hStdError
>      ----------------
>     MEMBER POINTER32 lpAttributeList   STARTUPINFOEX  Vista or higher
>
> it seems me "more" ... not to forget all Property
>
>      ----------------   constants for wShowWindow
>     DYNAMIC PROPERTY swHide             IS CONSTANT 0
>     DYNAMIC PROPERTY swShowNormal       IS CONSTANT 1
>     DYNAMIC PROPERTY swNormal           IS CONSTANT 1
>     DYNAMIC PROPERTY swShowMinimized    IS CONSTANT 2
>     DYNAMIC PROPERTY swShowMaximized    IS CONSTANT 3
>     DYNAMIC PROPERTY swMaximize         IS CONSTANT 3
>     DYNAMIC PROPERTY swShowNoActivate   IS CONSTANT 4
>     DYNAMIC PROPERTY swShow             IS CONSTANT 5
>     DYNAMIC PROPERTY swMinimize         IS CONSTANT 6
>     DYNAMIC PROPERTY swShowMinNoActive  IS CONSTANT 7
>     DYNAMIC PROPERTY swShowNA           IS CONSTANT 8
>     DYNAMIC PROPERTY swRestore          IS CONSTANT 9
>     DYNAMIC PROPERTY swShowDefault      IS CONSTANT 10
>     DYNAMIC PROPERTY swForceMinimize    IS CONSTANT 11
>      ----------------   masks for dwFlags
>     DYNAMIC PROPERTY lUseShowWindow    IS MASK 0x0001 OF dwFlags
>     DYNAMIC PROPERTY lUseSize          IS MASK 0x0002 OF dwFlags
>     DYNAMIC PROPERTY lUsePosition      IS MASK 0x0004 OF dwFlags
>     DYNAMIC PROPERTY lUseCountChars    IS MASK 0x0008 OF dwFlags
>     DYNAMIC PROPERTY lUseFillAttribute IS MASK 0x0010 OF dwFlags
>     DYNAMIC PROPERTY lRunFullScreen    IS MASK 0x0020 OF dwFlags
>     DYNAMIC PROPERTY lForceOnFeedback  IS MASK 0x0040 OF dwFlags
>     DYNAMIC PROPERTY lForceOffFeedback IS MASK 0x0080 OF dwFlags
>     DYNAMIC PROPERTY lUseStdHandles    IS MASK 0x0100 OF dwFlags
>      ----------------
>
> END STRUCTURE
>
> so i recommend to use Pablos CLASS TRunProcess which have all you need.
>
>
Jorge L. BorlandoRe: Run an App Asynch
on Thu, 16 Nov 2017 23:27:42 -0300
Hello Carlos, let me suggest that you work on Jim's advice with the 
trunprocess() class, I highlight 2 possibilities (among others) tha maybe 
you are interested in, on the one hand you can direct the output of the 
application that you execute to a text file and also you can 
intercommunicate data between 2 executables (VM_COPY_DATA), if you need an 
example of what I mention, I can send them to you like,
ot4xb you can download it from xbwin.com
regards



"Carlos a Beling" <beling@bipbip.com.br> wrote in message 
news:231a6559$1c9ca14d$1030f@news.alaska-software.com...
> Hello Jim:
> good morning.
> Again many thanks.
> I need studying "TRunProcess" before to use it because I have not OT4Xb 
> installed (there many things that I need to know in advance before to use 
> it), what will waste a time taht I have not right now .
> Because of this I searched for "CreateProcess" pointed by mr Pascal Boivin 
> in this thread in 14.11.2017 that shows to me to be easier to make it 
> working; but unfortunately it is crashing.
> I posted a testing program that is not working and, if someone could to 
> correct it I will to attend my current need, and I can leave to study 
> OT4Xb later because it is very powerful and has many utilities that we can 
> need day by day.
>
> Fraternally
> Beling
>
> Em 15/11/2017 16:37, Jim Lee escreveu:
>> hi,
>>
>>> Can someone point to me what is wrong?
>>
>> you are not using "TRunProcess" which NEED STRUCTURE  _TRunProcess_base
>>
>>
>>
>>
Carlos a Beling Re: Run an App Asynch
on Fri, 17 Nov 2017 16:36:23 -0200
Hello Jorge.
Good afternoon.
Many thanks.
As soon as possible I am thinking in downloading ot4xb because it seems 
to be very good and must to be studied.

Fraternally
Beling

Em 17/11/2017 00:27, Jorge L. Borlando escreveu:
> Hello Carlos, let me suggest that you work on Jim's advice with the
> trunprocess() class, I highlight 2 possibilities (among others) tha
> maybe you are interested in, on the one hand you can direct the output
> of the application that you execute to a text file and also you can
> intercommunicate data between 2 executables (VM_COPY_DATA), if you need
> an example of what I mention, I can send them to you like,
> ot4xb you can download it from xbwin.com
> regards
>
>
>
> "Carlos a Beling" <beling@bipbip.com.br> wrote in message
> news:231a6559$1c9ca14d$1030f@news.alaska-software.com...
>> Hello Jim:
>> good morning.
>> Again many thanks.
>> I need studying "TRunProcess" before to use it because I have not
>> OT4Xb installed (there many things that I need to know in advance
>> before to use it), what will waste a time taht I have not right now .
>> Because of this I searched for "CreateProcess" pointed by mr Pascal
>> Boivin in this thread in 14.11.2017 that shows to me to be easier to
>> make it working; but unfortunately it is crashing.
>> I posted a testing program that is not working and, if someone could
>> to correct it I will to attend my current need, and I can leave to
>> study OT4Xb later because it is very powerful and has many utilities
>> that we can need day by day.
>>
>> Fraternally
>> Beling
>>
>> Em 15/11/2017 16:37, Jim Lee escreveu:
>>> hi,
>>>
>>>> Can someone point to me what is wrong?
>>>
>>> you are not using "TRunProcess" which NEED STRUCTURE  _TRunProcess_base
>>>
>>>
>>>
>>>
Pascal BoivinRe: Run an App Asynch
on Thu, 16 Nov 2017 19:47:39 +0100
I did a small test and was able to create a new process But I too get
an internal data structure upon function return.


PROCEDURE CreateProcess(AppName, CmdLine, StartDir)
LOCAL sProfessInfo, sStartupInfo
LOCAL hProcess, hThread

  sProcessInfo := Replicate(L2Bin(0), 4)
  sStartupInfo := L2Bin(68) + Replicate(L2Bin(0), 16)

  IF CreateProcessA(AppName, CmdLine, 0, 0, 0, 0, 0, StartDir,
@sStartupInfo, @sProcessInfo) <> 0
    hProcess := BIN2L(LEFT(sProcessInfo,4))
    hThread  := BIN2L(SUBSTR(sProcessInfo,5,4))
    CloseHandle(hThread)
    CloseHandle(hProcess)
  ENDIF

RETURN

/*
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
BOOL WINAPI CreateProcess(
  _In_opt_    LPCTSTR               lpApplicationName,
  _Inout_opt_ LPTSTR                lpCommandLine,
  _In_opt_    LPSECURITY_ATTRIBUTES lpProcessAttributes,
  _In_opt_    LPSECURITY_ATTRIBUTES lpThreadAttributes,
  In        BOOL                  bInheritHandles,
  In        DWORD                 dwCreationFlags,
  _In_opt_    LPVOID                lpEnvironment,
  _In_opt_    LPCTSTR               lpCurrentDirectory,
  In        LPSTARTUPINFO         lpStartupInfo,
  Out       LPPROCESS_INFORMATION lpProcessInformation
);
*/
DLLFUNCTION
CreateProcessA(lpApplicationName,lpCommandLine,lpProcessAttributes,lpThr
eadAttributes,bInheritHandles,dwCreationFlags,lpEnvironmentlpCurrentDire
ctory,lpStartupInfo,lpProcessInformation) USING STDCALL FROM
KERNEL32.DLL
DLLFUNCTION CloseHandle(Handle) USING STDCALL FROM KERNEL32.DLL


------

When I talk about using thread, I mean something like this:

#include "Dll.ch"
#define SW_HIDE             0x00
#define SW_NORMAL           0x01
#define SW_MAXIMIZE         0x03
#define SW_MINIMIZE         0x06


PROCEDURE MAIN
 ? "Calling ShellExecuteASync"

 ShellExecuteASync("C:\Windows\System32\NOTEPAD.EXE")

 ? "Done"
 WAIT
RETURN

PROCEDURE ShellExecuteASync(cFile, cParameter, cOperation, cDirectory,
nShowCmd)
LOCAL oThread
  oThread := Thread():New()
  oThread:Start("ShellExecute", cFile, cParameter, cOperation,
cDirectory, nShowCmd)
RETURN

FUNCTION ShellExecute(cFile, cParameter, cOperation, cDirectory,
nShowCmd)
LOCAL nRet, lOK := .F.

  IF Valtype(cParameter) <> "C"
    cParameter := 0
  ENDIF

  IF Valtype(cDirectory) <> "C"
    cDirectory := "C:\"  //CurDrive() + ":\" + CurDir()
  ENDIF

  IF Valtype(cOperation) <> "C"
    cOperation := "Open"
  ENDIF

  IF Valtype(nShowCmd) <> "N"
    nShowCmd := SW_NORMAL
  ENDIF

  //nRet := DllCall("SHELL32.DLL", DLL_STDCALL, "ShellExecuteA",
AppDesktop():getHWND(),cOperation, cFile, cParameter, cDirectory,
nShowCmd)
  nRet := DllCall("SHELL32.DLL", DLL_STDCALL, "ShellExecuteA",
0,cOperation, cFile, cParameter, cDirectory, nShowCmd)

  Do Case
    Case nRet > 32
      lOK := .T.
    Case nRet == 31
      ? "Windows don't know how to open that file"
    Otherwise
      ? "Windows error " + Alltrim(Str(nRet))
  EndCase

RETURN lOK