1. Suresh Thoduvail
  2. PowerBuilder
  3. Friday, 5 August 2022 14:39 PM UTC

Hi All,

  

Our PowerBuilder Application (PB 2021 Build 1506 ) is not able to check if outlook.exe is open 
with the Apps for Enterprise (
new version of Office that M365) installed on a user machine. Our code is checking if Outlook is open prior to opening an email in a compose mode (send, reply or import) mode
but instead get the following error message: users get the error message: "Microsoft Outlook is not available"

Please provide any suggestions.
*Reproduce Steps:

Install Office M365 outlook and run the script below:
/*code start*/ nvo_process lnvo_process /*non visual user objected, not inherited from any ancestors. code attached for this object*/ lb_outlook_running = lnvo_process.of_is_process_running("outlook.exe") If Not lb_outlook_running Then Messagebox("Outlook Error","Microsoft Outlook is not available " + "~r~nPlease open your Microsoft Outlook to Continue with Emails Reply or Import!") Return End If
/*code end*/
Remarks: 

1. This code works find in we downgrade office back to Office 2016.
2. Office 365 once installed still have the executable for outlook called "outlook.exe"


/*Code of the nvo_process non visual user object not inherited*/
Declaration Local External Function:
Function Boolean EnumProcesses(REF processEntry Process, long cb, REF long cbNeeded ) Library "PSAPI.DLL"

Code for of_is_process_running:


// of_is_process_running
ProcessEntry pe_Process // Window structure (array of 500 ulong)
ModuleEntry me_Module // Window structure (array of 100 long)
PROCESS_MEMORY_COUNTERS pmc
long ll_size_of_process = 2000 // Size of Process
long ll_size_of_module = 400 // Size of Module
long ll_needed_size_of_process // returned size of Process
long ll_needed_size_of_module // returned size of Module

long ll_resName // size of returned name of the module
long li_cnt // for looping through processes
int li_total // for looping through processes
long ll_process_found

boolean lb_resultP // return codes for EnumProcesses and EnumProcessModules
boolean lb_resultM

string ls_module_name // Name of the module
string ls_process_to_find

TRY

ls_process_to_find = as_process_name

lb_resultP = EnumProcesses(pe_Process, ll_size_of_process, ll_needed_size_of_process)

IF lb_resultP THEN
li_total = integer(ll_needed_size_of_process / 4)
FOR li_cnt = 1 TO li_total
iul_HandleP[li_cnt] = OpenProcess(PROCESS_ALL_ACCESS, FALSE, &
pe_Process.lpIdProcess[li_cnt])
lb_resultM = EnumProcessModules(iul_HandleP[li_cnt], me_Module, &
ll_size_of_module, ll_needed_size_of_module)
IF ll_needed_size_of_module >= 4 THEN
IF GetProcessMemoryInfo(iul_HandleP[li_cnt], pmc, 40) THEN
ls_module_name = Space(254)
ll_resName = GetModuleBaseNameA(iul_HandleP[li_cnt], &
me_Module.lpidmodule[1], ls_module_name, 254)
IF Trim(Lower(ls_module_name)) = Trim(Lower(ls_process_to_find)) THEN
ll_process_found ++
END IF
END IF
END IF
CloseHandle(iul_HandleP[li_cnt])
NEXT

IF ll_process_found > 0 THEN
RETURN TRUE
ELSE
RETURN FALSE
END IF
ELSE
RETURN FALSE
END IF
CATCH (exception e1)
MessageBox( "Exception Error", e1.getMessage() )
CATCH (runtimeerror r1)
MessageBox("Run Time Exception", r1.getMessage())
CATCH (throwable t1)
MessageBox("Other Exception", t1.getMessage())
END TRY






 

 

Attachments (1)
Chris Pollach @Appeon Accepted Answer Pending Moderation
  1. Friday, 5 August 2022 15:05 PM UTC
  2. PowerBuilder
  3. # 1

Hi Suresh; 

  For O365 your IT may have installed the 64bit client. Thus, you'll need to have your App deployed as a 64bit EXE.  If that is the case (and it works a la 64bit mode) but you don't want to upgrade your PB App EXE from 32bit at this time then, create a 64bit PB App & call it from your 32bit main App to "broker" the Outlook interactions. Food for thought.

Regards ... Chris 

Comment
  1. Miguel Leeuwe
  2. Friday, 5 August 2022 18:55 PM UTC
Hi Chris,

You're wrong about one thing. A 32 bit Powerbuilder application works perfectly fine with Outlook 64 bits (when using OLE).

Now what I'm not sure about is whether the API function would detect a 64 bit Outlook running or not. (Function Boolean EnumProcesses(REF processEntry Process, long cb, REF long cbNeeded ) Library "PSAPI.DLL")
  1. Helpful
  1. Mark Goldsmith
  2. Friday, 5 August 2022 22:32 PM UTC
Hi Miguel...I might agree with you but I think it depends on what Chris was referring to in his reply about bitness in the context of the OPs question. If Chris is referring to the integration between a 32 bit PB app and an Office 64 bit app then you would be correct, as you say, when using OLE integration (but not mailsession where, if I remember correctly, bitness matters).



If, however, Chris was referring to the use of the external function call EnumProcesses from a 32 bit PB application with respect to 64 bit processes then he is correct as it will not include 64 bit processes in the list. Even though the Microsoft docs only refer to the bitness having to be the same when using the external function call EnumProcessModules in order to include 64 bit processes, I believe it also applies to the EnumProcesses function too and is an omission in their docs.

See my reply for another approach (using 1 line) to accomplish what the OP wanted to do...but I like your approach that uses WbemScripting!

Regards,

Mark
  1. Helpful 3
  1. Miguel Leeuwe
  2. Saturday, 6 August 2022 05:29 AM UTC
Hi Mark,

Yes I totally agree with what you are saying. That was also what I tried to say. Plus I wasn't sure about the 32 bit PB app being able to use the API to find 64 bit processes. (thanks for clearing that doubt!).

Indeed Mailsession and Mapi wouldn't work, that's why I said that it works when using OLE.

The reason for my remarks is that Chris (with all respect), in other posts / Q&As - when it comes to pb 32 bit and outlook 64 - always answers that the PB app HAS to be also 64 bit. (and I always try to explain that that's not really true).

Regards,

MiguelL
  1. Helpful
There are no comments made yet.
Miguel Leeuwe Accepted Answer Pending Moderation
  1. Friday, 5 August 2022 19:01 PM UTC
  2. PowerBuilder
  3. # 2

Hi,

This is what I do to detect if Outlook is running:

OLEOBJECT lole_Locator, lole_Service, lole_Props
STRING ls_Query 
INTEGER li_Cnt, li_Ret
LONG ll_i

ls_Query ="Select ProcessID from Win32_process where name = 'outlook.exe'"
lole_Locator = CREATE OleObject

TRY
                                
                li_Ret = lole_Locator.ConnectToNewObject("WbemScripting.SWbemLocator")
                lole_Service = lole_Locator.ConnectServer()
                lole_Service = lole_Service.ExecQuery(ls_Query)
                li_Cnt = lole_Service.Count()
                DESTROY lole_Locator
                
                IF li_Cnt > 0 THEN
                                RETURN // Outlook is already running, nothing to do.
                END IF
                
                // Try to Open Outlook
                ShellExecute(Handle(THIS), 'Open', "outlook.exe", uo_global.NullString, uo_global.NullString, 1)  // 1=Normal (last used winState), 3=maximized
                Sleep(2)
CATCH (OleRuntimeError OLEException)
                // do nothing
CATCH (Throwable TException)
                // do nothing
END TRY

IF IsValid(lole_Locator) THEN
                DESTROY lole_Locator
END IF

 

This is my external function declaration:

Function Long ShellExecute( Long hwnd, string lpOperation, string lpfile, string lpparameters, string lpdirectory, integer nshowcmd) Library "shell32.dll" alias for "ShellExecuteW".

for 64 bit executables in powerbuilder, I'll probably have to change the hWnd variable to use a LongPtr variable.

regards,

miguelL

 

Comment
  1. Suresh Thoduvail
  2. Friday, 5 August 2022 23:38 PM UTC
Thanks Miguel, really appreciate you sharing your method.
  1. Helpful
  1. Miguel Leeuwe
  2. Saturday, 6 August 2022 05:45 AM UTC
yw,

BTW "uo_global.NullString" is simply a String variable which has been set to null by using SetNull().
  1. Helpful 1
There are no comments made yet.
Mark Goldsmith Accepted Answer Pending Moderation
  1. Friday, 5 August 2022 22:37 PM UTC
  2. PowerBuilder
  3. # 3

Hi Suresh,

The command line equivalent to running Task Manager is to use the tasklist command (in conjunction with the find and start commands) which has a variety of options which will allow you to accomplish what you want to do. This would be used in conjunction with the PB Run() command and would look like the following:

Run('cmd /c tasklist.exe /nh /fi "IMAGENAME eq outlook.exe" | find /i "outlook.exe" > nul || (start outlook.exe)')

I won't take the time to explain what all the options are as you can Google those but this should accomplish what you would like irrespective of what bitness your PB app is or the bitness of the process you're trying to find.

The first pipe symbol sends the output of the first command as input to the second command and the double-pipe allows the third command to run if the second command fails.

HTH...regards,

Mark

Comment
  1. Suresh Thoduvail
  2. Friday, 5 August 2022 23:40 PM UTC
Thanks Mark for sharing your method. Appreciate your feedback.
  1. Helpful
  1. Mark Goldsmith
  2. Saturday, 6 August 2022 12:18 PM UTC
You're welcome Suresh and hope you find a solution that works for you.
  1. Helpful 1
There are no comments made yet.
  • Page :
  • 1


There are no replies made for this question yet.
However, you are not allowed to reply to this question.