943,987 Members | Top Members by Rank

Ad:
  • C# Discussion Thread
  • Unsolved
  • Views: 1763
  • C# RSS
May 15th, 2009
0

RedirectStandard Input Help

Expand Post »
hello
(im using c#, visual studio 2008)
I am trying to get Input/Output from a command prompt like process "scrds.exe".
If i try to start the process with standardInput = true, standardOutput = true, or standardError = true. The program cannot start.

after research the "scrds.exe" cant start due to it verifying the lines of output it has already written. I was wondering if there was a way to Redirect the output to my program or file. Save it in main memory or file, and then redirect it back to the process scrds.exe. I have tried lots of methods such as trying to put the process in debuging mode, and only redirecting certain things. Everytime it crashes at startup if Standard output is redirected. Or crashes because the StandardOutput could not be redirected.

Any ideas would be very welcome : )


also i am trying to just write or execute commands in the program from a c# program... If someone knows another way i am willing to do that as well.

Code so far
C# Syntax (Toggle Plain Text)
  1. start.StartInfo.FileName = data;
  2. start.StartInfo.Arguments = argu;
  3. start.StartInfo.UseShellExecute = false;
  4. //start.StartInfo.RedirectStandardInput = true;
  5. //start.StartInfo.RedirectStandardOutput = true;
  6. //start.StartInfo.RedirectStandardError = true;
  7. start.Start();
Similar Threads
Reputation Points: 10
Solved Threads: 1
Light Poster
DevC++4.9.9.2 is offline Offline
39 posts
since Apr 2008
May 15th, 2009
0

Re: RedirectStandard Input Help

Look when I was senior student my graduation project was about code generation I use a method to generate for me keyfile for libraries I used this method which helped me to do some redirection and so on.
C# Syntax (Toggle Plain Text)
  1. public void GenerateKeyFile(string command)
  2. {
  3. ProcessStartInfo PSI = new ProcessStartInfo("your.exe");
  4. PSI.RedirectStandardInput = true;
  5. PSI.RedirectStandardOutput = true;
  6. PSI.RedirectStandardError = true;
  7. PSI.UseShellExecute = false;
  8. Process p = Process.Start(PSI);
  9. System.IO.StreamWriter SW = p.StandardInput;
  10. System.IO.StreamReader SR = p.StandardOutput;
  11. SW.WriteLine(command);
  12. SW.Close();
  13. }
Featured Poster
Reputation Points: 480
Solved Threads: 276
Postaholic
Ramy Mahrous is offline Offline
2,189 posts
since Aug 2006
May 15th, 2009
0

Re: RedirectStandard Input Help

Thanks for your input, but once again RedirectStandardInput, Output, Error all cause this program to crash upon startup... I know how to do that, however is there a way to direct the output to my program then direct it back to the EXE that i started so that program does not crash.

Again the program i am starting is SRCDS.EXE. It tries to verify its output when run and crashes if nothing is written.
Reputation Points: 10
Solved Threads: 1
Light Poster
DevC++4.9.9.2 is offline Offline
39 posts
since Apr 2008
May 15th, 2009
0

Re: RedirectStandard Input Help

I'm some how can't understand you can you please tell me the scenario and how the crash happens?
Featured Poster
Reputation Points: 480
Solved Threads: 276
Postaholic
Ramy Mahrous is offline Offline
2,189 posts
since Aug 2006
May 16th, 2009
0

Re: RedirectStandard Input Help

I am trying to run srcds.exe. This is a command line based server for steam products such as team fortress 2, left 4 dead, counter strike, exc.... I am starting the program using:

C# Syntax (Toggle Plain Text)
  1. Process start = new Process();
  2. start.StartInfo.FileName = data;
  3. start.StartInfo.Arguments = argu;
  4. start.StartInfo.UseShellExecute = false;
  5. start.Start();

If i use these commands:
C# Syntax (Toggle Plain Text)
  1. start.StartInfo.RedirectStandardInput = true;
  2. start.StartInfo.RedirectStandardOutput = true;
  3. start.StartInfo.RedirectStandardError = true;

The Srcds.exe program will crash
The reason it crashes is because the output is not being written to the programs command lines. Aka you see no output to the console like window.
The srcds crashs because it checks to see if it wrote certain lines, since the output has been redirected, obviously it cant see the lines it wrote.

If i try to let the srcds start then redirect standard output using the commands above... it gives me the error standard output was not redirected.

I was wondering if anyone knew a way to redirect the output of the Srcds to my C# program.... then Direct that same output back to the Srcds program.... Or possibly instead of redirecting... just reading the output, if that is possible.

Ultimately i want to be able to give commands to this commandline based program and recieve the output so i can use my C# program as a sort of wrapper.

Thank you for any responses
Reputation Points: 10
Solved Threads: 1
Light Poster
DevC++4.9.9.2 is offline Offline
39 posts
since Apr 2008
May 16th, 2009
0

Re: RedirectStandard Input Help

If you can contact who developed Srcds they can give you the proper solution, I just gave the standardized solution for such demands.
Featured Poster
Reputation Points: 480
Solved Threads: 276
Postaholic
Ramy Mahrous is offline Offline
2,189 posts
since Aug 2006
Jun 2nd, 2009
0

Re: RedirectStandard Input Help

Although you've probably long ago forgotten about this I have not. It is not the output of SRCDS that is causing the error it is the input. SRCDS creates a number of threads and as such creates a very unstandardized member of the "ConsoleWindowClass". It will not run if inputRedirection is true. It will however run splendidly if OutputRedirection is true.

The following is code I wrote that works for getting the output but does not allow input:

C# Syntax (Toggle Plain Text)
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <string.h>
  4. #using <System.dll>
  5. //#include <Windows.h>
  6.  
  7. using namespace System;
  8. using namespace System::Diagnostics;
  9. using namespace System::IO;
  10. int _tmain(int argc, _TCHAR* argv[])
  11. {
  12. SetConsoleTitle(_T("Output Example") );
  13. //HWND WindowHandle;
  14.  
  15. Process^ myProcess = gcnew Process;
  16. //myProcess->EnableRaisingEvents = true;
  17. ProcessStartInfo^ myProcessStartInfo = gcnew ProcessStartInfo("srcds.exe","-console -nohltv -autoupdate -heapsize 524288 -game cstrike");
  18. myProcessStartInfo->UseShellExecute = false;
  19. myProcessStartInfo->RedirectStandardOutput = true;
  20. //myProcessStartInfo->RedirectStandardInput = false;
  21. myProcessStartInfo->RedirectStandardError = false;
  22. myProcess->StartInfo = myProcessStartInfo;
  23. myProcess->Start();
  24.  
  25. //Hide the SRCDS Window
  26. //while((WindowHandle = FindWindow(_T("ConsoleWindowClass"), _T("SOURCE DEDICATED SERVER")))==NULL){};
  27. //ShowWindow(WindowHandle, SW_HIDE); //hide the window
  28.  
  29.  
  30. StreamReader^ myStreamReader = myProcess->StandardOutput;
  31. String^ myString;
  32.  
  33. // Read the standard output of the spawned process.
  34. while(!(myProcess->HasExited)){
  35. if(myString = myStreamReader->ReadLine()){
  36. if (myString->IndexOf("DataTable")<0)
  37. Console::WriteLine( myString );
  38. }
  39. }
  40. myProcess->Close();
  41.  
  42. return 0;
  43. }

I'm working on using PostMessage() to send keystrokes to the srcds.exe window but as yet I cannot. Interestingly enough I can use PostMessage() to send keystrokes to a command prompt without a problem. This is how I discovered that the srcds application is extremely unique.

I have a larger multi-threaded application I'm experimenting with that I hope will allow me to send keystrokes to srcds seeing as how inputredirection crashes it.
Reputation Points: 10
Solved Threads: 0
Newbie Poster
streetfighter is offline Offline
2 posts
since Jun 2009
Jun 3rd, 2009
0

Re: RedirectStandard Input Help

Very good post.

I have create two console application. The below is a program takes argument and user input.

It is a code of sam1.exe
C# Syntax (Toggle Plain Text)
  1. public class Test
  2. {
  3. public static void Main(string[] args)
  4. {
  5. for (int i = 0; i < args.Length; i++)
  6. {
  7. System.Console.WriteLine(args[i]);
  8. }
  9. string name;
  10.  
  11. System.Console.WriteLine("Enter your name : ");
  12. name = Console.ReadLine();
  13.  
  14. System.Console.WriteLine("Welcome : " + name);
  15. }
  16. }

Another program to execute process "sam1.exe"
C# Syntax (Toggle Plain Text)
  1. class TestProcess
  2. {
  3. static void Main()
  4. {
  5. Process p = new Process();
  6. p.StartInfo.UseShellExecute = false ;
  7. p.StartInfo.RedirectStandardInput = true;
  8. p.StartInfo.RedirectStandardOutput = true;
  9.  
  10. p.StartInfo.FileName = @"c:\TC\sam1\bin\Debug\sam1.exe";
  11. p.StartInfo.Arguments = "tt dd ee rr";
  12. p.StartInfo.CreateNoWindow = true;
  13.  
  14. p.Start();
  15.  
  16. System.IO.StreamWriter wr = p.StandardInput;
  17. System.IO.StreamReader rr = p.StandardOutput;
  18.  
  19. wr.Write("Rajeshn" + "\n");
  20. Console.WriteLine(rr.ReadToEnd());
  21. wr.Flush();
  22. }
  23. }
Moderator
Reputation Points: 2136
Solved Threads: 1228
Posting Genius
adatapost is offline Offline
6,527 posts
since Oct 2008
Jun 3rd, 2009
0

Re: RedirectStandard Input Help

Thank you for the new posts... i have since abandoned the idea of redirecting input/output and just went to socket programming. I will post some examples when my program is fully working. Thank you again, this is still very helpful !
Reputation Points: 10
Solved Threads: 1
Light Poster
DevC++4.9.9.2 is offline Offline
39 posts
since Apr 2008
Jun 3rd, 2009
0

Re: RedirectStandard Input Help

DevC++4.9.9.2, I'm glad to see you're still working on this as it has been something that's bugged me for sometime now. I run a CS:S surf server and there is no built-in way to supress the million or so dataTable warnings that pop up every time a surfer exceeds the "speed-limit". There are some other features I wanted like automatic restarting on crashes (which I already coded in a seperate application).

I don't know anything about socket programming so I'm looking forward to your examples.

I got my code working using a C++ version of sendkeys I got here: http://www.codeproject.com/KB/cpp/se...p_Article.aspx
C# has sendkeys built in though it's a little messy and might require a class for certain functions.

Since I couldn't get postMessage() to work with the srcds window I had to use getfocus() every time I sent keys to srcds which is sloppy but it works. I attempted to hide the srcds window by making it small, moving it offscreen and only making it visible on the taskbar for the brief period when keys are sent.

I know this is in C++ but it is really easy to convert to C# and won't require my sloppy type conversions. I have done very little bug testing and the only obvious issue is that when you type in a command it spits out twice (once from you typing it and the other from srcds getting it and sending it back).

I code this in VS2008. I'll post a full project zip just as soon as I read the license for the version of sendkeys I'm using.
C# Syntax (Toggle Plain Text)
  1. #include "stdafx.h"
  2. #include "SendKeys.h"
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <Windows.h>
  6. #include <tchar.h>
  7. #include <time.h>
  8. #using <System.dll>
  9.  
  10. using namespace System;
  11. using namespace System::Diagnostics;
  12. using namespace System::IO;
  13. using namespace System::Threading;
  14.  
  15. ref class MyThread{
  16. public:
  17. static void GetInput(Object ^Name);
  18. };
  19.  
  20. void MyThread::GetInput(Object ^Name){
  21. HWND WindowHandle;
  22. HWND RestoreMain;
  23. String^ inputText;
  24. String^ check;
  25. LPCTSTR inputConv;
  26.  
  27. //http://www.codeproject.com/KB/cpp/sendkeys_cpp_Article.aspx
  28. CSendKeys sk;
  29.  
  30. //Get Window handles
  31. while((WindowHandle = FindWindow(_T("ConsoleWindowClass"), _T("SOURCE DEDICATED SERVER")))==NULL){};
  32. while((RestoreMain = FindWindow(_T("ConsoleWindowClass"), _T("Surf Mod")))==NULL){};
  33.  
  34. //Always wait for commands from user
  35. while(true)
  36. {
  37. inputText=Console::ReadLine();
  38. if ( inputText && inputText->Length > 0 )
  39. {
  40. //This is a sloppy function which converts String^ to LPCTSTR one character at a time
  41. //In C# this loop wouldn't be necessary
  42. for(int i=0; i<inputText->Length;i++){
  43. sk.AppActivate(WindowHandle);
  44. check=inputText->Substring(i,1);
  45. inputConv = (LPCTSTR)System::Runtime::InteropServices::Marshal::StringToCoTaskMemAnsi(check).ToInt32();
  46. sk.SendKeys(inputConv);
  47. }
  48. sk.SendKeys("{ENTER}");
  49.  
  50. //Once keys are sent hide the srcds window
  51. while(SetForegroundWindow(RestoreMain)==0){}
  52. ShowWindow(WindowHandle, SW_HIDE);
  53.  
  54. //Detect user exit and break read loop
  55. if(inputText->IndexOf("exit")>=0){
  56. break;
  57. }
  58. }
  59. }
  60. return;
  61. }
  62.  
  63. int _tmain(int argc, _TCHAR* argv[])
  64. {
  65. SetConsoleTitle(_T("Surf Mod") );
  66. HWND WindowHandle;
  67.  
  68. //Prepare the srcds process
  69. Process^ myProcess = gcnew Process;
  70. ProcessStartInfo^ myProcessStartInfo = gcnew ProcessStartInfo("srcds.exe","-console -game cstrike");
  71. myProcessStartInfo->UseShellExecute = false;
  72. myProcessStartInfo->RedirectStandardOutput = true;
  73. myProcessStartInfo->RedirectStandardError = false;
  74. myProcess->StartInfo = myProcessStartInfo;
  75. myProcess->Start();
  76.  
  77. //Hide the SRCDS Window
  78. while((WindowHandle = FindWindow(NULL, _T("SOURCE DEDICATED SERVER")))==NULL){};
  79. MoveWindow(WindowHandle,-200,-200,120,120,true);
  80. ShowWindow(WindowHandle, SW_HIDE);
  81.  
  82. //Start thread to get commands to send to srcds
  83. Thread ^thr1 = gcnew Thread(gcnew ParameterizedThreadStart(&MyThread::GetInput));
  84. thr1->Start("SOURCE DEDICATED SERVER");
  85.  
  86. //Prepare Stream Reader
  87. StreamReader^ myStreamReader = myProcess->StandardOutput;
  88. String^ myString;
  89.  
  90. // Read the standard output of the spawned process.
  91. while(!(myProcess->HasExited)){
  92. if(myString = myStreamReader->ReadLine()){
  93. if (myString->IndexOf("DataTable")<0)
  94. Console::WriteLine( myString );
  95. }
  96. }
  97. myProcess->Close();
  98. thr1->Abort();
  99. return 0;
  100. }
Reputation Points: 10
Solved Threads: 0
Newbie Poster
streetfighter is offline Offline
2 posts
since Jun 2009

This thread is more than three months old

No one has posted to this discussion for at least three months. Please let old threads die and do not reply to them unless you feel you have something new and valuable to contribute that absolutely must be added to make the discussion complete. Otherwise, please start a new thread in this forum instead.
Message:
Previous Thread in C# Forum Timeline: Generate Meassage once array is full
Next Thread in C# Forum Timeline: how to find my visual studio license key





About Us | Contact Us | Advertise | Acceptable Use Policy
Forum Index | Build Custom RSS Feed


Follow us on Twitter


© 2011 DaniWeb® LLC