Shell:appsFolder show Windows Explorer when App is not installed - c#

I have a code like this
Process p = new Process();
p.StartInfo = new ProcessStartInfo("explorer.exe");
p.StartInfo.Arguments = #"shell:appsFolder\AppName";
But if the App isn't installed on the machine, it only open a window explorer.
How can I prevent it from opening the Windows Explorer if the App isn't installed?
I've also tried using this code, to check for the app, it is working fine, but is there a way to just dont show the windows explorer when the app isn't installed?
var FOLDERID_AppsFolder = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}");
ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(FOLDERID_AppsFolder);
List<PackageInfo> installedPackages = new List<PackageInfo>();
((IKnownFolder)appsFolder).ToList().Where(w => !w.ParsingName.Contains(".txt") && !w.ParsingName.Contains(".chm") && !w.ParsingName.Contains(".htm") && !w.ParsingName.Contains(".html") && !w.ParsingName.Contains("http://") && !w.ParsingName.Contains(".bat") && !w.ParsingName.Contains(".rtf") && !w.ParsingName.Contains(".url") && !w.ParsingName.Contains(".pdf")).ToList().ForEach(fe =>
{
try
{
installedPackages.Add(new PackageInfo
{
DisplayName = (fe.ParsingName.Replace(#"\", #"\\")),
FullName = fe.Name,
Version = fe.Properties.System.FileVersion.Value == null ? "" : fe.Properties.System.FileVersion.Value
});
Debug.WriteLine(fe.ParsingName);
}
catch { }
});
return installedPackages.OrderBy(ob => ob.FullName).ToList();
I've tried getting the output,error and exitcode of the process.
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.RedirectStandardError = true;
string errorx = p.StandardError.ReadToEnd(); //return empty string
string outputx = p.StandardOutput.ReadToEnd(); //return empty string
int exitint = p.ExitCode; //return 1
But it didn't give me anything useful.

The windows explorer doesn't show now after I've added the code
p.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;

Related

Check all parts windows features are enable and enable off .Net Framework

I am using that script to check Windows Feature .Net Framework 4.x is enable
private static bool CheckWindowsFeatureNetFx4()
{
try
{
Process p = CreateProcess();
p.StartInfo.FileName = "powershell.exe";
p.StartInfo.Arguments = "Get-WindowsOptionalFeature -Online -FeatureName NetFx4";
p.Start();
var stand = p.StandardOutput.ReadToEnd();
var err = p.StandardError.ReadToEnd();
var i1 = stand.IndexOf("State");
var i2 = stand.IndexOf("CustomProperties");
if (i1 < i2 && (err == null || err == ""))
{
var state = stand.Substring(i1 + 19, i2 - i1 - 21);
Console.WriteLine(state);
if (state.ToLower() == "enabled")
{
return true;
}
}
}
catch (Exception)
{
}
return false;
And enable this in this way:
private static void RunWindowsFeatureNetFx4(Session session)
{
Process p = CreateProcess();
try
{
p.StartInfo.FileName = "powershell.exe";
p.StartInfo.Arguments = "Install-WindowsFeature .NET-Framework-45-Features";
p.Start();
p.StandardOutput.ReadToEnd();
CheckWindowsFeatureNetFx4(session);
}
catch (Exception)
{
session["TurnOnWindowsFeature4"] = "false";
}
}
Problem is it dont check "subfeatures" and only main funkcion is enable return true. I was trying use this RunWindowsFeatureNetFx4 method when not all parts are enable and it does not enable the rest of the features.
My solution:
I created Dictionary with all features name which are enabled with .Net Framework 3.5 and 4.x. I took them to compare the return value when features are turned on and off. Next check all enabled and remove it from dictionary. Then enable all functions in the right order. Order is important.
This list work for net framework 4.8
static void Main(string[] args)
{
AddFeature();
CreateFileFeature();
RemoveEnable();
TurnOnFeatures();
}
private static void TurnOnFeatures()
{
try
{
Process p = CreateProcess();
p.StartInfo.FileName = "cmd.exe";
foreach (var item in featureToEnable)
{
p.StartInfo.Arguments = "/C DISM /online /enable-feature /featurename:" + item.Value + " /NoRestart";
p.Start();
var a = p.StandardOutput.ReadToEnd();
var b = p.StandardError.ReadToEnd();
Console.WriteLine(item.Key);
}
}
catch (Exception e)
{
Console.WriteLine(e.Message);
}
}
private static void RemoveEnable()
{
for (int i = 0; i < 17; i++)
{
if (featureToEnable.ContainsKey(i))
if (featureAllEnable.Any(x => x == featureToEnable[i]) == true)
featureToEnable.Remove(i);
}
}
private static void AddFeature()
{
featureToEnable.Add(0, "NetFx3");
featureToEnable.Add(1, "NetFx4-AdvSrvs");
featureToEnable.Add(2, "NetFx4Extended-ASPNET45");
featureToEnable.Add(3, "WCF-Services45");
featureToEnable.Add(4, "WCF-TCP-PortSharing45");
featureToEnable.Add(5, "WCF-Pipe-Activation45");
featureToEnable.Add(6, "WCF-TCP-Activation45");
featureToEnable.Add(7, "WCF-MSMQ-Activation45");
featureToEnable.Add(8, "IIS-NetFxExtensibility");
featureToEnable.Add(9, "IIS-NetFxExtensibility45");
featureToEnable.Add(10, "WAS-NetFxEnvironment");
featureToEnable.Add(11, "IIS-ASPNET45");
featureToEnable.Add(12, "IIS-ManagementService");
featureToEnable.Add(13, "IIS-ASPNET");
featureToEnable.Add(14, "WCF-HTTP-Activation45");
featureToEnable.Add(15, "WCF-HTTP-Activation");
featureToEnable.Add(16, "WCF-NonHTTP-Activation");
}
private static void CreateFileFeature()
{
Process p = CreateProcess();
try
{
p.StartInfo.FileName = "cmd.exe";
p.StartInfo.Arguments = "/C DISM /online /get-features /format:table";
p.Start();
var a = p.StandardOutput.ReadToEnd();
var b = p.StandardError.ReadToEnd();
List<string> s = new List<string>();
int endLine = output.IndexOf("\r\n");
while (output.Length > 0)
{
if (endLine == 0)
{
output = output.Substring(2, output.Length - 2);
}
else
{
s.Add(output.Substring(0, endLine));
output = output.Substring(endLine, output.Length - endLine);
}
endLine = output.IndexOf("\r\n");
}
foreach (var item in s)
{
if (item.ToLower().Contains("enable"))
{
int ind = item.IndexOf(" ");
featureAllEnable.Add(item.Substring(0, ind));
}
}
}
catch (Exception)
{
}
}
Edit:
List for net framework 4.7.2. I check framework on pc and use appropriate list
featureToEnable.Add(0, "NetFx3");
featureToEnable.Add(1, "NetFx3ServerFeatures");
featureToEnable.Add(2, "NetFx4");
featureToEnable.Add(3, "NetFx4ServerFeatures");
featureToEnable.Add(4, "NetFx4Extended-ASPNET45");
featureToEnable.Add(5, "WAS-NetFxEnvironment");
featureToEnable.Add(6, "IIS-NetFxExtensibility");
featureToEnable.Add(7, "IIS-NetFxExtensibility45");
featureToEnable.Add(8, "IIS-ASPNET45");
featureToEnable.Add(9, "IIS-ManagementService");
featureToEnable.Add(10, "WCF-HTTP-Activation45");
featureToEnable.Add(11, "WCF-TCP-Activation45");
featureToEnable.Add(12, "WCF-Pipe-Activation45");
featureToEnable.Add(13, "WCF-MSMQ-Activation45");
featureToEnable.Add(14, "WCF-HTTP-Activation");
featureToEnable.Add(15, "WCF-NonHTTP-Activation");
featureToEnable.Add(16, "WCF-TCP-PortSharing45");

Using ManagementObjectSearcher and Win32_Printer to check Status

I have been forced to use the RawPrinterHelper class to print to a thermal printer because the PrintDocument method has proven unfit for POS printing.
I now need to check the status of the printer prior to printing to be sure that it is, online and ready to print. I have been able to successful check attributes from Win32_Printer. I can see properties such as PrinterStatus, changing from 3, to a 2 or a 1 when out of paper or tray is open. This is great.
My question is, which properties should indicate it is O.K. to print? There must be more than just checking if PrinterStatus is idle (3).
private bool ReadyCheck(string printerName)
{
bool ready = false;
string query = string.Format("SELECT * from Win32_Printer WHERE Name LIKE '%{0}'", printerName);
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(query))
using (ManagementObjectCollection coll = searcher.Get())
{
try
{
foreach (ManagementObject printer in coll)
{
// Print status = 3, idle and ready to print
string status = printer.Properties["PrinterStatus"].Value.ToString();
string extendedPrinterStatus = printer.Properties["ExtendedPrinterStatus"].Value.ToString();
// What else means printer is ready?
if (status.Trim() == "3")
ready = true;
}
}
catch (ManagementException ex)
{
Console.WriteLine(ex.Message);
}
}
return ready;
}
Edit:
#vendettamit Sorry I didn't ask very well. For instance, Idle (3) indicates it's OK to print. I am wondering if there are more which also indicate it's OK to print such as; Printing (4), WarmUp (5), ect, or is Idle (3) the only time you should send the next print job? Thanks
Below are the values that you can take into account to check if It's ready to print:
Other (1)
Unknown (2)
Idle (3)
Printing (4)
Warmup (5)
Stopped Printing (6)
Offline (7)
Also a note from Remarks on MSDN documentation for Win32_Printer-
If you are retrieving PrinterStatus = 3 or PrinterState = 0, the printer driver may not be feeding accurate information into WMI. WMI retrieves the printer information from the spoolsv.exe process. It is possible the printer driver does not report its status to the spooler. In this case, Win32_Printer reports the printer as Idle.
**//check printer is online**
private static bool IsOnline(ManagementBaseObject printer)
{
bool isOnlineprinter = true;
PrinterNative.PrinterNative.PrinterNative printerNative = new PrinterNative.PrinterNative.PrinterNative();
var PrinterName = printerNative.GetPrinterName();
var PrinterNameProperty = printer.Properties["DeviceId"].Value.ToString();
var ResultPrinter01 = printer.Properties["ExtendedPrinterStatus"].Value.ToString();
var ResultPrinter02 = printer.Properties["PrinterState"].Value.ToString();
if (PrinterNameProperty == PrinterName)
{
//(no internet connection or printer switched off):PrinterState
if (ResultPrinter02 == "128"|| ResultPrinter02=="4096")
{
isOnlineprinter = false;
}
////printer is initializing....
//if (ResultPrinter02 == "16")
//{
// isOnlineprinter = false;
//}
//(no internet connection or printer switched off):ExtendedPrinterStatus
if (ResultPrinter01 == "7")
{
isOnlineprinter = false;
}
}
return isOnlineprinter;
}
**//check for out of paper**
private static bool IspaperOK(ManagementBaseObject printer)
{
bool PaperOK = true;
PrinterNative.PrinterNative.PrinterNative printerNative = new PrinterNative.PrinterNative.PrinterNative();
var PrinterName = printerNative.GetPrinterName();
var PrinterNameProperty = printer.Properties["DeviceId"].Value.ToString();
var PaperStatus = printer.Properties["PrinterState"].Value.ToString();
if (PrinterNameProperty == PrinterName)
{
//(PrinterState)16 = Out of Paper
//(PrinterState)5 = Out of paper
//(PrinterState)4 = paperjam
//(PrinterState)144 = Out of paper
if ((PaperStatus == "5") || (PaperStatus == "16")||(PaperStatus=="144"))
{
PaperOK = false;
}
}
return PaperOK;
}
**//Verify still printing state or not**
private static bool Isprinting(ManagementBaseObject printer)
{
bool Isprintingnow = false;
PrinterNative.PrinterNative.PrinterNative printerNative = new PrinterNative.PrinterNative.PrinterNative();
var PrinterName = printerNative.GetPrinterName();
var PrinterNameProperty = printer.Properties["DeviceId"].Value.ToString();
var printing01 = printer.Properties["PrinterState"].Value.ToString();
var printing02 = printer.Properties["PrinterStatus"].Value.ToString();
if (PrinterNameProperty == PrinterName)
{
//(PrinterState)11 = Printing
//(PrinterState)1024 = printing
//(PrinterStatus)4 = printing
if (printing01 == "11" || printing01 == "1024" || printing02=="4")
{
Isprintingnow = true;
}
}
return Isprintingnow;
}
**//check for error (Printer)**
private static bool IsPrinterError(ManagementBaseObject printer)
{
bool PrinterOK = true;
PrinterNative.PrinterNative.PrinterNative printerNative = new PrinterNative.PrinterNative.PrinterNative();
var PrinterName = printerNative.GetPrinterName();
var PrinterNameProperty = printer.Properties["DeviceId"].Value.ToString();
var PrinterSpecificError = printer.Properties["PrinterState"].Value.ToString();
var otherError = printer.Properties["ExtendedPrinterStatus"].Value.ToString();
if (PrinterNameProperty == PrinterName)
{
//(PrinterState)2 - error of printer
//(PrinterState)131072 - Toner Low
//(PrinterState)18 - Toner Low
//(PrinterState)19 - No Toner
if ((PrinterSpecificError == "131072")||(PrinterSpecificError == "18")||(PrinterSpecificError == "19")||(PrinterSpecificError == "2")||(PrinterSpecificError == "7"))
{
PrinterOK = false;
}
//(ExtendedPrinterStatus) 2 - no error
if (otherError=="2")
{
PrinterOK = true;
}
else
{
PrinterOK = false;
}
}
return PrinterOK;
}
**//check Network or USB**
private static bool IsNetworkPrinter(ManagementBaseObject printer)
{
bool IsNetwork = true;
PrinterNative.PrinterNative.PrinterNative printerNative = new PrinterNative.PrinterNative.PrinterNative();
var PrinterName = printerNative.GetPrinterName();
var PrinterNameProperty = printer.Properties["DeviceId"].Value.ToString();
var network = printer.Properties["Network"].Value.ToString();
var local = printer.Properties["Local"].Value.ToString();
if (PrinterNameProperty == PrinterName)
{
if (network == "True")
{
IsNetwork = true;
}
if (network == "True" && local == "True")
{
IsNetwork = true;
}
if (local == "True" && network=="False")
{
IsNetwork = false;
}
}
return IsNetwork;
}
//(PrinterState)16 = Out of Paper
//(PrinterState)5 = Out of paper
//(PrinterState)4 = paperjam
//(PrinterState)144 = Out of paper
//(PrinterState)4194432 = Lid Open
//(PrinterState)4194448 = Out of paper/Lid open
//(PrinterState)4096= Offline
//(PrinterState)1024= Printing
//(PrinterState)128= Printer is offline

How to translate this PowerShell script to C#? - Get-ItemProperty

I can get a list of installed applications by using this PowerShell command:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName
in C#, it doesn't return the exact list like I see in PowerShell, I need it to show exactly the output from PowerShell.
It shows a totally different list with other programs.
public void conf() {
process p1 = new Process();
ProcessStartInfo psi1 = new ProcessStartInfo("powershell", "Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\* | Select-Object DisplayName");
psi1.RedirectStandardOutput = true;
psi1.CreateNoWindow = true;
p1.StartInfo = psi1;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.Verb = "runas";
p1.Start();
string output = p1.StandardOutput.ReadToEnd();
Console.WriteLine(output);
p1.WaitForExit(400);
}
What am I doing wrong?
Thanks.
If you are talking about content - if you force C# program to run as x64 in Configuration Manager, you'll get the same output. And by default (Any CPU) it was reading from and x86 registry key. Or if you will run Powershell x86, you'll get the same result, as your original C# program
If you query also HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* key and merge results you'll get the whole list. Make sure your program is x64 in that case
There is some mess with spaces in stdout from PowerShell, so I just removed it.
static void Main(string[] args)
{
var lines = GetSoft("Get-ItemProperty HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*")
.Union(GetSoft("Get-ItemProperty HKLM:\\Software\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\*"))
.Distinct()
.ToList();
lines.Sort();
foreach (var line in lines)
{
Console.WriteLine(line);
}
Console.WriteLine(lines.Count);
Console.ReadLine();
}
public static IEnumerable<string> GetSoft(string key)
{
Process p1 = new Process();
ProcessStartInfo psi1 = new ProcessStartInfo("powershell",
key + " | Select-Object DisplayName")
{
RedirectStandardOutput = true,
CreateNoWindow = true
};
p1.StartInfo = psi1;
p1.StartInfo.UseShellExecute = false;
p1.StartInfo.Verb = "runas";
p1.Start();
var output = p1.StandardOutput.ReadToEnd();
var result= output.Split('\r', '\n').Select(s => s.Trim()).Where(s => !String.IsNullOrWhiteSpace(s));
p1.WaitForExit(400);
return result;
}
}

Can I access a secured network folder with Directory.GetFiles()?

Is it possible to access a network folder with Directory.GetFiles() that I would normally have to enter my credentials for when opening through explorer?
If the running user is the logon user (with profil loading) and have already access to the remote path (by entering credentials), your application, which may run with user's profile loaded, should access to the UNC path without any login.
Otherwise, you can use this piece of code to logon you can find in GitHub :
using (UNCAccessWithCredentials unc = new UNCAccessWithCredentials())
{
if (unc.NetUseWithCredentials("uncpath", user, domain, password))
{
// Directory.GetFiles() here
}
}
It is possible. I usually spawn a process to pass the credentials to the system. Please see the code posted below which does exactly this. Once the process has completed you will be able to use the network share.
public void MapPath() {
string strServer = “ServerName”;
string strShare = “ServerShare”;
string strUsername = “ServerUsername”;
string strPassword = “ServerPassword”;
Process pNetDelete = new Process();
pNetDelete.StartInfo.CreateNoWindow = true;
pNetDelete.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pNetDelete.StartInfo.UseShellExecute = false;
pNetDelete.StartInfo.FileName = “net”;
pNetDelete.StartInfo.Arguments = string.Format(“use /DELETE {0}\
{1} /Y”, strServer, strShare);
pNetDelete.Start();
pNetDelete.WaitForExit();
Process pNetShare = new Process();
pNetShare.StartInfo.CreateNoWindow = true;
pNetShare.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
pNetShare.StartInfo.UseShellExecute = false;
pNetShare.StartInfo.RedirectStandardError = true;
pNetShare.StartInfo.RedirectStandardOutput = true;
pNetShare.StartInfo.FileName = “net”;
pNetShare.StartInfo.Arguments = string.Format(“use \\{0}\{1} /u:"{2}" "{3}"”,
strServer, strShare, strUsername, strPassword);
pNetShare.Start();
pNetShare.WaitForExit();
string strError = pNetShare.StandardError.ReadToEnd();
if (pNetShare.ExitCode != 0)
{
throw new Exception(strError);
}
}

mass .net update in iis6

We have about 200 web sites (on 3 separate servers, so 600 total) that we're going to have to update to run on .net 4 framework. They're currently set to run on .net 2. Does anyone know if there's a way to do this with a c# console program? Thanks!
Edit: I found a tool called IIS Metabase Explorer. Using that along with some code I had found a while ago for setting up a site in IIS 6, I came up with the following code. Hopefully it will be of help to others.
I would call it like
UpdateSiteToDotNet4("mytestsite", "mywebserver", #"D:\inetpub\wwwroot\", "DotNet4");
private void UpdateSiteToDotNet4(string siteName, string server, string serverPath, string newAppPoolId)
{
var service = new DirectoryEntry("IIS://" + server + "/W3SVC");
DirectoryEntries sites = service.Children;
bool found = false;
foreach (DirectoryEntry siteEntry in sites)
{
var siteId = siteEntry.Name;
DirectoryEntries siteSettings = siteEntry.Children; //Root
foreach (DirectoryEntry siteSetting in
from DirectoryEntry siteSetting in siteSettings
where siteSetting.SchemaClassName == "IIsWebVirtualDir"
let siteRoot = siteSetting.Properties["Path"][0].ToString()
where siteRoot.ToLower().Trim() == (serverPath + siteName).ToLower().Trim()
select siteSetting)
{
siteSetting.Properties["AppPoolId"].Value = newAppPoolId;
siteSetting.CommitChanges();
//Update to version v4.0.30319
var aspnet = string.Format(#"{0}\Microsoft.NET\Framework\v{1}\aspnet_regiis.exe", Environment.GetEnvironmentVariable("windir"), "4.0.30319");
var startInfo = new ProcessStartInfo(aspnet)
{
Arguments = string.Format("-sn \"{0}\"", "W3SVC/" + siteId + "/Root"),
WindowStyle = ProcessWindowStyle.Hidden,
UseShellExecute = false,
CreateNoWindow = true
};
var process = new Process { StartInfo = startInfo };
process.Start();
process.WaitForExit();
process.Dispose();
found = true;
break;
}
if (found) break;
}
}

Categories