1

I try to change the hostname via kernel32.dll import and the function SetComputerName. SetComputerName function

Mainclass:

namespace Castell
{
  class Program
  {
      private static string hostname { get; set; }
      setHostname();
      private static void setHostname()
      {
         hostname = "TEST123456789";
         int errorcode = ImportDLL.SetComputerName(hostname);
         Console.WriteLine(Marshal.GetLastWin32Error());
      }
  }
}

Import Class:

namespace Castell
{
    class ImportDLL
    {
        [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        public static extern int SetComputerName(string hostname);
    }
}

Result of the Marshal.GetLastWin32Error() is "6". So that means: ERROR_INVALID_HANDLE 6 (0x6) The handle is invalid.

Dont know whats wrong with the handle.

mnlfischer
  • 397
  • 4
  • 12
  • 26
  • The ms description is "The handle is invalid." – mnlfischer Nov 18 '13 at 13:23
  • [`SetComputerName()`](http://msdn.microsoft.com/en-us/library/windows/desktop/ms724930(v=vs.85).aspx): _"If the function succeeds, the return value is a nonzero value"_. The result of `GetLastWin32Error()` doesn't have to be related to your `SetComputerName()` call. What is being returned from the function call? – CodeCaster Nov 18 '13 at 13:32
  • When I set SetLastError = true, I thought the latest error displayed in win32 error? I read some questions here, that the GetLastError function is not the best to do. – mnlfischer Nov 18 '13 at 13:39
  • Again: what is being returned from the `SetComputerName()` call? – CodeCaster Nov 18 '13 at 13:44
  • it works now, the problem was the function definition. Now I changed the NetBios Name but I also want rename the hostname. Is the only way to change the registry entries tcp/ip? – mnlfischer Nov 18 '13 at 14:53

1 Answers1

1

You are just doing it wrong. The return type of SetComputerName() is bool, not int. It returns false when the function failed. The hard rule in the winapi is that you should only ever obtain the error code when the function failed. Or to put it another way, Windows doesn't explicitly set the error code back to 0 when the function is successful. Only then use Marshal.GetLastWin32Error() to retrieve the error code. Otherwise done automatically by the Win32Exception class constructor. Which makes this code work:

  public static void SetHostname(string hostname)
  {
     if (!SetComputerName(hostname)) {
         throw new System.ComponentModel.Win32Exception();
     }
  }

  [DllImport("Kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
  private static extern int SetComputerName(string hostname);
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536