How do I uninstall softwares using C# or powershell - c#

I want to uninstall a list of softwares silently, which I received from Windows Registry.
This has to be integrated in a WPF Application.
I have tried Cim, WMI, ManagementObjectSearcher for uninstalling as below
Get-CimInstance -Class Win32_Product | Where {$_.Name -like \"{returnStr}\"} | Remove-CimInstance".Replace("{returnStr}", softwareName)
ManagementObjectSearcher mos = new ManagementObjectSearcher("SELECT * FROM Win32_Product WHERE Name = '" + ProgramName + "'");
foreach (ManagementObject mo in mos.Get())
{
if (mo["Name"].ToString() == ProgramName)
{
object hr = mo.InvokeMethod("Uninstall", null);
}
}
Both these methods were unable to find the Software from the name that we got from Registry.
In ManagementObjectSearcher mos.Get() it throws Call Cancelled error.
Also tried the UninstallString from Registry which is also not working and I am getting options box for MsiExec.
Powershell script to uninstall these softwares also might help.

Related

How to activate Windows 10 in C# winform application

I've created an application to get the OEM key and then activate Windows with that key. I can get the key from
ManagementObjectSearcher s = new ManagementObjectSearcher("SELECT * FROM SoftwareLicensingService");
But how can I activate Windows with that key? I can do that with Powershell as below:
$service = get-wmiObject -query 'select * from SoftwareLicensingService'
if($key = $service.OA3xOriginalProductKey){
Write-Host 'Activating using product Key:' $service.OA3xOriginalProductKey
$service.InstallProductKey($key)
}else{
Write-Host 'Key not found. Please contact IT for more information'
}
pause
You can call methods of a WMI object by using InvokeMethod of the ManagementObject. Here you are interested to invoke the InstallProductKey method of SoftwareLicensingService.
For example:
var searcher = new ManagementObjectSearcher(
"SELECT * FROM SoftwareLicensingServissce");
var obj = searcher.Get().Cast<ManagementObject>().First();
var inParams = obj.GetMethodParameters("InstallProductKey");
inParams["ProductKey"] = obj["OA3xOriginalProductKey"];
var outParams = obj.InvokeMethod("InstallProductKey", inParams, null);
MessageBox.Show(((PropertyData)outParams["ReturnValue"])?.Value?.ToString());
To run the example, make sure you "Run as Administrator".

Invoke RenamePrinter as a non-administrator user

I'm trying to rename a printer using WMI in C#. I can run queries to select printers, but when I try to invoke the RenamePrinter method, I get an Access Denied result. I've tried running this application as administrator and creating a manifest, but I can't seem to invoke this method unless I'm actually running under the administrator account.
var oSearcher = new ManagementObjectSearcher(oMs, oQuery);
ManagementObjectCollection oReturnCollection = oSearcher.Get();
foreach (ManagementObject oReturn in oReturnCollection)
{
var objectClass = new ManagementClass("Win32_Printer");
var inParams = objectClass.GetMethodParameters("RenamePrinter");
inParams["NewPrinterName"] = "..."; // something
ManagementBaseObject oResult = oReturn.InvokeMethod("RenamePrinter", inParams, null);
var result = oResult["returnValue"]; // 5 = Access Denied
Is there some way I can invoke RenamePrinter under a normal user's account -- even if it means running as administrator?
I've been trying to do this, and I've found that I can't do this with certain network printers, but with local printers it works.
What I did was launch PowerShell as local admin and run it from there:
public void RenamePrinter(string strCurrentName, string strNewPrinterName)
{
var newProcessInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = #"C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe",
Verb = "runas",
CreateNoWindow = true,
Arguments = "-Command \"$printer = get-wmiobject win32_printer | where { $_.Name -eq '" + strCurrentName + "' }; $printer.RenamePrinter('" + strNewPrinterName + "')\""
};
System.Diagnostics.Process.Start(newProcessInfo);
}
I receive the same "Access Denied" error when I attempt this with network printers (maybe it's a driver thing? I don't know) but this works for local printers.

win32_processor out of memory

I want to get id processor in .NET with WMI but when I'm using the get() method from the ManagementObjectSearcher, I'm getting an out of memory exception ...
If you want to take a look from the code see below :
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"select * from Win32_Processor");
foreach (ManagementObject share in searcher.Get())
foreach (PropertyData PC in share.Properties)
if (PC.Name.Equals("ProcessorId"))
return (string)PC.Value;
return null;
This code works on others computers but not on mine ...
I'm using windows 7.
What is the problem ?
I tried to restart WMI service and that not resolve my problem :(
There are several reasons which could cause out of memory exception.
possible memory leak in WMI, source:
http://brooke.blogs.sqlsentry.net/2010/02/win32service-memory-leak.html
check whether you have permission(s), that would explain why does your code work on some computers and why doesn't on yours.
run your code as Administrator (for debugging start VS as Administrator)
Here is an other code snippet, try this one as well... who knows
Sample:
public static String GetCPUId()
{
String processorID = "";
ManagementObjectSearcher searcher = new ManagementObjectSearcher(
"Select * FROM WIN32_Processor");
ManagementObjectCollection mObject = searcher.Get();
foreach (ManagementObject obj in mObject)
{
processorID = obj["ProcessorId"].ToString();
}
return processorID;
}
Source: WIN32_Processor::Is ProcessorId Unique for all computers

Third Party Antivirus Name Fetch

Detect Antivirus on Windows using C#
This link tells whether antivirus is installed in the system or not ? Can we code in such a way that we fetch the name of the antivirus installed too?
You need to access wmi displayName property for each antivirus instance. Use ManagementBaseObject.Properties
string wmipathstr = #"\\" + Environment.MachineName + #"\root\SecurityCenter2";
var searcher = new ManagementObjectSearcher(wmipathstr, "SELECT * FROM AntivirusProduct");
var instances = searcher.Get();
foreach (var instance in instances)
{
Console.WriteLine(instance.GetPropertyValue("displayName"));
}

Uninstall application on remote computer silently

I am developing a C# program to remotely uninstall an application. It works fine but the problem is that it does not list all of the installed products on a particular selected computer.
The code for listing the installed product using WMI is :
void ListAllProducts()
{
try
{
ConnectionOptions connection = new ConnectionOptions();
connection.Username = Connect.UserName;
connection.Password = Connect.Password;
connection.Authority = "ntlmdomain:MSHOME";
ManagementScope scope = new ManagementScope("\\\\"+ Connect.MachineName +"\\root\\CIMV2", connection);
scope.Connect();
ObjectQuery query = new ObjectQuery("SELECT * FROM Win32_Product");
ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query);
System.Threading.Thread.Sleep(5000);
foreach (ManagementObject queryObj in searcher.Get())
{
listBox4.Items.Add(queryObj["Name"].ToString());
listBox2.Items.Add (queryObj["Name"].ToString ());
listBox1.Items.Add(queryObj["IdentifyingNumber"].ToString());
listBox3.Items.Add(queryObj["Version"].ToString());
}
}
catch (ManagementException e)
{
MessageBox.Show("An error occurred while querying for WMI data: " + e.Message);
}
}
The code for uninstalling all product is :
void UninstallProduct()
{
try
{
ConnectionOptions connection = new ConnectionOptions();
connection.Username = Connect.UserName;
connection.Password = Connect.Password;
connection.Authority = "ntlmdomain:MSHOME";
ManagementScope scope = new ManagementScope("\\\\"+Connect.MachineName +"\\root\\CIMV2", connection);
scope.Connect();
ManagementObject classInstance = new ManagementObject(scope, new ManagementPath ("Win32_Product.IdentifyingNumber='"+listBox1.Text +"',Name='"+listBox2.Text+"',Version='"+ listBox3.Text+"'"),null);
// no method in-parameters to define
// Execute the method and obtain the return values.
ManagementBaseObject outParams =
classInstance.InvokeMethod("Uninstall", null, null);
// List outParams
MessageBox.Show ("Uninstallation Starts");
}
catch(ManagementException err)
{
MessageBox.Show("An error occurred while trying to execute the WMI method: " + err.Message);
}
}
Please help me out to list all the products installed on the selected machine and to uninstall it without the consent of the user of that selected machine.
I believe your question relates to knowing which applications are installed on a remote machine. Once you know that, you can use your code to uninstall them. With that being the case, here is a link to an article on how to list all of the applications (with their uninstall information) on a remote computer:
http://mdb-blog.blogspot.com/2010/12/c-check-if-programapplication-is.html
The WMI Win32_Product only represents products that are installed by Windows Installer. To get a list of all installed products, you need to enumerate the subkeys of the SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall registry key. To do this remotely, you can use the WMI registry class StdRegProv class. TechNet includes sample scripts that show how this can be done, and which you can adapt to your particular needs:
How do I list all the installed applications on a given machine?
List Installed Software

Categories