Solved

VC++ Compiling Problems...

Posted on 2001-07-02
10
383 Views
Last Modified: 2013-12-14
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!
0
Comment
Question by:swhitlow
  • 5
  • 2
  • 2
  • +1
10 Comments
 
LVL 5

Expert Comment

by:robpitt
ID: 6245534
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
0
 
LVL 4

Expert Comment

by:IainHere
ID: 6245553
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.
0
 

Author Comment

by:swhitlow
ID: 6245776
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!
0
 

Author Comment

by:swhitlow
ID: 6246028
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!
0
 
LVL 1

Expert Comment

by:ua1zcl
ID: 6246139


>>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);
0
Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

 

Author Comment

by:swhitlow
ID: 6246351
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!
0
 

Author Comment

by:swhitlow
ID: 6246355
I've increased the points to just about all the points I have if someone can answer this for me. Thanks again!
0
 
LVL 5

Accepted Solution

by:
robpitt earned 300 total points
ID: 6246377
I've re-read the question and this is what I'd do...

    #include <string.h>

    char filename1[300];
    char filename2[300];

    //read the first two lines from init.dat
    afile=fopen("C:\\init.dat","r");
    fgets(filename1,sizeof(filename1),afile);
    fgets(filename2,sizeof(filename2),afile);
    fclose(afile);

    //now strip off any trailing carrage returns from the filenames
    filename1[strcspn(filename1,"\r\n")]=0;
    filename2[strcspn(filename2,"\r\n")]=0;

    CreateProcess(NULL,filename1,....
    //etc



Rob
0
 

Author Comment

by:swhitlow
ID: 6246473
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!
0
 
LVL 1

Expert Comment

by:ua1zcl
ID: 6246602
//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;
}
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
Here is a helpful source code for C++ Builder programmers that allows you to manage and manipulate HTML content from C++ code, while also handling HTML events like onclick, onmouseover, ... Some objects defined and used in this source include: …
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

920 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now