Windows Network Information Manipulation - c#

I am working as a trainee engineer in a networking firm and am getting annoyed by having to change the IP information from time to time.
I am in need of building a software to help me change these details easily. I have managed to set the IP information. But I still have problems.
I need to run the program as Administrator [right click], is there a way to program to prompt for it at startup?
How can I change adapter to DHCP?
The code is quite long, and I hope not to fill bore you with it. But I have been using Management
Management Class
Management Base Object
Management Object Collection in my development.
I'd prefer to make my own program to develop my programming skills. But if there is an application to do it, I don't mind knowing.

I hope this answer gives you some insisght and direction to go.
Okay, the network adapter one isn't that straight forward, but I believe you can achieve it with WMI, specially this WMI object here. The MSDN documentation tells you all the properties, methods (which there are for setting DHCP etc) and the datatypes and values it takes. This may be one approach as using WMI through C# is pretty easy. I wish I could provide you an example, but I've never used that specific WMI class before. You can also access the above WMI class through the Visual Studio Server Explorer, which you can see here. ..and it has your "EnableDHCP" method you are probably looking for.
As far as asking for your program to run with administrative priviledges, here is the code from my setup project in my framework. What this does is before it runs any sort of form or logic, requests the "runas" verb which invokes UAC (if Windows has its Vista/7, and requests admin priviledges from the user)
namespace Setup {
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using Setup.Forms;
using System.Security.Principal;
using System.Diagnostics;
static class Program {
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
WindowsPrincipal principal = new WindowsPrincipal(WindowsIdentity.GetCurrent());
bool administrativeMode = principal.IsInRole(WindowsBuiltInRole.Administrator);
if (!administrativeMode) {
ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.Verb = "runas";
startInfo.FileName = Application.ExecutablePath;
try {
Process.Start(startInfo);
}
catch {
return;
}
return;
}
Application.Run(new ShellForm());
}
}
}
As far as a program to do it, Windows Network Connection Manager? I know its cumbersome because of all the dialogs, but.. its already there.

I once had to write a very similar program. I used some of the source code from these two projects to help me get started: Chameleon Project and Configuring TCP/IP Settings using WMI and C#
The Chameleon Project is a C# project to help change network settings of a particular adapter. The other project is a tutorial on how to use C# to change network settings using WMI and C#. You can look at the source code and learn from it to help you make your own software that does what you need.

Related

Can I delete files from "Windows" folder in Windows Server 2016 using C# (MVC or Core)?

In windows server 2016, I create a text file inside "Windows" folder for some reasons, and in special cases I need to delete it from my website which is built in C# MVC, is there any way to do that using C# (MVC or Core)? I know that it is illogical but I need that if applicable.
The answer for your solution is fairly simple, yes it is indeed possible to remove a Windows file or folder. However, this is costly! Allowing an application to have Administrator permissions can lead to malicious behaviors. Such as UAC Bypassing from other malware.
All you need to do in order to delete that file programming using C# is to first off run your application with administrator rights. Here's source the code for it:
using System;
using System.IO;
public class Program {
public static void Main() {
String myPath = #"<DRIVE_LETTER>:\Windows\<FILENAME>"; // E.g: #"C:\Windows\MyText.txt";
try{ // For stability purposes,
File.Delete(myPath);
} catch (IOException ERROR){ // If any errors occurs, it will print it out!
Console.WriteLine(ERROR.Message);
}
}
}
Documentation for Permission(s) Risks: Risks of Admin Rights
Documentation for File.Delete: File.Delete(String) Method C#

Mount Network Drive with WMI

Trying to write a WMI class function to mount a network drive on any computer (remote or local) using the credentials of the logged in computer.
This is a class for a larger project that I wrote for help desk staff to do first line fixes on remote PC's. The tech types in the the machine name or ip address and the app connects to it and allows to tech to click a couple of buttons and fix some basic items without having to remote(VNC) into the PC.
I've read all over the internet that it is much easier ways than WMI, but due to the remote nature of the app I would rather not use local API calls, nor do I want to worry about uploading script and executing it though a process start. Also other functions are already in WMI so I'd like to keep the code base the same.
The basic idea is to mount H: to //fileserver.example.com/$username
NetFixer is already in production use so I'm trying to keep my code nice and neat
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management;
namespace WMIcontrols
{
public class Remote
{
public string target;
//Some code skipped here for simplicity sake...
public bool MountNetDrive(string DriveLetter, string MountLocation)
{
try
{
//Mount the network drive
return true;
}
catch
{
//Mount Failed
return false;
}
}
}
}
This is not using WMI but will accomplish what you want and is very simple
System.Diagnostics.Process.Start("cmd", "/c net use x: \\fileserver.example.com /user:Username Password");

Get Windows Service Description ASP .NET

I'm writing a service monitoring ASP .NET app and I'm having issues particularly with getting the service descriptions. My current method (reading from registry) is not going to work due to registry read permissions on the production server.
For example:
Microsoft.Win32.RegistryKey system, currentControlSet, services, service;
system = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System");
currentControlSet = system.OpenSubKey("CurrentControlSet");
services = currentControlSet.OpenSubKey("Services");
service = services.OpenSubKey(scTemp.ServiceName, true);
row["service_description"] = service.GetValue("Description");
Produces:
System.Security.SecurityException: Requested registry access is not allowed.
My question is:
Is there a work-around with another .NET class (maybe under System.ServiceProcess namespace?) or will it always end with a security exception error?
I have no issues getting Service names and states with the System.ServiceProcess namespace but I can't find any classes contained to get descriptions which is why I resorted to reading from registry.
I think this should work.
EDIT: I should read questions closer. The code below gets the description for the first service in the array.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ServiceProcess;
using System.Management;
namespace ServiceNames
{
class Program
{
static void Main(string[] args)
{
ServiceController[] services = ServiceController.GetServices();
string serviceName = services[0].ServiceName;
string objPath = string.Format("Win32_Service.Name='{0}'", serviceName);
using (ManagementObject service = new ManagementObject(new ManagementPath(objPath)))
{
Console.WriteLine(service["Description"]);
}
Console.Read();
}
}
}
The previous answer showing the WMI solution is a good alternative and worth trying first.
--
I am not aware of a .NET Framework class that exposes the service description.
The first thing I would consider is requiring authenticated connections (e.g. NTLM) and impersonate the caller. As long as you don't do a double-hop (i.e. make a remote call with your impersonated credentials) you may find that you are able to successfully make the registery read.
If that is not possible then making a P/Invoke call may work.
If the credentials your web service has the SERVICE_QUERY_CONFIG permission you could do the following:
Find the service you are interested in using the ServiceController class
Using the ServiceHandle property make a P/Invoke call to QueryServiceConfig2 using the SERVICE_CONFIG_DESCRIPTION info level passing in null for the buffer and 0 for the lenght, reading the required buffer length from pcbBytesNeeded.
Allocate the proper buffer length and call QueryServiceConfig2 a second time getting the service description.
Obviously reading from the registery is a little more straight-forward (and in the end the permissions issues may be similar in both cases) - but using a supported API seems like a less fragile solution.
Side question: is there something you are trying to accomplish that PerfMon and logging can't tell you?

How to elevate privileges only when required?

This question applies to Windows Vista!
I have an application which normally works without administrative privileges. There is one activity which does need administrative privilege but I don't want to start the application itself with higher privileges when I know most of time user wont even be using that feature.
I am thinking about certain method by which I can elevate the privileges of application on some event (such as press of a button). Example:
If user clicks this button then he is prompted with UAC dialog or consent. How can I do this?
I don't believe that it is possible to elevate the currently running process. It is built into Windows Vista that administrator privileges are given to a process upon startup, as I understand. If you look at various programs that utilise UAC, you should see that they actually launch a separate process each time an administrative action needs to be performed (Task Manager is one, Paint.NET is another, the latter being a .NET application in fact).
The typical solution to this problem is to specify command line arguments when launching an elevated process (abatishchev's suggestion is one way to do this), so that the launched process knows only to display a certain dialog box, and then quit after this action has been completed. Thus it should hardly be noticeable to the user that a new process has been launched and then exited, and would rather appear as if a new dialog box within the same app has been opened (especially if you some hackery to make the main window of the elevated process a child of the parent process). If you don't need UI for the elevated access, even better.
For a full discussion of UAC on Vista, I recommend you see this very through article on the subject (code examples are in C++, but I suspect you'll need to use the WinAPI and P/Invoke to do most of the things in C# anyway). Hopefully you now at least see the right approach to take, though designing a UAC compliant program is far from trivial...
As it was said there:
Process.StartInfo.UseShellExecute = true;
Process.StartInfo.Verb = "runas";
will run the process as admin to do whatever you need with the registry, but return to your app with the normal privileges.
The following MSDN KB article 981778 describes how to 'self-elevate' an application:
http://support.microsoft.com/kb/981778
It contains downloadable samples in Visual C++, Visual C#, Visual Basic.NET.
This approach gets around the need to start a separate process, but in fact it is the original application that is restarted, running as an elevated user. Nevertheless this may still be very useful in some contexts where it is not practical to duplicate code in a separate executable.
To remove the elevation, you need to quit the application.
You need a UAC moniker and the code to run elevated as a COM object.
See this question.
Documentation on MSDN.
Perhaps someone comes in handy this simple example:
using System;
using System.Linq;
using System.Reflection;
using System.Diagnostics;
using System.Security.Principal;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
internal static class Program
{
private class Form1 : Form
{
internal Form1()
{
var button = new Button{ Dock = DockStyle.Fill };
button.Click += (sender, args) => RunAsAdmin();
Controls.Add(button);
ElevatedAction();
}
}
[STAThread]
internal static void Main(string[] arguments)
{
if (arguments?.Contains("/run_elevated_action") == true)
{
ElevatedAction();
return;
}
Application.Run(new Form1());
}
private static void RunAsAdmin()
{
var path = Assembly.GetExecutingAssembly().Location;
using (var process = Process.Start(new ProcessStartInfo(path, "/run_elevated_action")
{
Verb = "runas"
}))
{
process?.WaitForExit();
}
}
private static void ElevatedAction()
{
MessageBox.Show($#"IsElevated: {IsElevated()}");
}
private static bool IsElevated()
{
using (var identity = WindowsIdentity.GetCurrent())
{
var principal = new WindowsPrincipal(identity);
return principal.IsInRole(WindowsBuiltInRole.Administrator);
}
}
}
}
I know this is an old post, but this is in response to anyone else who comes across MarcP's suggestion. The msdn post he referenced indeed does restart the applications in all of the code examples. The code samples use the runas verb proposed already in other suggestions.
I downloaded the code to make sure, but this is from the original msdn article:
4. Click Yes to approve the elevation. Then, the original application
restarts, running as an elevated administrator.
5. Close the application.

C# file creation - how to grant IUSR DELETE?

I've got a console program written in C# which runs under user foo. The program creates a file. In some situations a web application running under the IUSR needs to be able to delete the files created by the console app.
I'd like to grant DELETE (or anything equivalent) to IUSR when the file is created. How can I do that in C# ?
I've found FileIOPermission and I'm not sure what that's for but as you can't specify a particular user I'm pretty sure that's now what I need.
Anyone got a good pointer on how to do this ?
[By the way I realise that in some circs granting the IUSR DELETE rights on any files would be a reasonably dodgy thing to do but in this case the nature of the files involved means I'm happy to grant these rights to IUSR]
#Sabau: thanks for the amendment to your answer - it inspired me to try again and this time I seem to have got it worked out. I wrote a little test program so that others can see how it's done. For my testing I gave the IUSR full control but obviously you can add/deny whatever you like.
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Security.Permissions;
using System.Security.Principal;
using System.Security.AccessControl;
namespace GrantingFilePermsTests
{
class Program
{
static void Main(string[] args)
{
string strFilePath1 = "E:/1.txt";
string strFilePath2 = "E:/2.txt";
if (File.Exists(strFilePath1))
{
File.Delete(strFilePath1);
}
if (File.Exists(strFilePath2))
{
File.Delete(strFilePath2);
}
File.Create(strFilePath1);
File.Create(strFilePath2);
// Get a FileSecurity object that represents the
// current security settings.
FileSecurity fSecurity = File.GetAccessControl(strFilePath1);
// Add the FileSystemAccessRule to the security settings.
fSecurity.AddAccessRule(new FileSystemAccessRule("IUSR_SOMESERVER",FileSystemRights.FullControl,AccessControlType.Allow));
// Set the new access settings.
File.SetAccessControl(strFilePath1, fSecurity);
}
}
}
Thanks to all for their replies.
Use the Windows Explorer -> select the directory where the file resides -> right-click -> Properties -> Security tab -> give the "Modify" right to the IUSR_xxx user account.
I presume that you have physical access to the computer that runs both the console app and the web app.
Edited: for programmatic setting of ntfs permissions you need to fiddle around with the System.Security.AccessControl.FileSecurity class and the File.SetAccessControl method.
Hope it helps.
A quick google search produced Setting NTFS Permissions with C#

Categories

Resources