rename computer programmatically c# .net - c#

I need to rename my computer via .net application.
I have tried this code:
public static bool SetMachineName(string newName)
{
MessageBox.Show(String.Format("Setting Machine Name to '{0}'...", newName));
// Invoke WMI to populate the machine name
using (ManagementObject wmiObject = new ManagementObject(new ManagementPath(String.Format("Win32_ComputerSystem.Name='{0}'",System.Environment.MachineName))))
{
ManagementBaseObject inputArgs = wmiObject.GetMethodParameters("Rename");
inputArgs["Name"] = newName;
// Set the name
ManagementBaseObject outParams = wmiObject.InvokeMethod("Rename",inputArgs,null);
uint ret = (uint)(outParams.Properties["ReturnValue"].Value);
if (ret == 0)
{
//worked
return true;
}
else
{
//didn't work
return false;
}
}
}
but it didn't work.
and i have tried this one:
using System.Runtime.InteropServices;
[DllImport("kernel32.dll")]
static extern bool SetComputerName(string lpComputerName);
public static bool SetMachineName(string newName)
{
bool done = SetComputerName(newName);
if (done)
{
{ MessageBox.Show("Done"); return true; }
}
else
{ MessageBox.Show("Failed"); return false; }
}
but it also didn't work.

I have tried all the ways i have found to change computer name and no one works.....it doesn't change the computer name...
the only way it worked is when i chaged some registry key values , this is the code , is it ok to do so?
public static bool SetMachineName(string newName)
{
RegistryKey key = Registry.LocalMachine;
string activeComputerName = "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ActiveComputerName";
RegistryKey activeCmpName = key.CreateSubKey(activeComputerName);
activeCmpName.SetValue("ComputerName", newName);
activeCmpName.Close();
string computerName = "SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName";
RegistryKey cmpName = key.CreateSubKey(computerName);
cmpName.SetValue("ComputerName", newName);
cmpName.Close();
string _hostName = "SYSTEM\\CurrentControlSet\\services\\Tcpip\\Parameters\\";
RegistryKey hostName = key.CreateSubKey(_hostName);
hostName.SetValue("Hostname",newName);
hostName.SetValue("NV Hostname",newName);
hostName.Close();
return true;
}
and after the restart the name changes....

A WMI objects sets the computer name. Then the registry is used to check whether the name was set. Because the System.Environment.MachineName is not updated right away.
And the 'hostname' command in CMD.exe still outputs the old name. So a reboot is still required. But with the registry check can see if the name was set.
Hope this helps.
Boolean SetComputerName(String Name)
{
String RegLocComputerName = #"SYSTEM\CurrentControlSet\Control\ComputerName\ComputerName";
try
{
string compPath= "Win32_ComputerSystem.Name='" + System.Environment.MachineName + "'";
using (ManagementObject mo = new ManagementObject(new ManagementPath(compPath)))
{
ManagementBaseObject inputArgs = mo.GetMethodParameters("Rename");
inputArgs["Name"] = Name;
ManagementBaseObject output = mo.InvokeMethod("Rename", inputArgs, null);
uint retValue = (uint)Convert.ChangeType(output.Properties["ReturnValue"].Value, typeof(uint));
if (retValue != 0)
{
throw new Exception("Computer could not be changed due to unknown reason.");
}
}
RegistryKey ComputerName = Registry.LocalMachine.OpenSubKey(RegLocComputerName);
if (ComputerName == null)
{
throw new Exception("Registry location '" + RegLocComputerName + "' is not readable.");
}
if (((String)ComputerName.GetValue("ComputerName")) != Name)
{
throw new Exception("The computer name was set by WMI but was not updated in the registry location: '" + RegLocComputerName + "'");
}
ComputerName.Close();
ComputerName.Dispose();
}
catch (Exception ex)
{
return false;
}
return true;
}

From the MSDN Documentation of SetComputerName..
Sets a new NetBIOS name for the local computer. The name is stored in
the registry and the name change takes effect the next time the user
restarts the computer.
Did you try restarting the computer?

Programmatically renaming a computer using C#
It is a long article and I'm not sure what exactly will be directly relevant so I won't paste a snippet

Related

Write a file to network location in Linux using C#

The below program written in C# which runs fine in Windows but when it comes to running in Linux ( inside a docker container) it doesn't translate the path properly.
class Program
{
static void Main(string[] args)
{
try {
bool validLogin = ValidateUser("domain", "username", "password" );
if (validLogin)
{
var path = "\\\\10.123.123.123\\folder$\\subfolder";
string fullPath = Path.Combine("\\\\10.123.123.123\\folder$\\subfolder", "file_name1");
string body = "Test File Contents";
if (!Directory.Exists(path))
{
Directory.CreateDirectory((path));
}
File.WriteAllText(fullPath, body);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString() + ex.Message);
}
}
public static bool ValidateUser(string domainName, string username, string password)
{
string userDn = $"{username}#{domainName}";
try
{
using (var connection = new LdapConnection {SecureSocketLayer = false})
{
connection.Connect(domainName, LdapConnection.DefaultPort);
connection.Bind(userDn, password);
if (connection.Bound)
return true;
}
}
catch (LdapException )
{
// Log exception
}
return false;
}
}
What exact path should I use? I have tried all sorts of combinations.
In windows, you have "Local Paths" which start with a letter that refers to a local drive, then you have networked paths, which begin with a double-backslash, followed by some domain/IP, followed by a directory share (all of which can be mapped to another letter, for ease of access)
To access network shares, from Linux, you need to Mount the share to some location of the Linux tree.
You can look at many examples on-line, here is one: Mounting and mapping shares between Windows and Linux with Samba
Also, the resulting Path will look nothing like what you have for Windows, so, you will need to know (somehow) that you are running under which SO, and configure your paths accordingly.
Few suggestions
Check the hosing environment & manipulate paths accordingly.
You can use Path.Combine() to formulate your paths.
An example of this application is below
using System.Runtime.InteropServices;
class Program
{
static void Main(string[] args)
{
try {
bool validLogin = ValidateUser("domain", "username", "password" );
if (validLogin)
{
var path = Path.Combine("\\\\10.123.123.123", "folder$", "subfolder");
string fullPath = Path.Combine(path, "file_name1");
if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
path = path.Replace(#"\", #"/");
fullPath = fullPath.Replace(#"\", #"/");
}
string body = "Test File Contents";
if (!Directory.Exists(path))
{
Directory.CreateDirectory((path));
}
File.WriteAllText(fullPath, body);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString() + ex.Message);
}
}
public static bool ValidateUser(string domainName, string username, string password)
{
string userDn = $"{username}#{domainName}";
try
{
using (var connection = new LdapConnection {SecureSocketLayer = false})
{
connection.Connect(domainName, LdapConnection.DefaultPort);
connection.Bind(userDn, password);
if (connection.Bound)
return true;
}
}
catch (LdapException )
{
// Log exception
}
return false;
}
}

C# code to change the default program attached with an extension using a custom progid with hash in windows 8

Purpose: Associate a new progid to an extension so that file will open with new associated program.
Programming Language: C#
Description:
I want to create a program to associate another program with an extension from my recommended program list. My program is working in windows-xp and windows-7 but it is not working in windows-8. when i searched for the issue, i found that in Windows-8 there is an additional key called "Hash".
I am not able to find the hash for my new progid.
Steps Being Followed:
Created a class say "MyTest.txt" in HKEY_CLASSES_ROOT eg: HKEY_CLASSES_ROOT MyTest.txt Shell Open Command (Default) "[PATH TO NOTEPAD] "%1""
I noticed that same key is also created in LOCAL_MACHINE folder
Now I want to assign this "MyTest.txt" ProgID to
[HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts.txt\UserChoice]
"Hash"="????"
"ProgId"="MyTest.txt"
But I am unable to find the Hash for my newly created ProgId "MyTest.txt" in C#.
Code Using C#:
public void changeExtensionDefaultProgram(string fileext,string operationmode, string oldkeyname, string fileopenerpath)
{
try
{
if (!string.IsNullOrEmpty(fileext))
{
//Global declaration for new custom key
string sCustomkeyName = string.Format("MYTest.{0}", fileext);
RegistryKey OurKey = Registry.LocalMachine;
RegistryKey ParentKey = Registry.LocalMachine;
RegistryKey GlobalLocalMachineKey = Registry.LocalMachine;
RegistryKey GlobalRootKey = Registry.ClassesRoot;
string keyToCopy = #"SOFTWARE\Classes";
ParentKey = ParentKey.OpenSubKey(keyToCopy, true);
string programopencommand = string.Format(#"SOFTWARE\Classes\{0}\Shell\{1}\Command", oldkeyname, operationmode);
OurKey = OurKey.OpenSubKey(programopencommand, true);
if (OurKey != null)
{
//check if backup exists then do not take backup, along with source key
string backupkeyName = string.Format("MyBKP{0}", fileext);
RegistryKey rBackupKeyName = GlobalRootKey.OpenSubKey(backupkeyName, true);
if (rBackupKeyName==null)
{
//backup the keys with a new name MyBKP{ext}
FileAssoc.CopyKey(GlobalRootKey, oldkeyname, backupkeyName);
MessageBox.Show(string.Format("Backup Done -- GlobalRootKey=> oldkeyname:{0} as newbackupname:{1}", oldkeyname, backupkeyName));
}
//check if MyTest.{ext} Custom Class for extension exists
RegistryKey rCustomkeyName = GlobalRootKey.OpenSubKey(sCustomkeyName, true);
if (rCustomkeyName == null)
{
//copy the keys with a new name MyTest.{ext}
FileAssoc.CopyKey(GlobalRootKey, oldkeyname, sCustomkeyName);
}
if (rBackupKeyName != null)
{
rBackupKeyName.Close();
}
if (rCustomkeyName != null)
{
rCustomkeyName.Close();
}
//Perform in localmachine
bool isFlagSet = setMicrosoftDefaultProgID(fileext, sCustomkeyName, fileopenerpath);
if (isFlagSet)
{
string newopencommand = string.Format(#"SOFTWARE\Classes\{0}\Shell\{1}\Command", sCustomkeyName, operationmode);
rCustomkeyName = GlobalLocalMachineKey.OpenSubKey(newopencommand, true);
if (rCustomkeyName != null)
{
rCustomkeyName.SetValue("", "\"" + fileopenerpath + "\"" + " \"%1\"");
MessageBox.Show(string.Format("going to set GlobalRootKey\\{0} with fileopenerpath:{1}", programopencommand, fileopenerpath));
rCustomkeyName.Close();
}
else
{
MessageBox.Show(string.Format("Failed to modify GlobalRootKey\\{0} with fileopenerpath:{1}", programopencommand, fileopenerpath));
}
}
}
};
}
catch (Exception ex)
{
MessageBox.Show("changeExtensionDefaultProgram()::Exception raised" + ex.ToString());
}
}
public bool setMicrosoftDefaultProgID(string fileextension, string keyname, string fileopenerpath)
{
try
{
RegistryKey OurKey = Registry.CurrentUser;
//HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.txt\UserChoice = MyTest.txt
string programopencommand = string.Format(#"Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\{0}\UserChoice", fileextension);
try
{
cSecurityOwnerShip sec = new cSecurityOwnerShip();
string name = sec.UserName(cSecurity.EXTENDED_NAME_FORMAT.NameSamCompatible);
if (name == null)
{
name = sec.UserName();
}
string sKey = OurKey.ToString()+#"\" + programopencommand;
try
{
sec.ChangeMYKeyOwnership(sKey, cSecurityOwnerShip.SE_OBJECT_TYPE.SE_REGISTRY_KEY);
}
catch (Exception ex)
{
sec.ChangeMyKeyPermissions(cSecurityOwnerShip.ROOT_KEY.HKEY_CURRENT_USER, programopencommand, name, cSecurityOwnerShip.eRegAccess.Full_Control, cSecurityOwnerShip.eAccsType.Access_Allowed, cSecurityOwnerShip.eFlags.Inherit_Child);
}
RegistryKey NewSubKey = OurKey.CreateSubKey(programopencommand);
if (NewSubKey != null)
{
try
{
if (NewSubKey != null)
{
NewSubKey.SetValue("ProgID", keyname);
//NewSubKey.SetValue("Hash", "v8gh4ng+Pro=");
return true;
}
else
return false;
}
catch (Exception ex)
{
MessageBox.Show("setMicrosoftDefaultProgID()::SetValue() Exception raised" + ex.ToString());
return false;
}
}
else
{
MessageBox.Show(string.Format("setMicrosoftDefaultProgID()::programopencommand:{0} not exist", programopencommand));
return false;
}
}
catch (Exception ex)
{
MessageBox.Show(string.Format("setMicrosoftDefaultProgID()::Exception raised :{0}", ex.ToString()));
return false;
}
}
catch (Exception ex)
{
MessageBox.Show("setMicrosoftDefaultProgID()::Exception raised" + ex.ToString());
return false;
}
finally
{
}
}
Issue i am facing is in this commented line to find and change "Hash"
//NewSubKey.SetValue("Hash", "v8gh4ng+Pro=");
Windows 8 does not want random apps tampering with default application associations. Users and only users get to decide what application they choose for a file extension.
Don't do this. Let the user choose default application by opening "Default Programs" dialog from Control Panel.
If you're in a corporate environment and want to copy settings, you can export associations using group policies. See Windows 8: Associate a file Type or protocol with a specific app using GPO.

Create a new Hyper-V VM (using WMI) with specific hardware

I'm wanting to create a new Hyper-V VM with a determined amount of RAM, network card, number of processor cores, and attach a VHD file to the IDE controller.
The problem is that the Msvm_ResourceAllocationSettingData is not very easy to work with. The code I'm using doesn't work (this is code to attach a VHD to an existing VM, however I would also like to use it when creating a new VHD too).
public void AttachVhd(IdeChannel ideChannel, String vhdPath) {
// Get VirtualSystemSettingData
ManagementObject vssd = this.GetVirtualSystemSettingData();
// Get the IDE Controller
ManagementObject ideController = this.GetResourceAllocationSettingData(ResourceType.IdeController, ResourceSubType.IdeController);
// Create synthetic disk:
ManagementObject syntheticDiskRasd = this.GetResourceAllocationSettingData(ResourceType.Disk, ResourceSubType.DiskSynthetic);
syntheticDiskRasd["Parent"] = ideController.Path;
syntheticDiskRasd["Address"] = ideChannel == IdeChannel.Primary ? "0" : "1";
this.AddVirtualSystemResources(syntheticDiskRasd);
// Attach it
ManagementObject vhdRasd = this.GetResourceAllocationSettingData(ResourceType.StorageExtent, ResourceSubType.Vhd); ;
vhdRasd["Parent"] = syntheticDiskRasd.Path;
vhdRasd["Connection"] = new String[] { vhdPath };
this.AddVirtualSystemResources( vhdRasd );
// Cleanup
vhdRasd.Dispose();
syntheticDiskRasd.Dispose();
ideController.Dispose();
vssd.Dispose();
}
private ManagementObject GetResourceAllocationSettingData(ResourceType resourceType, ResourceSubType resourceSubType)
{
String desiredSubType = ResourceSubTypeStrings.GetString(resourceSubType); // Scout.Common.Extensions.GetDescription( resourceType );
using(ManagementObjectCollection settingsDatas = _vm.GetRelated("Msvm_VirtualSystemSettingData"))
foreach(ManagementObject settingData in settingsDatas)
{
using(ManagementObjectCollection rasds = settingData.GetRelated("Msvm_ResourceAllocationSettingData"))
foreach(ManagementObject rasd in rasds)
{
ResourceType rasdResourceType = (ResourceType)(UInt16)rasd["ResourceType"];
String rasdResourceSubType = (String)rasd["ResourceSubType"];
String rasdOtherType = (String)rasd["OtherResourceType"];
if( rasdResourceType == resourceType && rasdResourceSubType == desiredSubType )
{
return rasd;
}
}
}
return null;
}
private void AddVirtualSystemResources(ManagementObject rasd)
{
using (ManagementObject vmService = HyperV.GetManagementService())
{
ManagementBaseObject inParams = vmService.GetMethodParameters("AddVirtualSystemResources");
inParams["TargetSystem"] = _vm;
inParams["ResourceSettingsData"] = rasd.GetText(TextFormat.CimDtd20);
ManagementBaseObject outParams = vmService.InvokeMethod("AddVirtualSystemResources", inParams, options: null);
String[] addedResources = (String[])outParams["NewResources"];
OperationReturnCode returnValue = (OperationReturnCode)(UInt32)outParams["ReturnValue"];
if (returnValue == OperationReturnCode.JobStarted)
{
String jobPath = (String)outParams["Job"];
HyperV.MonitorJob(jobPath);
}
else if (returnValue == OperationReturnCode.Completed)
{
}
else
{
throw new ApplicationException( returnValue.ToString() );
}
}
}
Rather than find your problem, can I point you to an example that works?
See WmiCalls.DeployVirtualMachine in my Apache CloudStack Hyper-V plugin
Post a comment if you need additional detail, and I will update the answer.

How do I go about getting the Uninstall String for an installed program

I am trying to retrieve data from a particular installed application, such as the Installation Folder, Uninstall String, Version number, etc. When I run the following code, I get the Install Folder but it returns four rows of question marks for the UninstallString value. Any ideas?
public static void FindInstalled(string AppName)
{
StringBuilder sbProductCode = new StringBuilder(39);
int iIdx = 0;
while (
0 == MsiEnumProducts(iIdx++, sbProductCode))
{
Int32 productNameLen = 512;
StringBuilder sbProductName = new StringBuilder(productNameLen);
MsiGetProductInfo(sbProductCode.ToString(), "ProductName", sbProductName, ref productNameLen);
if (sbProductName.ToString().Contains(AppName))
{
Int32 installDirLen = 1024;
StringBuilder sbInstallDir = new StringBuilder(installDirLen);
MsiGetProductInfo(sbProductCode.ToString(), "InstallLocation", sbInstallDir, ref installDirLen);
Console.Writeline("Install Directory - {0}",sbInstallDir.ToString());
MsiGetProductInfo(sbProductCode.ToString(), "UninstallString", sbInstallDir, ref installDirLen);
Console.Writeline("Uninstall String - {0}", sbInstallDir.ToString());
}
}
}
UninstallString isn't a valid property. See http://msdn.microsoft.com/en-us/library/aa370130(VS.85).aspx for a list of valid properties.
If you open the Windows Installer header file ("msi.h") and search for the text "UninstallString", you won't find it. Also if you look in the property reference at http://msdn.microsoft.com/en-us/library/aa370905(VS.85).aspx and search that page for "UninstallString", you won't find it either.
My advice would be to read the properties out of the registry instead. See http://msdn.microsoft.com/en-us/library/aa372105(VS.85).aspx for details. You can get the details you need from that.
How about something like this:
public static void FindInstalled(AppName)
{
RegistryKey myRegKey = Registry.LocalMachine;
myRegKey = myRegKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall");
String[] subkeyNames = myRegKey.GetSubKeyNames();
foreach (String s in subkeyNames)
{
RegistryKey UninstallKey = Registry.LocalMachine;
UninstallKey = UninstallKey.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\" + s);
Object oValue = UninstallKey.GetValue("DisplayName");
if (oValue != null)
{
if (oValue.ToString() == AppName)
{
oValue = UninstallKey.GetValue("UninstallString");
Console.Writeline("Uninstall URL - {0}", oValue.ToString());
break;
}
}
}
}

Windows RegKey - Default Browser Application Path

What RegKey can you get the default browser application's path from?
Best way to get to it from C#/.NET?
Here's the key you want:
HKEY_LOCAL_MACHINE\SOFTWARE\Classes\http\shell\open\command
And here's a quick registry tutorial for C#, if you need it.
Edit:
For per-user settings, use this key:
HKEY_CLASSES_ROOT\http\shell\open\command
(HKCR has both machine and user settings, user takes priority).
Note that this might not work on Vista. For more info, see here.
for windows 7 default browser path save in following registry key
HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\ Associations\UrlAssociations\http
by using c# you can get it as follows -
RegistryKey regkey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\shell\\Associations\\UrlAssociations\\http\\UserChoice", false);
string browser = regkey.GetValue("Progid").ToString();
Based on your answers I wrote this sample code that should do what you want (not tested)
public static string GetDefaultBrowserPath()
{
string defaultBrowserPath = null;
RegistryKey regkey;
// Check if we are on Vista or Higher
OperatingSystem OS = Environment.OSVersion;
if ((OS.Platform == PlatformID.Win32NT) && (OS.Version.Major >= 6))
{
regkey = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\shell\\Associations\\UrlAssociations\\http\\UserChoice", false);
if (regkey != null)
{
defaultBrowserPath = regkey.GetValue("Progid").ToString();
}
else
{
regkey = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Classes\\IE.HTTP\\shell\\open\\command", false);
defaultBrowserPath = regkey.GetValue("").ToString();
}
}
else
{
regkey = Registry.ClassesRoot.OpenSubKey("http\\shell\\open\\command", false);
defaultBrowserPath = regkey.GetValue("").ToString();
}
return defaultBrowserPath;
}
I just made a function for this:
public void launchBrowser(string url)
{
string browserName = "iexplore.exe";
using (RegistryKey userChoiceKey = Registry.CurrentUser.OpenSubKey(#"Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice"))
{
if (userChoiceKey != null)
{
object progIdValue = userChoiceKey.GetValue("Progid");
if (progIdValue != null)
{
if(progIdValue.ToString().ToLower().Contains("chrome"))
browserName = "chrome.exe";
else if(progIdValue.ToString().ToLower().Contains("firefox"))
browserName = "firefox.exe";
else if (progIdValue.ToString().ToLower().Contains("safari"))
browserName = "safari.exe";
else if (progIdValue.ToString().ToLower().Contains("opera"))
browserName = "opera.exe";
}
}
}
Process.Start(new ProcessStartInfo(browserName, url));
}

Categories