Link to home
Start Free TrialLog in
Avatar of dwoolley3
dwoolley3Flag for United States of America

asked on

How can I get remote Machine Name where Console Application resides when it executes?

I am working on an intranet and have 3 different machines: Development, Test, Production. My Development machine is my laptop; the Test machine is a remote server; the Production machine is a different remote server. I built a simple Console Application using C#, and I would like for it to show me the Machine's name (or domain name) where the executable is actually residing when it is run. It may be running from my laptop machine, but I want it to show me the name of the machine where it resides.

Currently I have tried both of the following, but they both give me my laptop's machine name:

using System.Net;             //For Dns

            string machineName = Environment.MachineName.ToString();
            string strHostName = Dns.GetHostName();

What can I do or use to get the machine name (or host name) of the machine where the Console Application resides when it executes?
Avatar of Nasir Razzaq
Nasir Razzaq
Flag of United Kingdom of Great Britain and Northern Ireland image

This gives you dev machine name when you run it on server? Strange. Are the names of two machines different? You are not storing the name anywhere are you?
Avatar of dwoolley3

ASKER

Both commands give me the Dev machine name when I use my laptop to navigate to the Test server (via Windows Mappings) and execute the Console Application executable that resides on the Test server.  From one perspective, I suppose it is executing on my laptop. Is there a way to have it show that the executable actually resides on the Test machine?
SOLUTION
Avatar of Ark
Ark
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Nice thought Ark, yet it seems that Application.StartUp is only available for Windows Applications (as opposed to Console Applications). I tried to add the namespace System.Windows.Forms, but VS 2008 says that the namespace Windows does not exist in the namespace System.

Perhaps the answer to my question is that I can't get the info that I want when I run the executable remotely from my laptop, since it seems to copy the executable into machine memory and executes it from there (as mentioned by Ark).
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thanks, though the System.AppDomain.CurrentDomain.BaseDirectory is not what I need.

I am able to accomplish my goal of determining whether the machine is production or not by using either

string machineName = Environment.MachineName.ToString();
string strHostName = Dns.GetHostName();

The only catch is that it will show the machine Name that is running the executable and not the machine that is storing the executable. In my case, I can live with this because the production run will be scheduled through SQL Server's Job scheduler that runs on the same production machine. Thus, in production mode, the job will run on the production machine and the program will detect the correct machineName.
That was a known part I thought.
I tried to add the namespace System.Windows.Forms
Winform app add reference to windows.forms automatically. To use this namespace in console app, add reference either from .Net components or directly to system.windows.forms.dll
Thank you both for your suggestions, both of which I tested. I added the reference to system.windows.forms.dll -- thank you for that technique.

            string startupPath = Application.StartupPath;
            string baseDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
            Console.WriteLine("StarupPath = " + startupPath);
            Console.WriteLine("BaseDirectory = " + baseDirectory);

With the above code, my executable will produce a complete path only on Development machine:
on Dev machine: C:\Inetpub\wwwroot\etc.
on Test machine: O:\
on Prod machine: A:\

The Test and Prod machine return 3 characters indicating the drive that I have assigned the mapping to from my local machine. If my partner runs these executables from his machine, the drives will be different based on which drives he mapped to the test machine and production machine. We are not logging onto these machines remotely but we are mapping to them through Windows Explorer. Although I would like to have the program differentiate these three environments and thus access things specific to those three environments (like a different database), I am willing to settle for the program differentiating between this kind of a run and the real production run that gets executed on the production machine via SQL Server Job Scheduler.
  <DllImport("mpr.dll")> _
    Shared Function WNetGetConnection(<MarshalAs(UnmanagedType.LPTStr)> _
                      ByVal localName As String, ByVal remoteName As System.Text.StringBuilder, _
                      ByRef length As Integer) As Integer
    End Function
    Private Function pathToUnc(ByVal path As String)
        Dim length As Integer = 255
        Dim UNC As New System.Text.StringBuilder(length)
        WNetGetConnection(path.Substring(0, 2), UNC, length)
        Return UNC.ToString
    End Function
    
    Private Sub Test()
        Dim dr As String = "O:\"
        MsgBox("The UNC-Path of drive " & dr & " is: " & strToUnc(dr))
    End Sub

Open in new window

Oops, sorry, seems u'r using CSharp:
DllImport("mpr.dll", CharSet = CharSet.Unicode, SetLastError = true)]
        public static extern int WNetGetConnection(
            [MarshalAs(UnmanagedType.LPTStr)] string localName,
            [MarshalAs(UnmanagedType.LPTStr)] StringBuilder remoteName,
            ref int length);

        public static string GetUNCPath(string originalPath)
        {
            StringBuilder sb = new StringBuilder(512);
            int size = sb.Capacity;
            // look for the {LETTER}: combination ...
            if (originalPath.Length > 2 && originalPath[1] == ':')
            {
                // don't use char.IsLetter here - as that can be misleading
                // the only valid drive letters are a-z && A-Z.
                char c = originalPath[0];
                if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
                {
                    int error = WNetGetConnection(originalPath.Substring(0, 2),
                        sb, ref size);
                    if (error == 0)
                    {
                        DirectoryInfo dir = new DirectoryInfo(originalPath);
                        string path = Path.GetFullPath(originalPath)
                            .Substring(Path.GetPathRoot(originalPath).Length);
                        return Path.Combine(sb.ToString().TrimEnd(), path);
                    }
                }
            }

Open in new window