Running a process

M

MattMenard

I've written a C program that I want to run inside an Gui wrapper that
I started to write in MFC. I have to select some files then kick off a
process running the C program. I have the initial dialog file
selection stuff written, but am not sure how to run the C program
inside a seperate thread. I'm using VS.NET 2003 and am trying to use
the Thread and Process objects, but am not sure if I can use that with
MFC. I can't compile the code I have because I get some compiler
errors...

TAD2H5TDTestGui.cpp(57): error C3828: 'System::Diagnostics::process':
placement arguments not allowed while creating instances of managed
classes.
TAD2H5TDTestGui.cpp(148): error C3828:
'System::Threading::ThreadStart': placement arguments not allowed while
creating instances of managed classes.
TAD2H5TDTestGui.cpp(149): error C3828: 'System::Threading::Thread':
placement arguments not allowed while creating instances of managed
classes.

I looked up what placement arguments are in the documentation, but
found that I don't have any in the code. Here's the code with the line
numbers marked that have the errors. I've include both the header and
the source file, where the errors are.

////////////////////////////////////////////////////////////
// TAD2H5TDTestGui.h : main header file for the application
////////////////////////////////////////////////////////////

#pragma once

#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif

#include <string>
#include "resource.h" // main symbols

using std::string;

// CTAD2H5TDTestGuiApp:
// See TAD2H5TDTestGui.cpp for the implementation of this class
//

class CTAD2H5TDTestGuiApp : public CWinApp
{
public:

CTAD2H5TDTestGuiApp();
static void ProcessRunner();

// Overrides
public:
virtual BOOL InitInstance();

// Implementation
DECLARE_MESSAGE_MAP()
};

extern CTAD2H5TDTestGuiApp theApp;

////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////
// TAD2H5TDTestGui.cpp : Defines the class behaviors for the app.
////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TAD2H5TDTestGui.h"
#include "TAD2H5TDTestGuiDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#using <mscorlib.dll>
#using <System.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Diagnostics;
using namespace System::ComponentModel;

// CTAD2H5TDTestGuiApp

BEGIN_MESSAGE_MAP(CTAD2H5TDTestGuiApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

// The one and only CTAD2H5TDTestGuiApp object

CTAD2H5TDTestGuiApp theApp;
CString fileType = "";
CString openFile = "";
CString saveFile = "";


// CTAD2H5TDTestGuiApp construction

CTAD2H5TDTestGuiApp::CTAD2H5TDTestGuiApp(){
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}

void CTAD2H5TDTestGuiApp::processRunner() {
CString commandStr;

if (fileType == "hdf5") {
commandStr = "c:\\hdf5\\tad2h5td\\tad2h5td.exe";
} else {
commandStr = "c:\\matlab\\tad2matlab\\tad2matlab.exe";
}


commandStr = commandStr + " " + openFile + " " + saveFile + " -bs
50000";

TRACE("\n" + commandStr + "\n\n");

// M *m1 = new M();

try {
myProcess->StartInfo->FileName = commandStr;

myProcess->StartInfo->UseShellExecute = false;
myProcess->StartInfo->RedirectStandardOutput = true;

myProcess->Start();

Console::WriteLine(myProcess->StandardOutput->ReadToEnd());

myProcess->WaitForExit();

} catch (Win32Exception *e) {
if(e->NativeErrorCode == ERROR_ACCESS_DENIED) {
Console::WriteLine(S"{0}. You don't have permission to access this
file.",e->Message);

}
}
}

// CTAD2H5TDTestGuiApp initialization

BOOL CTAD2H5TDTestGuiApp::InitInstance()
{
// InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
InitCommonControls();

CWinApp::InitInstance();

AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));

CTAD2H5TDTestGuiDlg* openDlg = new CTAD2H5TDTestGuiDlg(TRUE,NULL) ;
// m_pMainWnd = openDlg;
INT_PTR nResponse = openDlg->DoModal();
if (nResponse == IDOK) {

// TODO: Place code here to handle when the dialog is
// dismissed with OK
openFile = openDlg->GetPathName();
TRACE("\n" + openFile + "\n\n");
delete openDlg;

CTAD2H5TDTestGuiDlg* saveDlg = new CTAD2H5TDTestGuiDlg(FALSE,NULL)
;
nResponse = saveDlg->DoModal();
if (nResponse == IDOK) {

// TODO: Place code here to handle when the dialog is
// dismissed with OK
saveFile = saveDlg->GetPathName();
fileType = saveDlg->GetFileExt();
TRACE("\n" + saveFile + "\n\n");
TRACE("\n" + fileType + "\n\n");
delete saveDlg;

//System
// TODO: Place code here to handle when the dialog is
// dismissed with OK

} else if (nResponse == IDCANCEL) {
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
delete saveDlg;
}
}
else if (nResponse == IDCANCEL) {
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
delete openDlg;
}

// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

int main() {
// Console::WriteLine("The Main Program Starts!");
thr1.Start();
Console::WriteLine("The Main Program Ends!");
}


/////////////////////////////////////////////////////////////


I'm not sure what I'm doing wrong. Also, if you have any other
comments like what are you doing that for, please let me know. I
usually try things until they work, but that doesn't mean that it's the
best way to do it. Thanks for any and all help...
 
R

Ronald Laeremans [MSFT]

MattMenard said:
I've written a C program that I want to run inside an Gui wrapper that
I started to write in MFC. I have to select some files then kick off a
process running the C program. I have the initial dialog file
selection stuff written, but am not sure how to run the C program
inside a seperate thread. I'm using VS.NET 2003 and am trying to use
the Thread and Process objects, but am not sure if I can use that with
MFC. I can't compile the code I have because I get some compiler
errors...

TAD2H5TDTestGui.cpp(57): error C3828: 'System::Diagnostics::process':
placement arguments not allowed while creating instances of managed
classes.
TAD2H5TDTestGui.cpp(148): error C3828:
'System::Threading::ThreadStart': placement arguments not allowed while
creating instances of managed classes.
TAD2H5TDTestGui.cpp(149): error C3828: 'System::Threading::Thread':
placement arguments not allowed while creating instances of managed
classes.

I looked up what placement arguments are in the documentation, but
found that I don't have any in the code. Here's the code with the line
numbers marked that have the errors. I've include both the header and
the source file, where the errors are.

////////////////////////////////////////////////////////////
// TAD2H5TDTestGui.h : main header file for the application
////////////////////////////////////////////////////////////

#pragma once

#ifndef __AFXWIN_H__
#error include 'stdafx.h' before including this file for PCH
#endif

#include <string>
#include "resource.h" // main symbols

using std::string;

// CTAD2H5TDTestGuiApp:
// See TAD2H5TDTestGui.cpp for the implementation of this class
//

class CTAD2H5TDTestGuiApp : public CWinApp
{
public:

CTAD2H5TDTestGuiApp();
static void ProcessRunner();

// Overrides
public:
virtual BOOL InitInstance();

// Implementation
DECLARE_MESSAGE_MAP()
};

extern CTAD2H5TDTestGuiApp theApp;

////////////////////////////////////////////////////////////




////////////////////////////////////////////////////////////////
// TAD2H5TDTestGui.cpp : Defines the class behaviors for the app.
////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TAD2H5TDTestGui.h"
#include "TAD2H5TDTestGuiDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#using <mscorlib.dll>
#using <System.dll>

using namespace System;
using namespace System::Threading;
using namespace System::Diagnostics;
using namespace System::ComponentModel;

// CTAD2H5TDTestGuiApp

BEGIN_MESSAGE_MAP(CTAD2H5TDTestGuiApp, CWinApp)
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()

// The one and only CTAD2H5TDTestGuiApp object

CTAD2H5TDTestGuiApp theApp;
CString fileType = "";
CString openFile = "";
CString saveFile = "";


// CTAD2H5TDTestGuiApp construction

CTAD2H5TDTestGuiApp::CTAD2H5TDTestGuiApp(){
// TODO: add construction code here,
// Place all significant initialization in InitInstance
}

void CTAD2H5TDTestGuiApp::processRunner() {
CString commandStr;

if (fileType == "hdf5") {
commandStr = "c:\\hdf5\\tad2h5td\\tad2h5td.exe";
} else {
commandStr = "c:\\matlab\\tad2matlab\\tad2matlab.exe";
}


commandStr = commandStr + " " + openFile + " " + saveFile + " -bs
50000";

TRACE("\n" + commandStr + "\n\n");

// M *m1 = new M();




try {
myProcess->StartInfo->FileName = commandStr;

myProcess->StartInfo->UseShellExecute = false;
myProcess->StartInfo->RedirectStandardOutput = true;

myProcess->Start();

Console::WriteLine(myProcess->StandardOutput->ReadToEnd());

myProcess->WaitForExit();

} catch (Win32Exception *e) {
if(e->NativeErrorCode == ERROR_ACCESS_DENIED) {
Console::WriteLine(S"{0}. You don't have permission to access this
file.",e->Message);

}
}
}

// CTAD2H5TDTestGuiApp initialization

BOOL CTAD2H5TDTestGuiApp::InitInstance()
{
// InitCommonControls() is required on Windows XP if an application
// manifest specifies use of ComCtl32.dll version 6 or later to enable
// visual styles. Otherwise, any window creation will fail.
InitCommonControls();

CWinApp::InitInstance();

AfxEnableControlContainer();

// Standard initialization
// If you are not using these features and wish to reduce the size
// of your final executable, you should remove from the following
// the specific initialization routines you do not need
// Change the registry key under which our settings are stored
// TODO: You should modify this string to be something appropriate
// such as the name of your company or organization
SetRegistryKey(_T("Local AppWizard-Generated Applications"));

CTAD2H5TDTestGuiDlg* openDlg = new CTAD2H5TDTestGuiDlg(TRUE,NULL) ;
// m_pMainWnd = openDlg;
INT_PTR nResponse = openDlg->DoModal();
if (nResponse == IDOK) {

// TODO: Place code here to handle when the dialog is
// dismissed with OK
openFile = openDlg->GetPathName();
TRACE("\n" + openFile + "\n\n");
delete openDlg;

CTAD2H5TDTestGuiDlg* saveDlg = new CTAD2H5TDTestGuiDlg(FALSE,NULL)
;
nResponse = saveDlg->DoModal();
if (nResponse == IDOK) {

// TODO: Place code here to handle when the dialog is
// dismissed with OK
saveFile = saveDlg->GetPathName();
fileType = saveDlg->GetFileExt();
TRACE("\n" + saveFile + "\n\n");
TRACE("\n" + fileType + "\n\n");
delete saveDlg;

//System
// TODO: Place code here to handle when the dialog is
// dismissed with OK

} else if (nResponse == IDCANCEL) {
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
delete saveDlg;
}
}
else if (nResponse == IDCANCEL) {
// TODO: Place code here to handle when the dialog is
// dismissed with Cancel
delete openDlg;
}

// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}

int main() {
// Console::WriteLine("The Main Program Starts!");



thr1.Start();
Console::WriteLine("The Main Program Ends!");
}


/////////////////////////////////////////////////////////////


I'm not sure what I'm doing wrong. Also, if you have any other
comments like what are you doing that for, please let me know. I
usually try things until they work, but that doesn't mean that it's the
best way to do it. Thanks for any and all help...


#ifdef _DEBUG
#define new DEBUG_NEW
#endif

Is the problem. Remove that and for safety add

#undef new

after where that block originally was (in case you picked up the
definition from the MFC headers).

Look at the second question in this MSDN column for full details as to
what is happening:
http://msdn.microsoft.com/msdnmag/issues/04/09/CQA/default.aspx

Thanks.

Ronald Laeremans
 
Top