Is there any way (in C#, using WMI classes) to find out that how many times a particular software has been installed and uninstalled?
I want to run it on remote computer. I am getting software list by following code:
ManagementScope scope = new ManagementScope(#"\\" + ipAddress + #"\root\cimv2");
ObjectQuery query = new ObjectQuery("Select * from Win32_Product");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
ManagementObjectCollection queryCollection = searcher.Get();
foreach (ManagementObject m in queryCollection)
{
Console.Write(m["Caption"]+"\t");
Console.WriteLine(m["installDate"]);
}
Normally not.
When a program will be uninstalled every bit of the program should be removed from the machine like it was never their. Unfortunately nearly every program doesn't make a perfect job at this point leaving some artifacts on the machine.
Nevertheless the desired behavior is that after a uninstall everything is gone (including some kind of counter) so that it is only possible to check if a program is currently installed or not.
On the other site nothing permits a program to save somewhere some counter (e.g. registry) which will increased everytime a installation is started, but that's something specific for each program and no common mechanism exists where this counter should reside.
Related
I have the following instructions in my code.
ManagementObjectSearcher usersSearcher = new ManagementObjectSearcher(#"SELECT * FROM Win32_UserAccount");
ManagementObjectCollection users = usersSearcher.Get();
It works fine on most machines. But in some cases the result (users) is empty. I failed to determine the reason. all three machine where it had happened are Windows 7 (Ultimate, Professional, Home Basic).
Is there any special conditions that causes this query to fail?
Thanks in advance.
Suppose I'm programming a game and I want the option of banning people from it after violating the terms. I can ban them per account, I can also ban their IP but it's not going to ban them from my game forever. They will just have to create a new account and change their IP.
Is there something like a machine-ID that is unique for every machine in the world? If there is, is it possible to read it using a program language? Is it possible for the user to change this machine-ID?
Bulletproof solution?
I would say no solution will be 100% secure, even with huge invested money..
What you can do, is to make it as hard as possible for normal users, and this way minimize the cheaters.
You could make a hash id of the pc machine id + the mac address + the motherboard id + the harddisk id, etc. But a clever cracker/hacker could get around this. I mean take a look at companies like Microsoft that uses millions in making a secure way and still people can get around the activation in some way... ;)
In windows there is a hardware id, that you might be intrested in.
HKEY_LOCAL_MACHINE\Software\Microsoft\Cryptography\MachineGuid
Take a look at WMI too, there are examples of how to use it with c++
Windows Management Instrumentation (WMI) is a set of extensions to the Windows Driver Model that provides an operating system interface through which instrumented components.
see WMI c++ exmaples
How about hard disk serial number which you can get in WMI Win32_DiskDrive.
ManagementObjectSearcher searcher = null;
try
{
searcher = new ManagementObjectSearcher("root\\CIMV2", "SELECT * FROM Win32_DiskDrive");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("SerialNumber: {0}", queryObj["SerialNumber"]);
queryObj.Dispose();
}
}
finally
{
if (searcher != null)
searcher.Dispose();
}
Anyone else had to determine who the currently logged on user is remotely in a Windows 7 environment? I am using .NET 4.0 and C#. The environment is mixed XP and 7.
WMI queries involving sessions result in all active sessions, but not the session that is interactive.
UserName from ComputerSystem (WMI) returns null exception if user is connected via Remote Desktop, which is common enough that this method cannot be used.
PsLoggedOn takes too long for my purposes (yes, 300 ms is too long) and is surprisingly not accurate 100% of the time
Using p/invoke for WTSGetActiveConsoleSessionID or LsaEnumerateLogonSessions is too complicated and prone to memory leaks (from what I've read)
tasklist /S <computername> will return information for XP systems, but Windows 7 won't be agreeable thanks to that lovely UAC.
HKCU (win registry) is inaccessible remotely due to permissions restrictions, HKU is accessible, but Volatile Environment doesn't appear to have a tag for "active"
So far, the most reliable way is using PsExec to remotely execute qwinsta from the command line and traverse the output to text remotely. This is annoying and takes time (more than PsLoggedOn), but I'm running out of ideas here for reliability. Reliability before speed, but speed is very important in terms of cost benefit.
Third party tools are not an option, has to be a script, preferably WMI and C#. I delved into hitting the DC using Principal objects, but I'm afraid I might have confused myself more. Also, all user accounts are administrators.
I've done a lot of research over Google, but I am thinking that maybe I am looking in the wrong place.
Any takers?
you can achieve this by browsing Win32_ComputerSystem class's UserName Propperty :
ConnectionOptions con = new ConnectionOptions();
con.Username = "Administrator";
con.Password = "********";
ManagementScope scope = new ManagementScope(#"\\" + strIPAddress + #"\root\cimv2", con);
scope.Connect();
//check for scope.IsConnected, then process
ManagementObjectSearcher searcher =new ManagementObjectSearcher(#"\\" + strIPAddress + #"\root\cimv2", "SELECT * FROM Win32_ComputerSystem");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Win32_ComputerSystem instance");
Console.WriteLine("-----------------------------------");
Console.WriteLine("UserName: {0}", queryObj["UserName"]);
}
I have a really simple Powershell query:
Get-WmiObject -query 'ASSOCIATORS OF {Win32_LogicalDisk.DeviceID="C:"} WHERE AssocClass = Win32_LogicalDiskToPartition'
On a Windows 7 (64-bit) machine, running this in a Powershell correctly enumerates a single management object. However if I run the same query in an elevated Powershell I get a long pause and then no results.
I find a similar problem when trying to execute the WMI query in code (which is what I am actually trying to do) - when my program runs without elevation the code works, when it runs with elevation no results are returned. This is the simplest version of my code that shows this problem:
static void Main(string[] args)
{
var query = "ASSOCIATORS OF {Win32_LogicalDisk.DeviceID=\"C:\"} WHERE AssocClass = Win32_LogicalDiskToPartition";
var searcher = new ManagementObjectSearcher(query);
foreach (var o in searcher.Get())
{
Console.WriteLine(o);
}
Console.WriteLine("DONE");
Console.ReadLine();
}
Why does this happen ? More importantly is there anyway I can ensure that this query will execute correctly when run elevated - as the final program will need to run elevated for other reasons.
I think I found the culprit - I have an encrypted drive mounted using TrueCrypt. When I dismount that drive the enumeration works correctly, when I mount it again the problem re-appears.
My best guess is that WMI is hitting a problem because the encrypted drive has no partitions - though why it works when not running elevated is another thing entirely.
In add or remove programs you can view list of updates/patches for MS office Outlook. Is there a way to get this information using c# code. We tried WMI code
const string query = "SELECT HotFixID FROM Win32_QuickFixEngineering";
var search = new ManagementObjectSearcher(query);
var collection = search.Get();
foreach (ManagementObject quickFix in collection)
Console.WriteLine(quickFix["HotFixID"].ToString());
This only lists windows updates. Is there a way to list updates for office components?(for windows XP)
I believe you will have to use the registry to get these. The following registry keys should help:
#"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall",
#"SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall"
You will have to loop though both the values for the HKLM and HKCU hives in order to be sure you have everything. Then you can filter on DisplayName and Publisher for each entry in order to get only the MS office patches.
Note you could also try to query the Win32_Product class to get products installed by the Windows installer. Although I have often found that it does not list everything you need (however it might be sufficient for your current problem - but I am not in a position to check right now).