.

     

MPI Application Template
template.c
 

meiConfig1.c -- Invoking meiConfig From an Application
/* meiConfig1.c */

/* Copyright(c) 1991-2006 by Motion Engineering, Inc.  All rights reserved.
 *
 * This software  contains proprietary and  confidential information  of
 * Motion Engineering Inc., and its suppliers.  Except as may be set forth
 * in the license agreement under which  this software is supplied, use,
 * disclosure, or  reproduction is prohibited without the prior express
 * written consent of Motion Engineering, Inc.
 */

/*

This sample application describes how to call meiConfig programatically as a
separate process. stderr and stdout from the meiConfig process are written to 
stdout of this process.

Note that this applications is intended to compile for the Win32 operating
systems only. For other operating systems that are Posix compliant, the popen
system call may be used instead of win32_system.

Warning!  This is a sample program to assist in the integration of an
 MEI motion controller with your application.  It may not contain all
 of the logic and safety features that your application requires.

*/

#include <stdlib.h>
#include <windows.h>
#include <stdio.h>


DWORD win32_system (char* cmd);
void win32_displayError(char *pszAPI);

#if 1
   /* meiConfig must be in the PATH environment variable for this version of 
   // the MEI_CONFIG command to work. 
   */
#  define MEI_CONFIG "meiConfig " /* Note that the space at the end is necessary */
#else
   /* In this case the path to meiConfig is specified exactly. */
#  define MEI_CONFIG "C:\\MEI\\XMP\\bin\\WinNT\\meiConfig.exe "
#endif

#define CONFIG_FILE  "C:\\tmp\\foo.xmc"
#define GET_CMD      "-get -control 0 "
#define SET_CMD      "-set -control 0 "

#if 1
#  define FILTER_FILE   " "
#else
/* Specify your filter file below */
#  define FILTER_FILE   "-filter C:\\MEI\\XMP\\bin\\WinNT\\meiConfig_lib\\myFilterFile.txt "
#endif

int main(int     argc,
         char   *argv[])
{
   DWORD nExitStatus;

   /* Create the command by concatonating the various parts of the command 
   // together 
   */
   nExitStatus = win32_system(MEI_CONFIG GET_CMD FILTER_FILE CONFIG_FILE);

   if (nExitStatus != 0) {
      printf("meiConfig -get exit status is %d", nExitStatus);
   }
   else {
      nExitStatus = win32_system(MEI_CONFIG SET_CMD FILTER_FILE CONFIG_FILE);
      if (nExitStatus != 0) {
         printf("meiConfig -set exit status is %d", nExitStatus);
      }
   }

    /* return a success. */
    return 0;
}

/* The following code is based off of MSDN KB: Q190351 */
/* win32_system (char* cmd): Call the cmd. Write the stdout and stderr
 * generated by cmd to stdout of the calling process.
 */
DWORD win32_system (char* cmd)
{
   HANDLE hOutputReadTmp,hOutputRead,hOutputWrite;
   HANDLE hInputWriteTmp,hInputRead,hInputWrite;
   HANDLE hErrorWrite;
   SECURITY_ATTRIBUTES sa;
   PROCESS_INFORMATION pi;
   STARTUPINFO si;
   DWORD dwTermination = -1;
   CHAR lpBuffer[256];
   DWORD nBytesRead;

   printf("%s\n", cmd);

   /*
   // Set up the security attributes struct.
   */
   sa.nLength= sizeof(SECURITY_ATTRIBUTES);
   sa.lpSecurityDescriptor = NULL;
   sa.bInheritHandle = TRUE;


   /*
   // Create the child output pipe.
   */
   if (!CreatePipe(&hOutputReadTmp,&hOutputWrite,&sa,0)) {
      win32_displayError("CreatePipe");
   }


   /*
   // Create a duplicate of the output write handle for the std error
   // write handle. This is necessary in case the child application
   // closes one of its std output handles.
   */
   if (!DuplicateHandle(GetCurrentProcess(),hOutputWrite,
               GetCurrentProcess(),&hErrorWrite,0,
               TRUE,DUPLICATE_SAME_ACCESS)) {
      win32_displayError("DuplicateHandle");
   }


   /*
   // Create the child input pipe.
   */
   if (!CreatePipe(&hInputRead,&hInputWriteTmp,&sa,0)) {
      win32_displayError("CreatePipe");
   }


   /*
   // Create new output read handle and the input write handles. Set
   // the Properties to FALSE. Otherwise, the child inherits the
   // properties and, as a result, non-closeable handles to the pipes
   // are created.
   */
   if (!DuplicateHandle(GetCurrentProcess(),hOutputReadTmp,
               GetCurrentProcess(),
               &hOutputRead, /* Address of new handle. */
               0,FALSE, /* Make it uninheritable. */
               DUPLICATE_SAME_ACCESS)) {
      win32_displayError("DuplicateHandle");
   }

   if (!DuplicateHandle(GetCurrentProcess(),hInputWriteTmp,
                  GetCurrentProcess(),
                  &hInputWrite, /* Address of new handle. */
                  0,FALSE, /* Make it uninheritable. */
                  DUPLICATE_SAME_ACCESS)) {
      win32_displayError("DuplicateHandle");
   }


   /*
   // Close inheritable copies of the handles you do not want to be
   // inherited.
   */
   if (!CloseHandle(hOutputReadTmp)) {
      win32_displayError("CloseHandle");
   }
   if (!CloseHandle(hInputWriteTmp)) {
      win32_displayError("CloseHandle");
   }


   /*
   // Sets up STARTUPINFO structure, and launches redirected child.
   */

   /*
   // Set up the start up info struct.
   */
   ZeroMemory(&si,sizeof(STARTUPINFO));
   si.cb = sizeof(STARTUPINFO);
   /* Use STARTF_USESHOWWINDOW to hide the child */
   si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
   si.hStdOutput = hOutputWrite;
   si.hStdInput  = hInputRead;
   si.hStdError  = hErrorWrite;
   si.wShowWindow = SW_HIDE; /* Use this to hide the child */


   /*
   // Launch the process that you want to redirect (in this case, "cmd".)
   */
   if (!CreateProcess(NULL,cmd,NULL,NULL,TRUE,
         CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi)) {
      win32_displayError("CreateProcess");
   }

   /*
   // Close any unnecessary handles.
   */
   if (!CloseHandle(pi.hThread)) {
      win32_displayError("CloseHandle");
   }


   /*
   // Close pipe handles (do not continue to modify the parent).
   // You need to make sure that no handles to the write end of the
   // output pipe are maintained in this process or else the pipe will
   // not close when the child process exits and the ReadFile will hang.
   */
   if (!CloseHandle(hOutputWrite)) {
      win32_displayError("CloseHandle");
   }
   if (!CloseHandle(hInputRead )) {
      win32_displayError("CloseHandle");
   }
   if (!CloseHandle(hErrorWrite)) {
      win32_displayError("CloseHandle");
   }

   /*
   // Read the child's output.
   */
   while(TRUE) {
      if (!ReadFile(hOutputRead,lpBuffer,sizeof(lpBuffer),
            &nBytesRead,NULL) || !nBytesRead) {
         if (GetLastError() == ERROR_BROKEN_PIPE) {
            break; /* pipe done - normal exit path. */
         }
         else {
            win32_displayError("ReadFile"); /* Something bad happened. */
         }
      }

      fwrite(lpBuffer, sizeof(char), nBytesRead, stdout);
   }
   /*
   // Redirection is complete
   */

   if (!CloseHandle(hOutputRead)) {
      win32_displayError("CloseHandle");
   }
   if (!CloseHandle(hInputWrite)) {
      win32_displayError("CloseHandle");
   }
   if (!GetExitCodeProcess(pi.hProcess, &dwTermination)) {
      win32_displayError("GetExitCodeProcess");
   }

   return dwTermination;
}


/*
// win32_displayError
// Displays the error number and corresponding message.
*/
void win32_displayError(char *pszAPI)
{
   LPVOID lpvMessageBuffer;

   FormatMessage(
         FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM,
         NULL, GetLastError(),
         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
         (LPTSTR)&lpvMessageBuffer, 0, NULL);

   fprintf(stderr,
      "ERROR: API    = %s.\n   error code = %d.\n   message    = %s.\n",
         pszAPI, GetLastError(), (char *)lpvMessageBuffer);

   LocalFree(lpvMessageBuffer);
   ExitProcess(GetLastError());
}


 
      
       Legal Notice  |  Tech Email  |  Feedback
      
Copyright ©
2001-2009 Motion Engineering