share folder c# - not work - c#

I try to share a local folder in my computer - The code is shown below , taken from the Internet and appear in many places, but not working .
Am I missing something ?
private void button1_Click(object sender, EventArgs e)
{
// Create a ManagementClass object
ManagementClass managementClass = new
ManagementClass("Win32_Share");
// Create ManagementBaseObjects for in and out parameters
ManagementBaseObject inParams =
managementClass.GetMethodParameters("Create");
ManagementBaseObject outParams;
// Set the input parameters
inParams["Description"] = "My Files Share";
inParams["Name"] = "My Files Share";
inParams["Path"] = #"C:\folder";
inParams["Type"] = 0x0; // Disk Drive
// Invoke the method on the ManagementClass object
outParams = managementClass.InvokeMethod("Create", inParams,
null);
//Check to see if the method invocation was successful
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
{
throw new Exception("Unable to share directory.");
}
}

First of all , the problem was a permission. I'v tried to do net share through CMD and it also did not work, only when I run CMD as administrator share operation worked.
The same thing in C # , Visual Studio you MUST run as an administrator, then it works. Here's my code:
try
{
ManagementClass managementClass = new ManagementClass("Win32_Share");
ManagementBaseObject inParams = managementClass.GetMethodParameters("Create");
inParams["Description"] = Description;
inParams["Name"] = ShareName;
inParams["Path"] = folderPath;
inParams["Type"] = 0; //Disk Drive
inParams["MaximumAllowed"] = null;
inParams["Password"] = null;
inParams["Access"] = null;
ManagementBaseObject outParams;
outParams = managementClass.InvokeMethod("Create", inParams, null);
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
throw new Exception();
ManagementObject share = new ManagementObject(managementClass.Path + ".Name='" + ShareName + "'");
}
catch
{
MessageBox.Show("You must run the program as administrator", "N.U.C", MessageBoxButtons.OK, MessageBoxIcon.Information);
Environment.Exit(1);
}

The code it's ok. If what you want it's to debug the program with your IDE it's pretty simple, if you are using Visual Studio as IDE, just run VS with Administrator right and open your project.

Related

How to EnableDHCP and delete IP from adapter via WMI

Im making some kind of IP setting tool and i have a problem with EnableDHCP method via WMI (Win32_NetworkAdapterConfiguration). Adapter was set to DHCP but there is still IP and gateway. So i am using netsh function which works to me but i want to use only WMI. Any advice?
I try some methods like Lease and send null to static but it doesnt work.
s//THIS ONE I WANT TO USE BUT ITS LET IP AT ADAPTER EVEN DHCP IS ENABLED
public void button1_Click(object sender, EventArgs e)
{
ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection objMOC = objMC.GetInstances();
//check numbe of aktive ports
foreach (ManagementObject objMO in objMOC)
{
if ((bool)objMO["IPEnabled"])
{
try
{
// write parameters to active port
ManagementBaseObject setIP;
setIP = objMO.InvokeMethod("EnableDHCP", null, null);
}
catch (Exception x)
{
}
}
}
}
Process p = new Process();//netsh work well but i dont want to use
ProcessStartInfo psi = new ProcessStartInfo("netsh", "interface ip set address \"" + adapter.Name + "\" dhcp");
p.StartInfo = psi;
p.Start();
I expect using EnableDHCP over WMI and IP adress was cleared, but IP adress is still there
This(Picture)
public Collection<PSObject> Invoke(string Query)
{
Collection<PSObject> ps = new Collection<PSObject>();
try
{
using (PowerShell PSI = PowerShell.Create())
{
PSI.AddScript(Query);
ps = PSI.Invoke();
}
}
catch (Exception ex)
{
ps = null;
throw;
}
return ps;
}
Create a class to invoke PS Query
public List<YourObjectList> GetInfo(string ParametersIFYouWant)
{
List<YourObjectList> ListInfo = new List<YourObjectList>();
InvokePowerShellQuery powerShellQuery = new InvokePowerShellQuery();
string PSQuery = "Query Here as a string";
try
{
var PSOutput = powerShellQuery.Invoke(PSQuery);
//In your case you wont need unless in you PS Query you return a message or some other object you want to report back for success or failure.
foreach (var item in PSOutput)
{
//Fill ListInfo
}
}
catch (Exception ex)
{
Listinfo = null;
//handle however you want here
}
return Listinfo;
}
Send the query to your class
Quick Google search on PS Queries you may use
https://www.pdq.com/blog/using-powershell-to-set-static-and-dhcp-ip-addresses-part-1/
https://4sysops.com/archives/set-an-ip-address-and-configure-dhcp-with-powershell

Uninstall msi/service remotely with administrator rights

I have implemented code to uninstall a msi. The problem is, when I try to uninstall it remotely using WMI it doesnt get happen and even don't throw any exception. I tried on local and found that when I run command "MsiExec.exe /x {Product Code} /qn"; in cmd as administrator the service gets uninstall & even when I try to debug code in Visual Studio (as administrator) the code works too.
But unfortunately this has to get unistall at remote machine. Is there a way where I can run this code or command as administrator remotely?. I googled and found many answers but nothing worked. Any other approach?
private void UnInstall(string ipAddress, long discoveredMachineId)
{
ipAddress = ipAddress.Trim();
ConnectionOptions connection = new ConnectionOptions();
connection.Username = this.userName;
connection.Password = this.password;
ManagementScope scope = new ManagementScope(#"\\" + ipAddress + "\\root\\CIMV2");
try
{
scope.Connect();
if (scope.IsConnected == true)
{
//Start Uninstalling
try
{
var checkKey = Registry.LocalMachine.OpenSubKey(#"Software\Microsoft\Windows\CurrentVersion\Uninstall\{Product Code}");
if (checkKey == null)
{
// Key does not exist
Console.WriteLine("Not Installed");
}
else
{
// Key exist
var wmiProcess = new ManagementClass(scope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
ManagementBaseObject inParams = wmiProcess.GetMethodParameters("Create");
inParams["CommandLine"] = "MsiExec.exe /x {Product Code} /qn";
ManagementBaseObject outParams = wmiProcess.InvokeMethod("Create", inParams, null);
Console.WriteLine("Creation of the process returned: " + outParams["returnValue"]);
Console.WriteLine("Process ID: " + outParams["processId"]);
Console.WriteLine("UnInstalled Successfully...");
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}

Restart remote server from client

I have accessed remote server but it can be some problem. So i want to restart the remote via client side using c#. Is that possible to restart?
EDIT: See #amitdayama's answer below for a more reasonable approach
Yes this is possible.
First, add this using namespace statements:
using System.Diagnostics;
using System.Runtime.InteropServices;
To shut down your computer, use:
Process.Start("shutdown","/s /t 0"); // starts the shutdown application
// the argument /s is to shut down the computer
// the argument /t 0 is to tell the process that
// the specified operation needs to be completed
// after 0 seconds
To restart your computer, use:
Process.Start("shutdown","/r /t 0"); // the argument /r is to restart the computer
Source: Codeproject.com
using System;
using System.Management;
namespace WMI3
{
class Class1
{
static void Main(string[] args)
{
Console.WriteLine("Computer details retrieved using Windows Management Instrumentation (WMI)");
//Connect to the remote computer
ConnectionOptions co = new ConnectionOptions();
co.Username = "username";
co.Password = "Pass";
string serverName="servername";
System.Management.ManagementScope ms = new System.Management.ManagementScope(servername + "\\root\\cimv2", co);
//Query remote computer across the connection
System.Management.ObjectQuery oq = new System.Management.ObjectQuery("SELECT * FROM Win32_OperatingSystem");
ManagementObjectSearcher query1 = new ManagementObjectSearcher(ms,oq);
ManagementObjectCollection queryCollection1 = query1.Get();
foreach( ManagementObject mo in queryCollection1 )
{
string[] ss={""};
mo.InvokeMethod("Reboot",ss);
Console.WriteLine(mo.ToString());
}
}
}
}
This is my solution which supports silent mode, "fire and forget" and delayed reboot. In can simply become enhanced with an individual logon for the process start.
public static bool RebootRemoteMachineSOVersion(ContentControl parentControl, string remoteHostNameOrIp, int waitSeconds = 60, bool silent = false, bool waitForExit = true)
{
waitSeconds = Math.Max(0, waitSeconds);
if (!silent && MessageBox.Show($"Reboot remote computer ({ remoteHostNameOrIp }) in { waitSeconds } seconds?", "Reboot remote machine", MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No) == MessageBoxResult.No)
{
return false;
//<-----------
}
ProcessStartInfo processInfo = new ProcessStartInfo();
processInfo.FileName = "shutdown.exe";
processInfo.Arguments = $#"-r -t { waitSeconds } -m \\{ remoteHostNameOrIp }";
processInfo.WindowStyle = ProcessWindowStyle.Hidden;
processInfo.CreateNoWindow = true;
Process proc;
try
{
proc = Process.Start(processInfo);
if (waitForExit) proc.WaitForExit();
else return true;
//<----------
}
catch (Exception ex)
{
if (!silent) MessageBox.Show($"An error happened:\n\n{ ex.Message }", "Reboot remote machine", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
//<-----------
}
{
string message = "";
const int ERROR_BAD_NETPATH = 53;
const int ERROR_SHUTDOWN_IN_PROGRESS = 1115;
const int RPC_S_UNKNOWN_IF = 1717;
switch (proc.ExitCode)
{
case 0:
if (!silent) MessageBox.Show($"Remote computer is rebooting ({ remoteHostNameOrIp }) in { waitSeconds } seconds.", "Reboot remote computer", MessageBoxButton.OK, MessageBoxImage.Information);
return true;
//<----------
case ERROR_BAD_NETPATH:
message = $"Remote computer not found ({ remoteHostNameOrIp })";
break;
case ERROR_SHUTDOWN_IN_PROGRESS:
message = $"A shutdown is already in progress ({ remoteHostNameOrIp })";
break;
case RPC_S_UNKNOWN_IF:
message = $"Remote computer does not accept shutdown. Probably it is currently booting. ({ remoteHostNameOrIp })";
break;
default:
message = $"Could not shut down - errorcode: { proc.ExitCode } ({ remoteHostNameOrIp })";
break;
}
if (!silent) MessageBox.Show($"{ message }", "Reboot remote computer", MessageBoxButton.OK, MessageBoxImage.Error);
return false;
}
}

Redirecting console output to a log file

I am working with the WMI API for c# in order to connect to a remote server and execute some commands. I have successfully established a connection. All I need now is to redirect the output of the remote CMD into a log file in my local machine.
Here is my code :
ConnectionOptions options = new ConnectionOptions();
options.Username = "login";
options.Password = "password";
ManagementScope scope = new ManagementScope("\\\\myserver\\root\\cimv2", options);
scope.Options.EnablePrivileges = true;
scope.Options.Impersonation = System.Management.ImpersonationLevel.Impersonate;
try
{
scope.Connect();
System.Management.ManagementClass local_ClassInstance = new System.Management.ManagementClass(scope, new System.Management.ManagementPath("Win32_Process"), null);
Console.WriteLine("SUCCESS");
//execute the command
System.Management.ManagementBaseObject local_InParams = local_ClassInstance.GetMethodParameters("Create");
local_InParams["CommandLine"] = #"cmd.exe /C myCommand";
local_InParams["CurrentDirectory"] = #"mypath";
System.Management.ManagementBaseObject local_ManagementBaseObject = local_ClassInstance.InvokeMethod("Create", local_InParams, null);
}
catch (Exception e)
{
Console.WriteLine("FAILURE"+e.ToString());
}
Edit
I tried to accomplish this by using the '>' primitive :
local_InParams["CommandLine"] = "command > log.txt";
But the output file that I created doesn't contain anything.
I tried also to do this using a process
Process myProcess = new Process();
myProcess.StartInfo.FileName = "ipconfig";
myProcess.StartInfo.Arguments = "/all";
myProcess.StartInfo.RedirectStandardOutput = true;
myProcess.StartInfo.UseShellExecute = false;
myProcess.Start();
myProcess.WaitForExit();
string myResult = myProcess.StandardOutput.ReadToEnd();
Console.WriteLine(myResult);
myProcess.Close();
But the process does not return the information that I want because I want the output of cmd of the remote machine (Because I want the log of the behaviour of the server while running the command).
Any Help please ?
I too had an issue with capturing, and found ANOTHER redirect that works similar to what you have...
myProcess.StartInfo.RedirectStandardError = true;
// trap normal data received AND any ERROR data received too
myProcess.OutputDataReceived += DOSOutputResultsHandler;
myProcess.ErrorDataReceived += DOSOutputErrorsHandler;
I also have two string builder properties for capturing the output responses on my class that does the DOS Call process
StringBuilder DOSOutputResults = new StringBuilder();
StringBuilder DOSOutputErrors = new StringBuilder();
protected void DOSOutputResultsHandler(object sendingProcess,
System.Diagnostics.DataReceivedEventArgs outLine)
{
if (!string.IsNullOrEmpty(outLine.Data))
// track data into the NORMAL output string builder
DOSOutputResults.Append(Environment.NewLine + outLine.Data);
}
protected void DOSOutputErrorsHandler(object sendingProcess,
System.Diagnostics.DataReceivedEventArgs outLine)
{
if (!String.IsNullOrEmpty(outLine.Data))
// track data into the ERROR output string builder
DOSOutputErrors.Append(Environment.NewLine + outLine.Data);
}
Additionally, for using the primitive ">" redirection, there is also a "2>" redirection that handles errors not redirected to normal output. I found this out when dealing with DOS calls to Java.

Starting a process on a remote machine c#

I am using the code below to start a process on a remote machine. It does start the process, but it is running under the Admin user instead of the current user that is logged in. I need the current user to be able to interact with the program. If I use their credential in my code instead of admin then I will get an access denied. How do I specify to run under user "JohnDoe" ? I know PSSuite is an option, but I would rather use the ManagementScope class if possible.
class Program
{
static void Main(string[] args)
{
try
{
object[] theProcessToRun = { "notepad.exe" };
ConnectionOptions theConnection = new ConnectionOptions();
theConnection.Username = #"MyDomain\Admin";
theConnection.Password = "mypassword";
ManagementScope theScope = new ManagementScope("\\\\" + "BMBM14" + "\\root\\cimv2", theConnection);
ManagementClass theClass = new ManagementClass(theScope, new ManagementPath("Win32_Process"), new ObjectGetOptions());
theClass.InvokeMethod("Create", theProcessToRun);
Console.WriteLine("Success");
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
Console.ReadLine();
}
Console.ReadLine();
}
}

Categories