I'm trying to disconnect network connections which are not mapped to a local drive (e.g. net use \server\share).
I know the command net use U: /D to delete a network connection which is mapped to U:.
Now I want to disconnect that connection using it's UNC Path (e.g. net use \server\ /D).
I want to implement this in a C# Application using the Windows Networking API (WNetCancelConnection-Function) but this function can't handle the UNC Path, too.
I receive all connected UNC Paths with the following code:
var searcher = new ManagementObjectSearcher(
"SELECT * FROM Win32_NetworkConnection");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine(queryObj["RemoteName"]);
Console.WriteLine(queryObj["RemotePath"]);
}
Console.ReadKey();
Hope so can help me solving that problem.
Edit:
i = WNetCancelConnection2A(ls_ShareName, iFlags, 1);
ls_ShareName = "\\server\share" (escaped)
iFlags = 0
results in: This network connection does not exist.
I'm 100% sure that my "shareName" is correct... also net use \server\share /D does not work.
Not sure where can be your problem without seeing your code. But after
net use \\192.168.1.45\ipc$
the following code
#include "windows.h"
void main(void){
WNetCancelConnection2("\\\\192.168.1.45\\ipc$",0,TRUE);
}
disconnects the resource without problems.
Related
NetworkInterface.GetAllNetworkInterfaces() doesn't return a complete list,
when I go to A network device, and using properties I disable internet protocol version 4(TCP/IPv4) check box, GetAllNetworkInterfaces stop recognizing the device.
I find this odd as although the device is not internet capable after this(we still may have IPv6 but for the sake of the argument) its still a network device
can someone explain this, or show how this can be solved?
After some time searching I found that a complete list can be accessed by using the following:
SelectQuery wmiQuery = new SelectQuery("SELECT * FROM Win32_NetworkAdapter");
ManagementObjectSearcher searchProcedure = new ManagementObjectSearcher(wmiQuery);
foreach (ManagementObject networkAdapter in searchProcedure.Get())
{
//here do whatever you want to do to the adapter
}
A more general description can be found at(not C# specific):
http://msdn.microsoft.com/en-us/library/aa394216(v=vs.85).aspx
Also in C# make sure to reference System.Management, or you wan't be able to use the code above
What's the best way to reset network connections using C#/.NET?
My company has several machines out with customers that connect by various means (3G, wifi, ethernet cable) and sometimes (especially with 3G) are reporting to Windows that they're still connected when they're not. I have a way to check if the connection is really live, but I'm struggling to reset them. Here's one problem:
var searcher = new ManagementObjectSearcher("select * from Win32_NetworkAdapter");
var managementObject = searcher.Get();
foreach (ManagementObject obj in managementObject)
{
var name = obj.Properties["Name"].Value.ToString();
Console.WriteLine(name);
obj.InvokeMethod("Disable", null);
obj.InvokeMethod("Enable", null);
}
As you can see, that will go through ALL network adapters and reset them, which I don't want to do. Furthermore, some adapters won't accept the null parameter.
I can get the NetworkInterface objects I want with this:
var interfaces = NetworkInterface.GetAllNetworkInterfaces().Where(ni => ni.IsReceiveOnly == false &&
ni.OperationalStatus == OperationalStatus.Up && ni.NetworkInterfaceType != NetworkInterfaceType.Loopback);
But the NetworkInterface class seems to have no Start(), Stop(), Reset() etc methods. Where do I go from here?
After some searching and experimentation, I found this blog post:
Disable/Enable Network Connections Under Vista
It is a much better approach.
The just of it, is to use a utility called mgmtclassgen.exe to generate a wrapper class around the WMI Win32_NetworkAdapter class. Use the following command in a developer command prompt at the folder of your choosing:
mgmtclassgen Win32_NetworkAdapter -p NetworkAdapter.cs
After you've generated NetworkAdapter.cs you can import it into a new project, add System.Management.dll to your project references, and use the following code to disable or enable an adapter of your choosing:
SelectQuery query = new SelectQuery("Win32_NetworkAdapter", "NetConnectionStatus=2");
ManagementObjectSearcher search = new ManagementObjectSearcher(query);
foreach(ManagementObject result in search.Get())
{
NetworkAdapter adapter = new NetworkAdapter(result);
// Identify the adapter you wish to disable here.
// In particular, check the AdapterType and
// Description properties.
// Here, we're selecting the LAN adapters.
if (adapter.AdapterType.Equals("Ethernet 802.3"))
{
adapter.Disable();
}
}
Also keep in mind, your program will have to be run as an administrator on any systems where UAC is enabled - to do this it is recommended to create an application manifest. You can do that by changing the requestedExecutionLevel entry in your manifest file to this:
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Might be a bit simplistic, but could you call ipconfig /renew from a new process?
Process.Start("ipconfig", "/renew");
Alternatively, this similar question talks about using netsh, which I guess you could call from a process too How to disable (or reset) a network adapter programmatically in C#
You need Win32 API :
GetExtendedTcpTable : Get all exists tcp connection.
SetTcpEntry : Change tcp connection state.
Example code:
MIB_TCPROW row = new MIB_TCPROW();
row.dwState = TcpState.DeleteTcb;
row.dwLocalAddr = ...;
row.dwLocalPort = ...;
row.dwRemoteAddr = ...;
row.dwRemotePort = ...;
SetTcpEntry(ref row);
I am currently developing an application in C# (.NET 4.0) that should have as a part of its functionality the ability to determine the percentage of fragmentation on a particular volume. All the other features have been tested and are working fine but I’ve hit a snag trying to access this data. I would ideally prefer to use WMI as this matches the format I’m using for the other features but at this point I’m willing to use anything that can be efficiently integrated into the application, even if I have to use RegEx to filter the data. I am currently doing the development on a Windows 7 Professional (x64) machine. I have tested the following Powershell snippet using Administrator rights and it works flawlessly.
$drive = Get-WmiObject -Class Win32_Volume -Namespace root\CIMV2 -ComputerName . | Where-Object { $_.DriveLetter -eq 'D:' }
$drive.DefragAnalysis().DefragAnalysis
This is the method I’m using in C# to accomplish the same thing, but the InvokeMethod keeps returning 11 (0xB).
public static Fragmentation GetVolumeFragmentationAnalysis(string drive)
{
//Fragmenation object initialization removed for simplicity
try
{
ConnectionOptions mgmtConnOptions = new ConnectionOptions { EnablePrivileges = true };
ManagementScope scope = new ManagementScope(new ManagementPath(string.Format(#"\\{0}\root\CIMV2", Environment.MachineName)), mgmtConnOptions);
ObjectQuery query = new ObjectQuery(string.Format(#"SELECT * FROM Win32_Volume WHERE Name = '{0}\\'", drive));
scope.Connect();
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
object[] outputArgs = new object[2];
foreach (ManagementObject moVolume in searcher.Get())
{
// Execution stops at this line as the result is always 11
UInt32 result = (UInt32)moVolume.InvokeMethod("DefragAnalysis", outputArgs);
if (result == 0)
{
Console.WriteLine("Defrag Needed: = {0}\n", outputArgs[0]);
ManagementBaseObject mboDefragAnalysis = outputArgs[1] as ManagementBaseObject;
if (null != mboDefragAnalysis)
{
Console.WriteLine(mboDefragAnalysis["TotalPercentFragmentation"].ToString());
}
}
else
{
Console.WriteLine("Return Code: = {0}", result);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("Could not acquire fragmentation data.\n" + ex);
}
return result;
}
I have even added the following line to the app.manifest but still nothing.
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
Could somebody please tell me what I’m overlooking? Failure is not an option for me on this, so if it cannot be done using C# I don’t mind creating a DLL in another language (even if I have to learn it), that will give me the results I need. Ideally the application should be able work on any OS from XP upwards and must be totally transparent to the user.
These are the resources I have already used. I wanted to add the jeffrey_wall blog on msdn as well but as a new user I can only add 2 hyperlinks at a time. Thanks again.
http://www.codeproject.com/Messages/2901324/Re-the-result-of-DefragAnalysis-method-in-csharp.aspx
http://social.technet.microsoft.com/Forums/vi-VN/winserverfiles/thread/9d56bfad-dcf5-4258-90cf-4ba9247200da
Try building your application targeting 'Any CPU' - on the Build tab of the project properties. I suspect you're using a target of x86. I get the same error code on my Win7 x64 machine if I do that.
In fact, running your PowerShell snippet in the x86 version of PowerShell gives an empty set of results, too.
You get the same error if you run either piece of code without full Administrator privileges, as you've found, so also ensure your app.manifest is correct. A UAC prompt is a handy hint that it's taking effect!
No idea why this WMI query doesn't like running under WoW64, I'm afraid, but hopefully this will give you a head-start.
You could simply call the PowerShell command you mentioned in your post, since you said the PowerShell code works. From C# you would want to follow this workflow:
Instantiate a PowerShell RunSpace
Open the RunSpace
Add a script to the Commands property
Invoke the command list
Here is an example of how to achieve this, and process the resulting object output.
http://www.codeproject.com/Articles/18229/How-to-run-PowerShell-scripts-from-C
For Windows XP and Windows Vista, you would have to ensure that PowerShell was installed on each of the systems you want to run your program on. Not a bad prerequisite to have, but something to keep in mind as a dependency.
Hope this helps.
The 32-bit WMI provider for Win32_Volume doesn't seem to be able to start the defragsvc for whatever reason. You can force the 64-bit WMI provider even in a 32-bit client running under WOW64 by changing your code to add an additional WMI connection option:
ConnectionOptions mgmtConnOptions = new ConnectionOptions {
EnablePrivileges = true,
Context = new ManagementNamedValueCollection() {
{ "__ProviderArchitecture", 64 }
}
};
Summary: is it possible to specify a port to use when querying WMI using System.Management;
I have a python script under Linux that queries, using WBEM, classes on a number of ESXi servers to check for warnings or errors on various subsystems. Previously, separately, I have written a WPF application that queries a number of WinTel boxes for their disk consumption etc. using WMI.
I am wanting to write a new WPF application that will perform the same function as the script and I thought I would be able to do this with WMI. Below is my testing code with the error handling removed for brevity, SetOptions is a private function that provides the username and password:
foreach (string hostname in Properties.Settings.Default.Hosts)
foreach (string WMIclass in Properties.Settings.Default.Classes)
{
ObjectQuery Query = new ObjectQuery("SELECT * FROM " + WMIclass);
ManagementObjectSearcher mos = GetMos(Query, hostname);
foreach (ManagementObject mo in mos.Get())
foreach (PropertyData pdc in mo.Properties)
Debug.WriteLine(pdc.Name + " \t\t: " + pdc.Value);
}
private ManagementObjectSearcher GetMos(ObjectQuery Query, string Hostname)
{
ConnectionOptions Options = SetOptions();
ManagementScope Scope = new ManagementScope("\\\\" + Hostname + "\\root\\cimv2", Options);
return new ManagementObjectSearcher(Scope, Query);
}
The trouble is I get a RPC unavailable on the remote server. I think that is because I am first trying to establish a RPC call on 135 which is not hosted by an ESX server. My question is how can one specify the port 5989 or is there something straightforward I can use in .net to perform what I need to do. Naively I'm thinking the class structure looks the same between WMI/WBEM surely it can be done :-/
System.Management can only be used to connect to other Windows machines running WMI, and doesn't support WBEM. The only C# WBEM client library I seen is http://code.google.com/p/wbemtools/, but it doesn't look very mature.
As said WMI Classes in .net don't support WBEM. In the end I ended up writing some code around the VMware.Vim.dll which has some good documentation on what I needed to do.
I'm creating a watch dog service that will be monitoring other services on various remote servers (all in the same domain). The user that I'm using to connect to the remote servers is not an admin. When I try to enumerate the services in the Win32_Service class, I get an access denied error.
I've given the user 'Remote Enable' & 'Enable Account' persmissions to the Root\CIMV2 namespace in the WMI Control.
I am able to connect to the server with the following code. The object ServiceListItem is just a simple class that contains the server name and the service name:
SecureString secureString = new SecureString();
foreach ( char c in "password" )
{
secureString.AppendChar( c );
}
ConnectionOptions connectionOptions = new ConnectionOptions();
connectionOptions.Username = "domain\\user";
connectionOptions.SecurePassword = secureString;
foreach ( ServiceListItem service in _serviceList )
{
ManagementScope managementScope = new ManagementScope();
managementScope = new ManagementScope( String.Format( #"\\{0}\root\cimv2", service.ServerName ), connectionOptions );
managementScope.Connect();
//RelatedObjectQuery relatedObjectQuery = new RelatedObjectQuery( String.Format( "Win32_Service.Name='{0}'", service.ServiceName ) );
//ManagementObjectSearcher objectSearcher = new ManagementObjectSearcher( managementScope, relatedObjectQuery );
ObjectQuery objectQuery = new ObjectQuery( "SELECT * FROM Win32_Service WHERE Name = '" + service.ServiceName + "'" );
ManagementObjectSearcher objectSearcher = new ManagementObjectSearcher( managementScope, objectQuery );
ManagementObjectCollection objectCollection = objectSearcher.Get();
foreach ( ManagementObject managementObject in objectCollection )
{
serviceStatus = managementObject.Properties["State"].Value.ToString();
Debug.Print(service.ServiceName + " - " + serviceStatus);
//break;
}
}
The managementScope.Connect() runs fine, which means the wmi security on cimv2 is set up correctly. However, when I try to enumerate the objectCollection, I get the 'Access Denied' exception. This tells me (I think) that the user doesn't have permissions to enumerate the Win32_Service class (SC_MANAGER_ENUMERATE_SERVICE).
I just haven't been able to find any good examples on how to enable that permission for a remote user. I'm not very experienced when it comes to coding with Windows api's, so please be as detailed as possible in your answers :)
Trying to find the same answer myself today, I've been doing a lot of googling. After a good half hour of incantations, I found this MSDN article (907460) which uses sc sdet. It seems to work so far, even though the security descriptor is for Windows Server 2003. I've found you can do sc sdshow SCMANAGER to get the current value so when back in the office tomorrow I'll be comparing an contrasting to make sure I've not locked something out I shouldn't have :-)
For completeness, the notes in KB907460 (in case it moves/goes away):
Symptoms: After you install Microsoft Windows Server 2003 Service Pack 1 (SP1), non-administrators cannot remotely access the Service Control Manager.
Cause: Windows Server 2003 SP1 changes the Service Control Manager default security settings.
Resolution:
To resolve this issue, use version 5.2.3790.1830 of the Sc.exe tool.
This tool is located in the %windir%\System32 folder. To do this,
follow these steps:
Click Start, click Run, type cmd, and then click OK.
Type the following command at the command prompt, and then press ENTER:
sc sdset SCMANAGER D:(A;;CCLCRPRC;;;AU)(A;;CCLCRPWPRC;;;SY)(A;;KA;;;BA)S:(AU;FA;KA;;;WD)(AU;OIIOFA;GA;;;WD)
I found myself stuck into a similar problem. In my case it had nothing to do with permissions, which I did set by following this link: http://www.poweradmin.com/help/enableWMI.aspx
So, After hours of wondering lost I found this article that tells how UAC interfere with your set of permissions and how can you fix that:
http://www.solarwinds.com/documentation/apm/docs/APMWMITroubleshooting.pdf
In my case, the registry key didn't existed, so I created it.
Hope this helps also, cheers!