The Origin Forum
File Exchange
Try Origin for Free
The Origin Forum
Home | Profile | Register | Active Topics | Members | Search | FAQ | Send File to Tech support
 All Forums
 Origin Forum for Programming
 Forum for Origin C
 ShellExecute, WinExec and CreateProcess

Note: You must be registered in order to post a reply.
To register, click here. Registration is FREE!

Screensize:
UserName:
Password:
Anti-Spam Code:
Format Mode:
Format: BoldItalicizedUnderlineStrikethrough Align LeftCenteredAlign Right Horizontal Rule Insert HyperlinkUpload FileInsert Image Insert CodeInsert QuoteInsert List
   
Message:

* HTML is OFF
* Forum Code is ON
Smilies
Smile [:)] Big Smile [:D] Cool [8D] Blush [:I]
Tongue [:P] Evil [):] Wink [;)] Clown [:o)]
Black Eye [B)] Eight Ball [8] Frown [:(] Shy [8)]
Shocked [:0] Angry [:(!] Dead [xx(] Sleepy [|)]
Kisses [:X] Approve [^] Disapprove [V] Question [?]

 
Check here to subscribe to this topic.
   

T O P I C    R E V I E W
Alexander N Posted - 09/29/2009 : 2:08:17 PM
Origin Ver. and Service Release (Select Help-->About Origin): 8.0 SR5&6
Operating System: Windows XP Pro SP3

Hi guys,

since quite a long time I try to start an external program (which has only commandline inputs, no gui) out of OriginC.

I declared the MS C++ native methods shellExecute / Winexec and CreateProcess in a header file. Then I could start the program using WinExec and shellExecute, but Origin always crashes after this command and the external program is also stopped.

With createProcess I even could not call the program since I could not imagine how to redeclare the pointers for ProcessInformation and Security_Attr in native OriginC datatypes.

I hope that someone could please explain this program breakdown or even has a snipet for using createProcess with Origin!?


My header looks like this (switching the pragma regarding the method to use):

//#pragma dll(kernel32, system)
#pragma dll(shell32, system)


#include <common.h> // must always include this
#include <string.h> // most likely you will also need strings
#include <mswin.h>
#include <Origin.h>

BOOL WINAPI CreateProcessA(
  string lpApplicationName,
  string lpCommandLine,
  void * lpProcessAttributes,
  void * lpThreadAttributes,
  bool bInheritHandles,
  int dwCreationFlags,
  void * lpEnvironment,
  string lpCurrentDirectory,
  void * lpStartupInfo,
  void * lpProcessInformation
);

int WinExec(
  string lpCmdLine,
  int uCmdShow
);

void ShellExecuteA (    
    void * hwnd,
    string lpOperation,
    string lpFile,
    string lpParameters,
    string lpDirectory,
    int nShowCmd
);


And my code snippet for calling the method like this:

	void * start;
	void * info;
	
	
	try {
		//CreateProcessA(NULL, app, ¶ms, NULL, FALSE, 0, NULL, "", &start, &info);
		//out_str(info);
		//WinExec(app, 1);
		ShellExecuteA(NULL, "open", "TEST.EXE", params, path, 1);
		//out_str(GetLastError());
	}
	catch(int nErr) {
		out_int("Error Calling External DLL = ", nErr);
	}


Thanks in advance,

Alexander
12   L A T E S T    R E P L I E S    (Newest First)
Alexander N Posted - 10/20/2009 : 04:05:05 AM
Yes, that's a mistake in my upper example. This line is correct according to MSDN (error came from switching between CreateProcess and ShellExecute / WinExec):

#pragma dll(kernel32, system) // for CreateProcess


or


#pragma dll(shell32, system) // for WinExec and ShellExecute
alexander.steppke Posted - 10/19/2009 : 09:28:59 AM
Hi everybody,

it would be very helpful if you could summarize a complete working example, so that we know which files need to be changed to use the CreateProcess function with Origin 8 SR 6. I tried different approaches and at the end still have the error "Error, external DLL cannot find function shell32 : CreateProcess".

Thank you and greetings
Alexander
Alexander N Posted - 10/07/2009 : 02:25:22 AM
Yeap. Both seems to work. Your way could be more stable or "more right". So I followed your solution instead of call by reference. So, thanks again!
cpyang Posted - 10/06/2009 : 2:00:49 PM
How about this,


void create_and_terminate_process(int max = 100)
{
	STARTUPINFO			sinfo;
	
	PROCESS_INFORMATION	pinfo;
	
	memset(&sinfo, 0, sizeof(STARTUPINFO));
	memset(&pinfo, 0, sizeof(PROCESS_INFORMATION));
	
	sinfo.dwFlags = STARTF_USESHOWWINDOW;
	sinfo.wShowWindow = SW_SHOWMAXIMIZED;

	BOOL bSucess = CreateProcess("C:\\Windows\\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &sinfo, &pinfo);
		
	DWORD dwCode;
	
	if(GetExitCodeProcess(pinfo.hProcess, &dwCode))
	{
		if(dwCode == STATUS_PENDING)
			out_str("lunch successfully.");
		else
			printf("code = %X\n", dwCode);
	}
	else
		out_str("Failed to get exit code");
	
	if(dwCode != STATUS_PENDING)// something is wrong
		return;
	
	dwCode = 1;//init to some other values
	int timer = 0;
	while(GetExitCodeProcess(pinfo.hProcess, &dwCode) && dwCode == STATUS_PENDING) {
		Sleep(100);//0.1 sec, Origin will be totally dead
		timer++;
		if (timer == max)
		  TerminateProcess(pinfo.hProcess, 2);
	}
	printf("%d:final exit code = %X\n", timer, dwCode);		
}



I tested this and works by either user closing Notepad, or wait for 10 sec to terminate and you see the correct exit code for both cases.


CP
Alexander N Posted - 10/06/2009 : 10:14:43 AM
No, by reference &dwCode is possible. call by value does not exit the loop... Perhaps I'm wrong, but I thought this works.
cpyang Posted - 10/06/2009 : 07:57:03 AM
you mean to use


while(dwCode == STATUS_PENDING) 


right?
CP
Alexander N Posted - 10/06/2009 : 03:43:31 AM

	DWORD dwCode;
	int timer = 0;
	
	if(GetExitCodeProcess(pinfo.hProcess, &dwCode)) {
		while(&dwCode == STATUS_PENDING) {
			Sleep(0.1);
			timer++;
			if (timer > 100) {
			  TerminateProcess(pinfo.hProcess, 2);
			  printf("After terminated, code = %X\n", dwCode);
			  break;
			}
			GetExitCodeProcess(pinfo.hProcess, &dwCode);
		}
	}
	else {
		out_str("Failed to get exit code");
	}



Hi,
I now used a loop. It seems to work. Thanks for the improvements to the code base!

Alexander
cpyang Posted - 10/05/2009 : 4:48:03 PM
The following added to 8.1 mswin.h

//a subset of the status values that you might see in GetExitCodeProcess
#define STATUS_TIMEOUT                   0x00000102    
#define STATUS_PENDING                   0x00000103    
#define STATUS_ACCESS_VIOLATION          0xC0000005    
#define STATUS_IN_PAGE_ERROR             0xC0000006    
#define STATUS_INVALID_HANDLE            0xC0000008    
#define STATUS_NO_MEMORY                 0xC0000017    

BOOL WINAPI TerminateProcess(HANDLE hProcess, UINT uExitCode);
BOOL WINAPI GetExitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode);


And the following example added as well


void create_and_terminate_process()
{
	STARTUPINFO			sinfo;
	
	PROCESS_INFORMATION	pinfo;
	
	memset(&sinfo, 0, sizeof(STARTUPINFO));
	memset(&pinfo, 0, sizeof(PROCESS_INFORMATION));
	// test control wShowWindow
	sinfo.dwFlags = STARTF_USESHOWWINDOW;
	sinfo.wShowWindow = SW_SHOWMAXIMIZED;
	BOOL bSucess = CreateProcess("C:\\Windows\\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &sinfo, &pinfo);
		
	DWORD dwCode;
	
	if(GetExitCodeProcess(pinfo.hProcess, &dwCode))
	{
		if(dwCode == STATUS_PENDING)
			out_str("still alive");
		else
			printf("code = %X\n", dwCode);
	}
	else
		out_str("Failed to get exit code");

	//wait 1 sec
	LT_execute("sec -p 1");
	TerminateProcess(pinfo.hProcess, 2);
	if(GetExitCodeProcess(pinfo.hProcess, &dwCode))
		printf("After terminated, code = %X\n", dwCode);
	else
		out_str("Failed to get exit code");
		
}



If you need to wait for process to be terminated by the user, then maybe build your own loop with LT_execute("sec -p 0.2") in the loop.

CP

cpyang Posted - 10/05/2009 : 4:13:36 PM
We have modified LPSECURITY_ATTRIBUTES in the Origin 8.1 mswin.h, sorry I forgot to mention.


Sure, we will add GetExitCodeProcess to mswin.h as well, and that function is simple so you can add to yours.

CP
Alexander N Posted - 10/05/2009 : 11:43:30 AM
Ok, now it works properly without break down. But how can I determine when the process has finished? Is it sufficient to copy all the definitions from MSDN:GetExitCodeProcess to my header and then execute GetExitCodeProcess?
Alexander N Posted - 10/05/2009 : 10:54:00 AM
quote:
Originally posted by cpyang

BOOL WINAPI CreateProcess(
  LPCSTR lpApplicationName,
  LPSTR lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL bInheritHandles,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCSTR lpCurrentDirectory,
  LPSTARTUPINFO lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);




Here I get an compiler error regarding syntax of the variables and type of variables. I tried a debug but could not distinguish which variable is affected.


Edit: Comparing your solution with your mswin.h, I suggest, that LPSECURITY_ATTRIBUTES should be replaced with a pointer SECURITY_ATTRIBUTES * ?? Then the code compiles successfully...
cpyang Posted - 10/02/2009 : 2:41:12 PM
The following has been added to mswin.h in upcoming Origin 8.1 and you can copy and paste into your own header in Origin 8. After #pragma dll(kernel32, system)

CP









//
// dwCreationFlags (Process Creation Flags) used in CreateProcess 
//
#define DEBUG_PROCESS               0x00000001
#define DEBUG_ONLY_THIS_PROCESS     0x00000002

#define CREATE_SUSPENDED            0x00000004

#define DETACHED_PROCESS            0x00000008

#define CREATE_NEW_CONSOLE          0x00000010

#define NORMAL_PRIORITY_CLASS       0x00000020
#define IDLE_PRIORITY_CLASS         0x00000040
#define HIGH_PRIORITY_CLASS         0x00000080
#define REALTIME_PRIORITY_CLASS     0x00000100

#define CREATE_NEW_PROCESS_GROUP    0x00000200
#define CREATE_UNICODE_ENVIRONMENT  0x00000400

#define CREATE_SEPARATE_WOW_VDM     0x00000800
#define CREATE_SHARED_WOW_VDM       0x00001000
#define CREATE_FORCEDOS             0x00002000

#define CREATE_BREAKAWAY_FROM_JOB	0x01000000
#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL 0x02000000
#define CREATE_DEFAULT_ERROR_MODE   0x04000000
#define CREATE_NO_WINDOW            0x08000000
//probably don't need these in OC
//#define PROFILE_USER                0x10000000
//#define PROFILE_KERNEL              0x20000000
//#define PROFILE_SERVER              0x40000000

//
// dwFlags in STARTUPINFO Structure
//
#define STARTF_USESHOWWINDOW    0x00000001
#define STARTF_USESIZE          0x00000002
#define STARTF_USEPOSITION      0x00000004
#define STARTF_USECOUNTCHARS    0x00000008
#define STARTF_USEFILLATTRIBUTE 0x00000010
#define STARTF_RUNFULLSCREEN    0x00000020  // ignored for non-x86 platforms
#define STARTF_FORCEONFEEDBACK  0x00000040
#define STARTF_FORCEOFFFEEDBACK 0x00000080
#define STARTF_USESTDHANDLES    0x00000100
#define STARTF_USEHOTKEY        0x00000200

typedef struct _STARTUPINFO {
    DWORD   cb;
    LPSTR   lpReserved;
    LPSTR   lpDesktop;
    LPSTR   lpTitle;
    DWORD   dwX;
    DWORD   dwY;
    DWORD   dwXSize;
    DWORD   dwYSize;
    DWORD   dwXCountChars;
    DWORD   dwYCountChars;
    DWORD   dwFillAttribute;
    DWORD   dwFlags;
    WORD    wShowWindow;
    WORD    cbReserved2;
    BYTE	*lpReserved2;
    HANDLE  hStdInput;
    HANDLE  hStdOutput;
    HANDLE  hStdError;
} STARTUPINFO, *LPSTARTUPINFO;

typedef struct _PROCESS_INFORMATION {
    HANDLE hProcess;
    HANDLE hThread;
    DWORD dwProcessId;
    DWORD dwThreadId;
} PROCESS_INFORMATION, *LPPROCESS_INFORMATION;

#define CreateProcess  CreateProcessA
/**
		The CreateProcess function creates a new process and its primary thread. The new process executes the specified executable file.
	Remarks:	
		For more info please check: http://msdn.microsoft.com/en-us/library/ms682425(VS.85).aspx
	Example:
	void test_create_process()
	{
		STARTUPINFO			sinfo;		
		PROCESS_INFORMATION	pinfo;		
		memset(&sinfo, 0, sizeof(STARTUPINFO));
		memset(&pinfo, 0, sizeof(PROCESS_INFORMATION));
		// test control wShowWindow
		sinfo.dwFlags = STARTF_USESHOWWINDOW;
		sinfo.wShowWindow = SW_SHOWMAXIMIZED;
		BOOL bSucess = CreateProcess("C:\\Windows\\notepad.exe", NULL, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, NULL, NULL, &sinfo, &pinfo);
	}
*/
BOOL WINAPI CreateProcess(
  LPCSTR lpApplicationName,
  LPSTR lpCommandLine,
  LPSECURITY_ATTRIBUTES lpProcessAttributes,
  LPSECURITY_ATTRIBUTES lpThreadAttributes,
  BOOL bInheritHandles,
  DWORD dwCreationFlags,
  LPVOID lpEnvironment,
  LPCSTR lpCurrentDirectory,
  LPSTARTUPINFO lpStartupInfo,
  LPPROCESS_INFORMATION lpProcessInformation
);




The Origin Forum © 2020 Originlab Corporation Go To Top Of Page
Snitz Forums 2000