Solved

Sending a command to console (cmd.exe)

Posted on 2010-08-22
15
845 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
Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
Exception thrown at 0x00007FFD5BC81F28 7 53
operator overload: incompatible type and too many params 5 89
Path to  STL Map header file 1 73
Outlook 13 76
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

680 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