Introduction
I have been doing some work recently that involves a lot of system setup for an installer I have been working on for installing a service. Part of this work involved creating shares. These are the methods I created to help in this activity. I did a lot of searching to create this code. I thought I would publish these methods to help others in the future so they don't have to do all the research.
There are the following methods:
ShareDirectory
: This includes arguments for the share name, path to the directory, a collection of users with permission types, and a description. DeleteShare
: Pass a name to this method to delete the share. GetShareNames
: Return an enumeration of string
s with the names of the shares.
There is also a class GrantSharePermissions
to help in adding permissions to the ShareDirectory
method. With the constructor of this class, you just have to pass the account name, and use an enumeration that will specify the access.
The Code
The following is a class to help maintain shares:
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Management;
namespace InstallApplication.Assets.StaticMethods
{
public class ShareDirectoryMethods
{
public static void ShareDirectory(string directoryPath, string shareName,
IEnumerable<GrantSharePermission> users = null, string description = null)
{
var grantString = (users != null && users.Any()) ? string.Join(" ", users) : string.Empty;
DeleteShare(shareName);
var executeString = string.Format("Share {0}={1} {2}", shareName,
directoryPath, grantString);
try
{
ProcessStartInfo processStartInfo = new ProcessStartInfo("NET", executeString);
processStartInfo.RedirectStandardOutput = true;
processStartInfo.RedirectStandardError = true;
processStartInfo.UseShellExecute = false;
Process process = new Process();
process.StartInfo = processStartInfo;
process.Start();
process.WaitForExit();
if (process.ExitCode == -1)
{
Logger.LogError(process.StandardOutput.ReadToEnd());
throw new Exception("Unable to share directory.");
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Could not create share \"{0}\" with path {1}",
shareName, directoryPath), ex);
}
}
public static void DeleteShare(string shareName)
{
try
{
using (ManagementClass shares = new ManagementClass("Win32_Share",
new ObjectGetOptions()))
{
foreach (var o in shares.GetInstances())
{
var share = (ManagementObject)o;
if (share["Name"].ToString() == shareName)
{
var outParams = share.InvokeMethod("delete", null, null);
}
}
}
}
catch (Exception ex)
{
throw new Exception(string.Format("Failed in deletion of a share"), ex);
}
+ shareName + "'", null))
}
public static IEnumerable<string> GetShareNames()
{
try
{
var items = new List<string>();
using (ManagementClass shares = new ManagementClass("Win32_Share",
new ObjectGetOptions()))
{
foreach (var o in shares.GetInstances())
{
var share = (ManagementObject)o;
items.Add(share["Name"].ToString());
}
return items;
}
}
catch (Exception ex)
{
throw new Exception("Failed to obtain shares", ex);
}
}
public class GrantSharePermission
{
private readonly string _userName;
private readonly ShareTypes _shareTypes;
public GrantSharePermission(string userName, ShareTypes shareTypes)
{
_userName = userName;
_shareTypes = shareTypes;
}
public override string ToString()
{
return string.Format("/GRANT:{0},{1}", _userName, _shareTypes.ToString().ToUpper());
}
}
public enum ShareTypes { Full, Read, Change }
}
}
Note
I originally tried to implement the creating of a share with the ManagementClass, but I had two problems: one was that share information was not showing up in the directory property share tab, and the other was figuring out how to set user permissions. I was pointed out in the comments that there was an implementation using the ManagementClass exclusively: http://www.harindaka.com/2011/11/having-to-write-piece-of-code-for-above.html#!/2011/11/having-to-write-piece-of-code-for-above.html. I have not testing how well this works with respect to but adding users, and seeing the share information in the property => share dialog for the directory being shared.
History
- 2018/06/27: Initial version