Link to home
Start Free TrialLog in
Avatar of swhitlow
swhitlow

asked on

VC++ Compiling Problems...

I'm a very new C++ programmer. I was wondering if someone could take a look at the following code, then look at the errors that I am having when I try and build the project, and offer a suggestion. Basically, all this small program does is opens a text file and reads two lines, then executes one program, wait for it to close then executes the next, then it's done. It works fine if I take hard code the actual files to open. Anyway, here is the code:

//** Begin Code

// ** include header files
#include <stdlib.h>
#include "stdafx.h"
#include <iostream.h>
#include <stdio.h>

int APIENTRY WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR     lpCmdLine,
                   int       nCmdShow)
{
   
     FILE *afile;
     afile=fopen("C:\\init.dat","r");
     char c;

     while(c!=EOF)
     {
          c=fgetc(afile);
     }

     fclose(afile);

     STARTUPINFO si;
     memset(&si, 0, sizeof(STARTUPINFO));

     si.cb = sizeof(STARTUPINFO);
     si.lpReserved = NULL;
     si.lpDesktop = "WinSta0\\Default";
     si.lpTitle = NULL;

     PROCESS_INFORMATION pi;
     
     // Execute first application or setup package (i.e. InstMsi.exe /q)
     if(CreateProcess(
          NULL,
          c,
          NULL,
          NULL,
          FALSE,
          0,
          NULL,
          NULL,
          &si,
          &pi
          )){

          // DO NOT DELETE! This will cause resource leaks if any of the
          // CloseHandle fn's are not processed. CloseHandle closes the thread that the resource uses
          // during execution.
          CloseHandle(pi.hThread);

          // Wait for application to finish
          WaitForSingleObject(pi.hProcess, INFINITE);

          // Kill the process
          CloseHandle(pi.hProcess);
   }


     // Execute second application or setup package (i.e. Setup.exe)
     if(CreateProcess(
          NULL,
          c,
          NULL,
          NULL,
          FALSE,
          0,
          NULL,
          NULL,
          &si,
          &pi
          )){

          // Close both processes
          CloseHandle(pi.hThread);
          CloseHandle(pi.hProcess);
   }

   return 0;
}

//** End Code

Here are the error messages that I am receiving:

//** Begin Debug Information

--------------------Configuration: SetupALL - Win32 Release--------------------
Compiling...
SetupALL.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\SetupALL\SetupALL.cpp(46) : error C2664: 'CreateProcessA' : cannot convert parameter 2 from 'char' to 'char *'
        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
C:\Program Files\Microsoft Visual Studio\MyProjects\SetupALL\SetupALL.cpp(73) : error C2664: 'CreateProcessA' : cannot convert parameter 2 from 'char' to 'char *'
        Conversion from integral type to pointer type requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.

SetupALL.obj - 2 error(s), 0 warning(s)

//** End Debug Information

Thanks in advance for your help!
Avatar of robpitt
robpitt

Regarding:
    char c;

    while(c!=EOF)
    {
        c=fgetc(afile);
    }

The above code declares a *single* character 'c' and then repeatadle reads characters from the file until EOF is encountered.

What you probably meant to do is read a complete string (i.e. an array of characters terminated by a null character). The following accomplishs this:
    char filename[300];

    //Read the current line from the file reading at most 300 characters.
    fgets(filename,sizeof(filename),afile);

Then pass 'filename' as the parameter to CreateProcess.

Rob
1) This is C code, not really C++.  We can go into this in detail later, but basically you're using many things that a C++ programmer wouldn't (normally) use.

2) The reason for the error is that c is defined as a single char, rather than a pointer to an array of chars, as CreateProcess expects.  This array of chars is a C-style string, and can be referenced by a pointer to the first character in the array.

<snipped example code having seen robpitt's post>

If you're interested in how C++ would approach this problem, just ask.  I'll be offline for a few hours.
Avatar of swhitlow

ASKER

LainHere, yes, I would like to know how to do this (read a file) with C++ instead of C. What would I do to accomplish this?  Thanks!
robpitt,

I tried your code that you posted for me to change. it compiles fine but then it doesn't do anything. I've tried changing filenames, contents of file, etc. Can you offer any other suggestions? Thanks!


>>opens a text file and reads two lines ...
while(c!=EOF)
      {
               c=fgetc(afile);
      }
Why you then read until end file? Read until two \n
are found then:

int iNewLines=0;
     while(c!=EOF)
      {
               c=fgetc(afile);
               if(c=='\n')iNewLines++;
               if(iNewLines>=2)break;
      }


Second param to CreateProcess must be char array or pointer to it
(as robpitt noted).
//LPTSTR lpCommandLine -
//Pointer to a null-terminated string that specifies the command line to execute.
Declare instead char c another variable for example
char cc[260];
and pass it as lpCommandLine (second parameter), but before you must
copy a real stuff to it:
 strcpy(cc,"InstMsi.exe /q"); or define right in declaration
char cc[260]="InstMsi.exe /q";
      if(CreateProcess(
               NULL,
               cc,
               NULL,
               ....
or right to function
      if(CreateProcess(
               NULL,
               "InstMsi.exe /q",
               NULL,
               ....
If you use NT OS i do not know exact usage of CreateProcess in this case.
For Win95/98 works if  char cc[260]="C:\\InstMsi.exe /q";// full path

Not forget to close file opened : fclose(afile);
Please - someone try and solve this problem. I am very new to C++ so anyone who would happen to do this please include as much detail as you can. I can now compile with no problem at all however, nothing happens! It's like it's not even reading the text file. I have no idea how to check and see if it's reading the text file. Please help me! Here is the new updated code for you to take a look at (or copy it and see if you can make it work. It's a Visual C++ Win32 Application). You can view up above the beginning of this question to find out what I'm trying to accomplish:

//** Begin Code **//

// ** include header files
#pragma warning(disable:4786)
#include <stdlib.h>
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

int APIENTRY WinMain(HINSTANCE hInstance,
                   HINSTANCE hPrevInstance,
                   LPSTR     lpCmdLine,
                   int       nCmdShow)
{
   
     FILE *afile;
    afile=fopen("C:\\init.dat","r");
    char filename[300];

    fgets(filename,sizeof(filename),afile);

     STARTUPINFO si;
     memset(&si, 0, sizeof(STARTUPINFO));

     si.cb = sizeof(STARTUPINFO);
     si.lpReserved = NULL;
     si.lpDesktop = "WinSta0\\Default";
     si.lpTitle = NULL;

     PROCESS_INFORMATION pi;
     
     // Execute first application or setup package (i.e. InstMsi.exe /q)
     if(CreateProcess(
          NULL,
          filename,
          NULL,
          NULL,
          FALSE,
          0,
          NULL,
          NULL,
          &si,
          &pi
          )){

          // DO NOT DELETE! This will cause resource leaks if any of the
          // CloseHandle fn's are not processed. CloseHandle closes the thread that the resource uses
          // during execution.
          CloseHandle(pi.hThread);

          // Wait for application to finish
          WaitForSingleObject(pi.hProcess, INFINITE);

          // Kill the process
          CloseHandle(pi.hProcess);
   }


     // Execute second application or setup package (i.e. Setup.exe)
     if(CreateProcess(
          NULL,
          filename,
          NULL,
          NULL,
          FALSE,
          0,
          NULL,
          NULL,
          &si,
          &pi
          )){

          // Close both processes
          CloseHandle(pi.hThread);
          CloseHandle(pi.hProcess);
   }

   return 0;
}

//** End Code **//

Thanks in advance!
I've increased the points to just about all the points I have if someone can answer this for me. Thanks again!
ASKER CERTIFIED SOLUTION
Avatar of robpitt
robpitt

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
YES!!!!!!  That's EXACTLY what I needed to get it to work! Thanks alot for your help! Also, thanks to all who commented. I really appreciate it. However, it was robpitt's last comment that worked. Thanks again!
//SetupALL.cpp - win32 gui app
/*
Suppose, c:\Setup\init.dat is text file with 2 lines:
c:\Setup\InstMsi.exe /q
c:\Setup\Setup.exe
*/
#include <windows.h>
#include <stdlib.h>
#include <stdio.h>

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
                                 LPSTR lpCmdLine,int nCmdShow)
{
 char cc[MAX_PATH*2+1];
 STARTUPINFO si;
 FILE *afile=fopen("c:\\Setup\\init.dat","r");
  if(!afile)
  {
   MessageBox(0,"Installation file not found.","SetupALL.exe",MB_OK); return 0;
  }
  while(fgets(cc,sizeof cc,afile))
  { cc[strlen(cc)]=0;// append \0
      memset(&si, 0, sizeof(STARTUPINFO));

      si.cb = sizeof(STARTUPINFO);
      si.lpReserved = NULL;
      si.lpDesktop = "WinSta0\\Default";
      si.lpTitle = NULL;
      PROCESS_INFORMATION pi;
      if(CreateProcess(
         NULL,
           cc,
           NULL,
           NULL,
           FALSE,
           0,
           NULL,
           NULL,
           &si,
           &pi
          ))
      {
       CloseHandle(pi.hThread);
       WaitForSingleObject(pi.hProcess, INFINITE);
       CloseHandle(pi.hProcess);
    }
  }
  fclose(afile);
  return 0;
}