Solved

Sending a command to console (cmd.exe)

Posted on 2010-08-22
15
841 Views
Last Modified: 2012-05-10
Hello,

I am sending a command to an open console (cmd.exe) via
AttachConsole()
...
fprintf(stdout,"dir");

The "dir" appears inside the console, however, when I manually press enter on the console window, the "dir" is not recognized as a command, it basicly executes the last manually entered command...

What should I do?

Tank You
0
Comment
Question by:hlienert
  • 6
  • 6
  • 3
15 Comments
 
LVL 40

Expert Comment

by:evilrix
ID: 33495192
>> What should I do?
You can't just print something to the console and expect it to be recongnised as a command. Execute it using the system function instead.

http://www.cplusplus.com/reference/clibrary/cstdlib/system/
fprintf(stdout,"dir"); // < --print it
system("dir"); // <-- execute it

Open in new window

0
 
LVL 8

Expert Comment

by:Anthony2000
ID: 33495376
I agree with evilrix, but if you really want to do it the way you describe....

I found this article that appears to do something like what you are trying to do. I unfortunately don't have the proper version of Microsoft's tools to try it.

http://www.devx.com/dotnet/Article/7914/0/page/5

Take a look.


0
 

Author Comment

by:hlienert
ID: 33497258
Hi!

I did that:
fprintf(stdout,"dir"); // < --print it
system("dir"); // <-- execute it

but somehow it brings out a different output than when I type the command.
When I type it, it brings the list of files in the current folder.
When I "execute" it, it says the Volume Information of the current drive...

@Anthony2000: I am not so sure what u mean...
0
Gigs: Get Your Project Delivered by an Expert

Select from freelancers specializing in everything from database administration to programming, who have proven themselves as experts in their field. Hire the best, collaborate easily, pay securely and get projects done right.

 
LVL 8

Expert Comment

by:Anthony2000
ID: 33497734
Did you try this for an example to compare:

type this dir c:\ in the console

then do:

system("dir c:\\");

You need the double backslash otherwise the compiler will told that you are trying to include the " in the message and you will get a compiler error.

Do both of these give you the same results?


0
 
LVL 8

Expert Comment

by:Anthony2000
ID: 33497739
I forgot to mention, when the system() function is executed, the current directory may not be the same as the one that the console has. So, for a test, if you tell the dir command what folder you want a listing of, the output should then be the same.

Do you still need to send the command to an already open console window? This is why I included the link above.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33498573
>> but somehow it brings out a different output than when I type the command.

As Anthony2000 eludes, unless you provide a path to dir it will give you a listing of the current working directory (whatever that is). You have two solutions...

-- where path is the directory you wish to list
1. system("dir ");
2. system("cd ; dir");
0
 

Author Comment

by:hlienert
ID: 33498633
Well, I am actually running a dll. If you type a certain keyword on your console + a trigger, this keyword will be replaced by a user-predifined command that is ment to be displayed and executed.
The displaying part works fine via fprintf
The execution gives out garbage. I tried with different commands (dir, cd..) it always brings some funny characters on the console.
For instance, if I use the system("cd..") command it only displays "cd..". If I manually press enter on the console, it brings out next line:
>cd.. ¿¿funden werden.¿¿ist entweder falsch geschrieben oder¿¿konnte nicht ge

It is german, it basicly trying to tell me my command is either misspelled or could not be found. But the words are scrammbled and misplaced.

Using c++ and WIndows 7
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33498652
Some code would be nice -- all of it that is relevant :)
0
 

Author Comment

by:hlienert
ID: 33498749
I solved the problem using the SendKeys class.

But here is the code of fprintf/system approach:

int hConHandle;
long lStdHandle;
CONSOLE_SCREEN_BUFFER_INFO coninfo;
FILE *fp;
FreeConsole();
DWORD pid;
HANDLE hProcessSnap;
HANDLE hProcess;
PROCESSENTRY32 pe32;
hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
if( hProcessSnap != INVALID_HANDLE_VALUE )
{
  if( Process32First( hProcessSnap, &pe32 ) )
  {
        pe32.dwSize = sizeof( PROCESSENTRY32 );
        do
        {
            CString cs_Name=pe32.szExeFile;
            cs_Name.MakeLower();
            if (cs_Name.Right(7)=="cmd.exe")
            {
                  pid=pe32.th32ProcessID;
            }

        } while( Process32Next( hProcessSnap, &pe32 ) );
        CloseHandle( hProcessSnap );
  }
}
BOOL res = AttachConsole(pid);
if(res==0) return;

lStdHandle = (long)GetStdHandle(STD_OUTPUT_HANDLE);
hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
fp = _fdopen( hConHandle, "w" );
*stdout = *fp;
setvbuf( stdout, NULL, _IONBF, 0 );

fprintf(stdout,text_plain);
system("cd..");
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33498810
Where is text_plain ever initialised? That code will just output garbage.

The system command just does a "cd.." what about the dir?

Incidentally, you could (and this would have been a better solution that system) also used the popen function to do this.
http://msdn.microsoft.com/en-us/library/z0kc8e3z(VS.80).aspx
0
 

Author Comment

by:hlienert
ID: 33498829
Yes, sorry, I slightly modified the code.
The "dir" was just an example, just as "cd..." is.
Just see the last 2 lines like this:

CString text_plain="cd...";
fprintf(stdout,text_plain);
system(text_plain);

0
 
LVL 40

Accepted Solution

by:
evilrix earned 500 total points
ID: 33498839
Ok, I am guessing you're building this as a Unicode application, in which case the CString will be wide and not narrow. Try this instead...

char const text_plain[] = "cd ; dir"; // where  is the directory you wish to list
fprintf(stdout,text_plain);
system(text_plain);
0
 

Author Comment

by:hlienert
ID: 33498941
Yes, that seemed to do the trick.

I will still use the SendKeys now, but will accept your answer.
0
 
LVL 40

Expert Comment

by:evilrix
ID: 33499057
>> Yes, that seemed to do the trick.
Great - does it make sense to you why my change worked? If not I am happy to elaborate.
0
 

Author Comment

by:hlienert
ID: 33499984
Yes, it did.
Funny thing is, my project settings are multi-byte.
But still, I guess I was setting the wrong conversion while getting text_plain from my database.
0

Featured Post

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

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

Suggested Solutions

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
This article shows you how to optimize memory allocations in C++ using placement new. Applicable especially to usecases dealing with creation of large number of objects. A brief on problem: Lets take example problem for simplicity: - I have a G…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.

776 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