Difference in Management.ManagementObject between XP and Win7 - c#

I have two OSes set up, a win7 and an XP, both them are in the same WORKGROUP (none of them is in a domain this way)
I'm trying to get the WorkGroup name of the computer with this code:
VB.NET:
Public Function GetWorkGroup() As String
Dim computer_system As New Management.ManagementObject(String.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName))
Dim result As Object = computer_system("Workgroup")
Return result.ToString()
End Function
C#:
public string GetWorkGroup()
{
Management.ManagementObject computer_system = new management.ManagementObject(string.Format("Win32_ComputerSystem.Name='{0}'", Environment.MachineName));
object result = computer_system("Workgroup");
return result.ToString();
}
This does work on Win7, but on XP computer_system("Workgroup") results in Nothing.
If I want to make it work I have to make the following modification:
VB.NET:
Dim result As Object = computer_system("Domain")
C#:
object result = computer_system("Domain");
This works on both Win7 and XP, gaves back the correct Workgroup name, but cleary somethings wrong if I get back the Workgroup name with the Domain property on XP.
Could someone explain please why does XP handles it's Workgroup as a Domain? thanks.

Related

Converting username to SID in C#

I'm trying to use this code to convert a Windows username (in the classic .\username form) to a SID object:
NTAccount account = new NTAccount(".\\MyUser");
SecurityIdentifier sid = (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
However, I keep getting the following exception when executing the last instruction:
System.Security.Principal.IdentityNotMappedException: 'Some or all
identity references could not be translated.'
What am I doing wrong?
Answering my own question after some trial and error:
The code is correct, but the Translate function doesn't seem to support the shorthand . to indicate the account is local and not in a domain. So in case you have a username that starts with .\ you need to replace the dot with the machine name. The following code works correctly:
public static SecurityIdentifier usernameToSid(string user)
{
if (user.StartsWith(#".\"))
{
user = user.Replace(#".\", Environment.MachineName + #"\");
}
NTAccount account = new NTAccount(user);
return (SecurityIdentifier)account.Translate(typeof(SecurityIdentifier));
}

Get Linux server time from windows service c#

Is there anyway I can get linux server time from windows service given linux server IP ? I tried to use Cliwrap (https://github.com/Tyrrrz/CliWrap) and wrote the following function but it is not working as well:
public string GetLinuxServerTime()
{
using (var cli = new Cli("bash.exe"))
{
// Execute
var output = cli.Execute("ssh user#10.104.12.114 date");
return "abc";
}
}
Kindly suggest some another way.

Mapped drivelabel windows 7 issue

I am going crazy with an issue with LABEL of mapping a drive to windows with windows 7 OS. Scenario;
We need to map the drive as soon as user logs in to the machine. That seems to be working fine with other os versions except windows 7. Steps for windows 7;
EXE (c# made by us) launched in windows 7
EXE has mapped drive correctly
User logged out
Logged in back
Again exe is trying to map drive (Its registered as a startup exe)
The mapped drive label becomes "Network Drive" (Not sure how)
We are setting the proper values in registry as well as shown in below figure;
Problem is here;
Issue is only occurring when we do logout and login. If we manually launch exe, it works fine...
I have also tried to DELETE all these registry before mapping driving assuming it might be cache or something but nothing helped..
We are using zMapDrive to map a drive;
//create struct data
structNetResource stNetRes = new structNetResource();
stNetRes.iScope = 2;
stNetRes.iType = RESOURCETYPE_DISK;
stNetRes.iDisplayType = 3;
stNetRes.iUsage = 1;
stNetRes.sRemoteName = ls_ShareName;
stNetRes.sLocalName = ls_Drive;
//prepare params
int iFlags = 0;
if (lf_SaveCredentials) { iFlags += CONNECT_CMD_SAVECRED; }
if (lf_Persistent) { iFlags += CONNECT_UPDATE_PROFILE; }
if (ls_PromptForCredentials) { iFlags += CONNECT_INTERACTIVE + CONNECT_PROMPT; }
if (psUsername == "") { psUsername = null; }
if (psPassword == "") { psPassword = null; }
//if force, unmap ready for new connection
if (lf_Force) { try { zUnMapDrive(true); } catch { } }
//call and return
int i = WNetAddConnection2A(ref stNetRes, psPassword, psUsername, iFlags);
if (i > 0) { throw new System.ComponentModel.Win32Exception(i); }
Maybe a simple powershell script, renaming network drive will work for you? You can then use Task Scheduler to run it every time a user logs in.
$Rename = New-Object -ComObject Shell.Application
$Net = New-Object -ComObject WScript.Network
# map the drive if the path doesn't exist
If (!(Test-Path Z:))
{
$Net.MapNetworkDrive("Z:", '\\SERVER_ADDRESS\Directory', $false, "user", "password")
}
# change the drive name
$Rename.NameSpace("Z:\").Self.Name = "MyNetDriveLabel"
From my experience, support for network mapped drives is somewhat buggy in Windows 7, so I use similar workaround on a few of our Win7 machines.

How can I get the device name?

I'm developing an application for Honeywell Dolphin 6100, a mobile computer with a barcode scanner that uses Windows CE 5.0 like OS.
I want to get the device name using code lines.
Any one have an idea on this ?
Note : I'm working with VS2008 using C# on win7.
private const string IDENTITY = #"HKEY_LOCAL_MACHINE\Ident";
private const string NAME = "Name";
string DeviceName = (string)Registry.GetValue(IDENTITY, NAME, "NAME");
We developed an application for the same device, we used this sentense to get device name.
Private Sub deviceidt_ParentChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles deviceidt.ParentChanged
Dim deviceidn As String = System.Net.Dns.GetHostName
deviceidt.Text = deviceidn
End If
End Sub

What's wrong with Registry.GetValue?

I trying to get a registry value:
var value = Registry.GetValue(#"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography", "MachineGuid", 0);
In Windows XP all ok, but in Windows 7 returns 0. In HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography using regedit I see MachineGuid, but if I run
var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE").OpenSubKey("Microsoft").OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree).GetValueNames();
keys.Length is 0.
What do I do wrong? With other values all ok in both of OS.
The problem is that you probably are compiling the solution as x86, if you compile as x64 you can read the values.
Try the following code compiling as x86 and x64:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("MachineGUID:" + MachineGUID);
Console.ReadKey();
}
public static string MachineGUID
{
get
{
Guid guidMachineGUID;
if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography") != null)
{
if (Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid") != null)
{
guidMachineGUID = new Guid(Microsoft.Win32.Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Cryptography").GetValue("MachineGuid").ToString());
return guidMachineGUID.ToString();
}
}
return null;
}
}
}
You can read more about Accessing an Alternate Registry View.
You can found in here a way of reading values in x86 and x64.
It probably has to do with UAC (User Account Control). The extra layer of protection for Windows Vista and Windows 7.
You'll need to request permissions to the registry.
EDIT:
Your code right now:
var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE")
.OpenSubKey("Microsoft")
.OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree)
.GetValueNames();
Only requests the permissions on the Cryptography subkey, maybe that causes the problem (at least I had that once), so the new code would then be:
var keys = Registry.LocalMachine.OpenSubKey("SOFTWARE", RegistryKeyPermissionCheck.ReadSubTree)
.OpenSubKey("Microsoft", RegistryKeyPermissionCheck.ReadSubTree)
.OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree)
.GetValueNames();
EDIT2:
I attached the debugger to it, on this code:
var key1 = Registry.LocalMachine.OpenSubKey("SOFTWARE", RegistryKeyPermissionCheck.ReadSubTree);
var key2 = key1.OpenSubKey("Microsoft", RegistryKeyPermissionCheck.ReadSubTree);
var key3 = key2.OpenSubKey("Cryptography", RegistryKeyPermissionCheck.ReadSubTree);
var key4 = key3.GetValueNames();
It turns out, you can read that specific value, at least that's my guess, because all data is correct, until I open key3, there the ValueCount is zero, instead of the expected 1.
I think it's a special value that's protected.
You say you're on 64-bit Windows: is your app 32-bit? If so it's probably being affected by registry redirection and is looking at HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Cryptography. You may have to P/Invoke to work around it: http://msdn.microsoft.com/en-us/library/aa384129.aspx.
If you're not an administrator, you only have read permission on HKLM. You need to open the key read-only instead. Not sure how to do that with .NET's Registry class; with the API directly, you use RegOpenKeyEx() with the KEY_READ flag.
EDIT: After checking MSDN, I see that OpenSubKey() does open read only, and returns the contents if it succeeds and nothing if it fails. Since you're chaining multiple OpenSubKey calls, it's most likely one of them that's failing that causes the others to fail. Try breaking them out into separate calls, and checking the intermediate values returned.
Maybe a little late to the party, but, none of the solutions worked for me.
This is how I've solved this issue:
public static Guid GetMachineGuid
{
get
{
var machineGuid = Guid.Empty;
var localMachineX64View = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var cryptographySubKey = localMachineX64View.OpenSubKey(#"SOFTWARE\Microsoft\Cryptography");
if (cryptographySubKey == null) return machineGuid;
var machineGuidValue = (string)cryptographySubKey.GetValue("MachineGuid");
Guid.TryParse(machineGuidValue, out machineGuid);
return machineGuid;
}
}
I solved the problem when i imported Microsoft.Win32 and changed the application-settings to x64 like pedrocgsousa mentioned.

Categories