Click here to Skip to main content
15,867,453 members
Articles / Desktop Programming / Win32
Tip/Trick

Helper Methods for Working with Shares

Rate me:
Please Sign up or sign in to vote.
5.00/5 (5 votes)
27 Jun 2018CPOL1 min read 6.8K   13   4
These are some methods I created to help with creating and deleting Windows shared directories.

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 strings 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:

C#
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;

            //First ensure share does not exist
            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);
            }

            //using (ManagementObject o = new ManagementObject("Win32_Share.Name='"
			 + shareName + "'", null))
            //{
            //    ManagementBaseObject outParams = o.InvokeMethod("delete", null, null);
            //    return (int)(uint)(outParams.Properties["ReturnValue"].Value);
            //}
        }

        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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Clifford Nelson Consulting
United States United States
Has been working as a C# developer on contract for the last several years, including 3 years at Microsoft. Previously worked with Visual Basic and Microsoft Access VBA, and have developed code for Word, Excel and Outlook. Started working with WPF in 2007 when part of the Microsoft WPF team. For the last eight years has been working primarily as a senior WPF/C# and Silverlight/C# developer. Currently working as WPF developer with BioNano Genomics in San Diego, CA redesigning their UI for their camera system. he can be reached at qck1@hotmail.com.

Comments and Discussions

 
QuestionRedundancy in DeleteShare Pin
mottykohn28-Jun-18 7:40
mottykohn28-Jun-18 7:40 
Why is there a
shares.GetInstances();
before the
foreach (var o in shares.GetInstances())
loop?
AnswerRe: Redundancy in DeleteShare Pin
Clifford Nelson29-Jun-18 6:52
Clifford Nelson29-Jun-18 6:52 
SuggestionAlternative Pin
Sammuel Miranda28-Jun-18 2:16
professionalSammuel Miranda28-Jun-18 2:16 
AnswerRe: Alternative Pin
Clifford Nelson29-Jun-18 6:52
Clifford Nelson29-Jun-18 6:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.