3

How i can run a 3rd party executable as child process in my PowerBuilder app?

The only objective i want to achieve is that the 3rd party exe file open and close just like we open and close a Sheet in PowerBuilder.

I dont want to give any other option to users of my app to close the 3rd party exe without closing my main PowerBuilder app. same way user is not allowed to run the 3rd party exe without running PowerBuilder app.

All that sound like some ActiveX behavior. So i can say if the 3rd party exe becomes an ActiveX then my objective is achieved. It is just my guess. really i can go for any other options that meets requirements.

2 Answers2

2

If you have the window handle for the other app, you might be able to use the SetParent API function to attach it to a blank sheet window in the PowerBuilder app. The resize event of the sheet window would have to use the PB function Send to forward a resize event. The close event of the sheet window would then send the WM_CLOSE event.

Roland Smith
  • 957
  • 4
  • 7
  • After SetParent somehow the 3rd party exe cannot be closed but it is not always true. The title bar of the child app (3rd paty app) is enabled sometimes on what event i have no idea. Also child app need no termination event sent to child when parent is closed. It is done automatically. Also the move for parent also moves child without need of a code for move. The child app will always be opened in maximized state so resizing is not needed after window is opened and SetParent is called. That is pretty much everything i needed in initial stages of my work. Thanks a lot. –  Apr 04 '18 at 15:29
  • Please let me know if some wrapper dll for win32 API calls is available for PowerBuilder, just to make functions calls simpler. I did try to find but could not find it. –  Apr 04 '18 at 15:33
  • I have a large number of examples on my website that use various Windows API functions. http://www.topwizprogramming.com/ – Roland Smith Apr 05 '18 at 16:32
  • I really wasn't 100% sure it would work, great news! How did you get the 3rd party exe window handle? Maybe I'll develop this idea as a new example for my website. – Roland Smith Apr 05 '18 at 16:44
  • I used the same FindWindowA function from sample code imankurpatel000 gave but it is pretty much awkward way to get the handle by tittle of the running process because for most windows applications title keep changing. for example a txt file opened in notepad will change its title too. In that case the FindWindowA will fail. luckily my 3rd party app has static title so it worked for me. Please see that code for syntax. Thanks a lot for the website link. –  Apr 05 '18 at 19:38
  • I am trying to embed a free business intelligence dashboard in my PowerBuilder app. That BI Dashboard when run from PowerBuilder it goes into Paused state. Reason could be that command line argument were not passed when Run function was used. Is there a way i can find out what arguments that 3rd party app need at start up? The shortcut created by app has no arguments specified. –  Apr 05 '18 at 20:02
  • I'm trying this myself where the PB window is a MDI sheet. The external app window isn't automatically sizing itself to the PB window. What did you do to achieve that? – Roland Smith Apr 05 '18 at 21:26
  • The documentation of the third party app should specify command line arguments. – Roland Smith Apr 05 '18 at 21:27
  • The External app was set to Maximized state which was not an issue for me. After SetParent i call this external function; Function long ShowWindow(long ChildHandel, Integer WhatState) LIBRARY "user32.dll" alias for "ShowWindow;Ansi" . See for more options https://msdn.microsoft.com/en-us/library/windows/desktop/ms633548(v=vs.85).aspx. I have not checked how resizing can be done. Run() function also accept 2nd parameter for window state but that did not work for me. This will maximize with external function call ShowWindow(TheChildHandel, 3). And call it after SetParent. –  Apr 06 '18 at 14:37
  • I haven't tried it yet but using the built in Send function from the resize event, you should be able to send the wm_size event: https://msdn.microsoft.com/en-us/library/windows/desktop/ms632646(v=vs.85).aspx – Roland Smith Apr 06 '18 at 18:08
  • I have it working. You can download it from here http://www.topwizprogramming.com/temp/parentwindow.zip – Roland Smith Apr 07 '18 at 02:24
  • I'm using CreateProcess to run the external app and WaitForInputIdle to wait for the app to completely open. The preferred method to get the window handle is EnumThreadWindows but unfortunately PowerBuilder doesn't support callbacks. – Roland Smith Apr 07 '18 at 02:29
  • I am using your target and i was able to complete some of my work with that. There are 15 processes that 3rd party app executes when it start. I have all the command line parameters for all the 15 processes. I am executing them with run() but one of them is Conhost.exe which returns error when executed. I checked the command C:\Windows\system32\conhost.exe "" in console and it works but Run() function failed with string parameter "C:\Windows\system32\conhost.exe ~"~" ". The conhost.exe need minimum one parameter even if that parameter is empty in double quotes and single quotes wont work –  Apr 08 '18 at 06:42
  • How conhost.exe can be run from PowerBuilder? i could not figure out the reason why it failed. It may be the rights issue. Please see if you can help me here because i am stuck at this point. –  Apr 08 '18 at 06:43
  • Actually, running this gn_app.of_Run("C:\Windows\system32\conhost.exe ~"~" ") returns FALSE. But C:\Windows\system32\conhost.exe "" executes in console successfully. I dont see any difference. –  Apr 08 '18 at 06:53
  • The return value from the built-in Run function has no meaning. The program conhost.exe is a system level program that hosts the command prompt window. You should not be running it directly. If you need to run a batch command prompt window use cmd.exe although to actually have it do something you should be running a .bat file. – Roland Smith Apr 09 '18 at 07:34
  • Luckily all processes ran successfully. The BI Dashboard is fully functional running as child process of PowerBuilder. All Conhost.exe processes also running but not under PowerBuilder and separately under csrss.exe. I reinstalled the 3rd party app on C:\ root instead of Programs Files and changed path everywhere when gave command line string to Run() function. Sending same target with some changes from my side here http://www.filedropper.com/graph –  Apr 09 '18 at 11:58
0

There is a way you can open 3rd party exe like a response window within your PowerBuilder application. Though I am not sure if that will be useful to you as you want to open it like a sheet window. Anyway, the following is the code.

Local External Function Declration:

Function long FindWindowA (long classname,  string windowname) LIBRARY "user32.dll" alias for "FindWindowA;Ansi"
Function Boolean BringWindowToTop (long classname) LIBRARY "user32.dll" alias for "BringWindowToTop;Ansi"

Local Function:

public function integer of_manage_third_party_exe ()
public function integer of_manage_third_party_exe ();///////////////////////////////////////////////////////////////////////////////////
//
// Returns 1 - window is not opened
//              -1 : A window is opened so bring it to top
//
///////////////////////////////////////////////////////////////////////////////////
long    ll_handle           //unique id of window opened

ll_handle = FindWindowA(0,"Title of third party exe")       

//If the window is not opened Then bring the window to top
If ll_handle > 0 Then
    Post BringWindowToTop(ll_handle)
    Return -1
End If

Return 1

Script in Activate event of your frame window/the window from which you are going to open the 3rd party exe:

of_manage_third_party_exe()

Script in CloseQuery event:

//if third party exe is open then don't allow to close the window
If of_manage_third_party_exe ( ) < 0 Then
    Return 1
End If

I guess it will help you figure out rest of the places where you might have to use the of_manage_third_party_exe function based on your functionality.

Ankur Patel
  • 1,413
  • 8
  • 14
  • The exe open with Run() function but user can close it while main application is still running. This is not supped to be a privilege. It does not matter what type it beome, either sheet or response will work. The Run function showed unexpected behavior even with a correct path it keep sending -1. The most important part of this question is that user should not be able to close the 3rd party app while using it. Yes, if somehow the exe behave as a a response or sheet window then i think rest of issues can be resolved with other tricks. Thanks for a good start you gave. –  Apr 03 '18 at 13:03