1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

C# - Accessing cmd

Discussion in 'HTML, Graphics & Programming' started by toastyman, 11 Jul 2006.

  1. toastyman

    Gangster

    Joined: 30 Dec 2005

    Posts: 421

    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?
     
  2. ByteJuggler

    Hitman

    Joined: 5 Jun 2005

    Posts: 988

    Location: Leicestershire

    Are you trying to find the user's public IP (if it exists?) You do realise this might not be "their" IP, but might be their router's public IP etc?
     
  3. growse

    Soldato

    Joined: 18 Oct 2002

    Posts: 7,139

    Location: Ironing

  4. toastyman

    Gangster

    Joined: 30 Dec 2005

    Posts: 421

    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.
     
  5. Lagz

    Wise Guy

    Joined: 25 Jul 2003

    Posts: 1,980

    The example at http://www.codeproject.com/dotnet/CSharpPing.asp compiles and runs perfectly for me. Its a much nicer way of doing it than parsing a website also.
     
  6. toastyman

    Gangster

    Joined: 30 Dec 2005

    Posts: 421

    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!
     
  7. Reezer

    Hitman

    Joined: 27 Oct 2002

    Posts: 895

    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...
     
  8. toastyman

    Gangster

    Joined: 30 Dec 2005

    Posts: 421

    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: 12 Jul 2006
  9. Reezer

    Hitman

    Joined: 27 Oct 2002

    Posts: 895

    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
     
  10. toastyman

    Gangster

    Joined: 30 Dec 2005

    Posts: 421


    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:
     
  11. Reezer

    Hitman

    Joined: 27 Oct 2002

    Posts: 895

    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: 12 Jul 2006
  12. toastyman

    Gangster

    Joined: 30 Dec 2005

    Posts: 421

    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: 12 Jul 2006