C# - Accessing cmd

Associate
Joined
30 Dec 2005
Posts
415
Is this possible?

I understand that I can launch command prompt using Visual C#:
Code:
    System.Diagnostics.Process process1;
    process1= new System.Diagnostics.Process();
    //Do not receive an event when the process exits.
    process1.EnableRaisingEvents = false;
    //The "/C" Tells Windows to Run The Command then Terminate 
    string strCmdLine;
    strCmdLine = "/C ping -r 2 routehiker.org.uk";
    System.Diagnostics.Process.Start("cmd.exe",strCmdLine);
    process1.Close();

What i'd really like to do is run the ping command behind the scenes, and capture the results to a string. The aim is to basically get hold of the IP address of the user.

This is my plan:
ping -r 2 routehiker.org.uk
capture the results
select all the (up to 9) IP addresses in to an array
scan the array for the first IP Address that doesn't begin with the following (they are all reserved for local networks):
10.
172.16.
192.168.
169.254.

Alternatively, is there a better method for finding the true IP of the user running the program?
 
Associate
OP
Joined
30 Dec 2005
Posts
415
Yes, it is the router's IP I am after, as it will pass this to a website so the site knows the IP of how to connect to the application.

The idea is that the website will send data to the application via a socket, but if there's a router involved, would this mean I would have to enable port forwarding on the router? There must be another method....

Unfortunately, both the examples on that website failed to compile. Another idea i've just had is to parse a website such as www.whatismyip.com.
 
Associate
OP
Joined
30 Dec 2005
Posts
415
Not sure why i'm geting errors compiling it then.

Anyway, as a temporary solution, i've got the following:

Code:
        public static string getip()
        {
            string args = "http://whatismyip.org/"; //Website to get IP of user from
            WebClient client = new WebClient();
            client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705;)");
            Stream data = client.OpenRead(args);
            StreamReader reader2 = new StreamReader(data);
            string userwanip = reader2.ReadToEnd();
            data.Close();
            reader2.Close();
            return userwanip;
        }

It's not ideal, but it does the job for now.

Thanks to all for your input!
 
Associate
Joined
27 Oct 2002
Posts
897
The only way to make it work on all connections is for the client to initiate the comminication. If you try and open a socket to the users external ip address (router, proxy, etc.) it's not going to work unless they happen to have port forwarding set up exatly as you program needs it - this is going to be a pain if not impossible for may users.

If however the server listens on a public socket and your client initiates the connection it will work perfectly regardless of his network config.

If you give some more details of how you want your program(s) to work I'll post some examples for you...
 
Associate
OP
Joined
30 Dec 2005
Posts
415
Reezer said:
The only way to make it work on all connections is for the client to initiate the comminication. If you try and open a socket to the users external ip address (router, proxy, etc.) it's not going to work unless they happen to have port forwarding set up exatly as you program needs it - this is going to be a pain if not impossible for may users.

If however the server listens on a public socket and your client initiates the connection it will work perfectly regardless of his network config.

If you give some more details of how you want your program(s) to work I'll post some examples for you...

That's just saved me a lot of hours of fustration! :p

Basically, the user starts the application, and it runs some checks. It checks the user's username and password etc, as well as making sure the website is ready to communicate (using xml). When it has done all these checks, I want it to start listening for the website. At some point, the website will 'notify' the application. This notification contains no useful data, it is just to trigger the application. When the application has been triggered, it will start talking to the website via XML. It will however, need to continue listening for other notifications after this first has occured.

So basically, whenever it's on the form 'maininterface.cs', it will be constantly listening for the website to say hello. The website knows the IP address of the user btw...

However, I dont want it so it stops doing everything whilst it listens...it needs to run in the background, so I can be calling on other events etc whilst it is running.

Here is the current PHP code whilst 'notifies' the application:
Code:
$fp = fsockopen("IP ADDRESS", 3519, $errno, $errstr);
if (!$fp) {
   echo "ERROR: $errno - $errstr<br />\n";
} else {
   fwrite($fp, "\n");
   echo fread($fp, 26);
   fclose($fp);
}

My current C# code which pauses everything :( whilst it is listening:

Code:
Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        try
        {
            TcpListener tcpl = new TcpListener(IPAddress.Any, 3519); // listen on port 13
            tcpl.Start();
            MessageBox.Show("Waiting for clients to connect");
            while (true)
            {
                // Accept will block until someone connects
                Socket s = tcpl.AcceptSocket();
                s.Close();
                MessageBox.Show("Sent {0}");
            }
        }
        catch (SocketException socketError)
        {
            if (socketError.ErrorCode == 10048)
            {
                MessageBox.Show("Connection to this port failed. There is another service listening on this port.");
            }
        }

Hope that makes sense!
 
Last edited:
Associate
Joined
27 Oct 2002
Posts
897
This article may be of use to you http://www.zend.com/pecl/tutorials/sockets.php

The second example is pretty much exactly what I think you need to do. I think your best bet would be to have it accept connections but not do anything with them in the case of a client and then when you want to send you alert your other php script connects to the one running as a server, sends some special input (and has it's IP checked to prove it's an internal message) which then triggers a message to all the other clients.

The client side all you'd have to do is open a socket to your server and set of an asynchronous read. It could idle for as long as necessary consuming trivial resources. Using an async read would also handle the multi-threaded nature for you automatically.

Provided you can get your php server to work for you you can be fairly confident it will work for anyone regardless of their network config (provided they can access your website they'll be fine).

On a side note you may as well use UDP packets rather than TCP because your messages are short and atomic - it'll save a bit of bandwidth and save you a bit of hasstle making sure you are receiving single whole TCP messages.

Good luck, I'd try it myself because it sounds quite interesting but I've just cancelled my hosting and can't be bothered to set up PHP :p
 
Associate
OP
Joined
30 Dec 2005
Posts
415
Reezer said:
This article may be of use to you http://www.zend.com/pecl/tutorials/sockets.php

The second example is pretty much exactly what I think you need to do. I think your best bet would be to have it accept connections but not do anything with them in the case of a client and then when you want to send you alert your other php script connects to the one running as a server, sends some special input (and has it's IP checked to prove it's an internal message) which then triggers a message to all the other clients.

The client side all you'd have to do is open a socket to your server and set of an asynchronous read. It could idle for as long as necessary consuming trivial resources. Using an async read would also handle the multi-threaded nature for you automatically.

Provided you can get your php server to work for you you can be fairly confident it will work for anyone regardless of their network config (provided they can access your website they'll be fine).

On a side note you may as well use UDP packets rather than TCP because your messages are short and atomic - it'll save a bit of bandwidth and save you a bit of hasstle making sure you are receiving single whole TCP messages.

Good luck, I'd try it myself because it sounds quite interesting but I've just cancelled my hosting and can't be bothered to set up PHP :p


The method of procedure you've suggested sounds spot on. I've just got to work out how to do a asynchronous read then. Eeek! I'll have a look round and see what I can find.

Thanks also for the tip on UDP over TCP. I should have thought of that myself with 2 years of cisco behind me :confused:
 
Associate
Joined
27 Oct 2002
Posts
897
toastyman said:
The method of procedure you've suggested sounds spot on. I've just got to work out how to do a asynchronous read then. Eeek! I'll have a look round and see what I can find.

Thanks also for the tip on UDP over TCP. I should have thought of that myself with 2 years of cisco behind me :confused:

Async is easy peasy, it sounds complex when people/books describe it the actual implemenation is very straighforward.

I posted a basic example in this thread which should be enough to get you started: http://forums.overclockers.co.uk/showpost.php?p=7059651&postcount=4

[EDIT] The example is for a TCP socket so it might not be quite right for UDP but it's probably something very similar [/EDIT]
 
Last edited:
Associate
OP
Joined
30 Dec 2005
Posts
415
I know this is full of errors and not at all likely to work...its really just a collection of code from the thread you suggested, put into an order.

Code:
private byte[] GetTcpData() {
    byte[] UdpData;
	try
	{
		UdpClient client = new UdpClient();
        client.Connect(IPAddress.Any, 3519); //Connect the socket
        _connection.Socket.BeginReceive(_connection.Buffer, 0, _connection.Buffer.Length, SocketFlags.None, new AsyncCallback(client), _connection);

	private void ReceiveCallback(IAsyncResult result)
        {
            lock (_connection)
            {
                try
                {
                    _connection.BytesRead += _connection.Socket.EndReceive(result);
	        }
           }
      }
}

The problem is i've only being doing C# for a week, and am still getting used to the event driven environment and the syntax.
I understand I need to create a global object called _connection as well, but have no idea how to do it.
 
Last edited:
Back
Top Bottom