Clarion Run vs CreateProcessA


#1

I have some old c5.5 code that uses CreateProcessA winapi vs Run. I can’t remember why, but RUN in earlier versions did not work too well.

In C11 the same code throws an access exception.

Is RUN safe now in c11?

Anyone have working c10+ code that calls createprocessA that they are willing to share?

Here is what I have now: (which fails in c11)

  program
  map
   module('')
 WaitForSingleObject(long hHandle, long  dwMilliseconds ),long,pascal,raw

 CreateProcessA(long lpApplicationName, long lpCommandLine, |
      long lpProcessAttributes , long lpThreadAttributes ,|
      long bInheritHandles , long dwCreationFlags , |
      long lpEnvironment, long lpCurrentDirectory, |
      StartupGroupType , ProcessGroupType),long,pascal,raw

 CloseHandle(long hObject),long,pascal,proc,raw

 GetExitCodeProcess(long hProcess, *long lpExitCode),long,pascal,proc,raw



     GetTickCount(),ULONG,RAW,PASCAL
   end

  end


  include('runexe.inc')

NORMAL_PRIORITY_CLASS long(20h)
INFINITE long(-1)
CREATE_SEPARATE_WOW_VDM     EQUATE(00000800h)

StartupGroupType  group,type
cb         Long
lpReserved long
lpDesktop   long
lpTitle   long
dwX   Long
dwY   Long
dwXSize   Long
dwYSize   Long
dwXCountChars   Long
dwYCountChars   Long
dwFillAttribute   Long
dwFlags   Long
wShowWindow   long  !Word
cbReserved2   long !WORD
lpReserved2   Long
hStdInput   Long
hStdOutput   Long
hStdError   Long
   End 

ProcessGroupType  group,type
hProcess   Long
hThread   Long
dwProcessID   Long
dwThreadID   Long
   End

  code
  return



RunThisClass.RunThis procedure(string command, string directory, short wait=0)
proc like(ProcessGroupType)
start like(StartupGroupType)
commandC cstring(300)
directoryC cstring(300)
ret long
creationFlag  long
WAIT_TIMEOUT equate(0102h)
   code
     ! ' Initialize the STARTUPINFO structure:
     
      start.cb = size(start)
      commandC = clip(command)
      directoryC = clip(directory)
 !     message(commandC)
 !     message(directoryC)
      creationFlag = NORMAL_PRIORITY_CLASS
      if SELF.separateFlag
         creationFlag += CREATE_SEPARATE_WOW_VDM
      end


      if (self.hideThis = true)
        start.dwFlags = 1 ! use wShowWindow
        start.wShowWindow =     0 ! hide
      end


      !' Start the shelled application:
      ret = CreateProcessA(0, address(commandC), 0, 0, 1, |
           creationFlag , 0, choose(len(directoryC)=0,0,address(directoryC)), start, proc)


    !  ' Wait for the shelled application to finish:

 

      if wait
       accept
        if event() = event:timer
         if WaitForSingleObject(proc.hProcess, 1 ) <> WAIT_TIMEOUT
           break
         end
        end
       end

       GetExitCodeProcess(proc.hProcess, ret)
       CloseHandle(proc.hThread)
       CloseHandle(proc.hProcess)
      end
   return ret



RunThisClass.Init    procedure(short separateFlag)
  code
    SELF.separateFlag = separateFlag
    SELF.hideThis = false
  return

RunThisClass.SetSeparate   procedure()
  code
    SELF.separateFlag = true
  return

RunThisClass.ClearSeparate procedure()
  code
    SELF.separateFlag = false
  return


RunThisClass.HideOutput   procedure()
  code
    SELF.hideThis = true
  return

#2

Looks like the createproccess definition that worked in c55 needed some updates for c11.

shows an alternative api declaration. (long -> ulong) and changing the last two from types to ulongs.


#3

I believe the Run() in clarion 10/11 is fixed. But using CreateProcessA should also work.

There are several templates that were used to do that, around. Looking at them should tell you what you have wrong (I don’t see it off hand).

HTH,

P.S. I did find this in my notes:
“But it always depends on the API and the use of that API. So even if you
are using only non-administrative APIs, you are not safe. For example, a
simple CreateProcess API to launch an external application. It is not an
administrative API per-se. But if you try to launch a program that itself
requests administrator execution level privileges from an non-elevated
running app, then CreateProcess will fail with error 740. It will succeed
if the calling program is running elevated.”