C#で共有フォルダーを作成する

やり方

net shareコマンドを使う方法とWin32 Apiを使う方法がある。以下、MyNewShareという名前でC:\Shareを共有し、EveryoneにFull Controlを付与するサンプル。

なお、どちらの方法でも管理者権限が必要となる。

net shareコマンドを使う方法

ProcessStartInfo info = new ProcessStartInfo("net", @"share MyNewShare=C:\Share /grant:everyone,full");
info.CreateNoWindow = true;
Process.Start(info);

Win32 Apiを使う方法

// フォルダーの共有
ManagementClass share = new ManagementClass("Win32_Share");

ManagementBaseObject inParams = share.GetMethodParameters("Create");
inParams["Name"] = "MyNewShare";
inParams["Path"] = @"C:\Share";
inParams["Type"] = 0x0; // Disk Drive

ManagementBaseObject outParams = share.InvokeMethod("Create", inParams, null);
if ((uint)(outParams.Properties["ReturnValue"].Value) != 0)
{
    throw new Exception("フォルダーの共有に失敗しました。");
}

// 権限の設定
// Everyoneを選択
NTAccount ntAccount = new NTAccount("Everyone");

// SID取得
SecurityIdentifier userSID = (SecurityIdentifier)ntAccount.Translate(typeof(SecurityIdentifier));
byte[] utenteSIDArray = new byte[userSID.BinaryLength];
userSID.GetBinaryForm(utenteSIDArray, 0);

// Trustee
ManagementClass userTrustee = new ManagementClass("Win32_Trustee");
userTrustee["Name"] = "Everyone";
userTrustee["SID"] = utenteSIDArray;

// ACE
ManagementClass userACE = new ManagementClass("Win32_Ace");
userACE["AccessMask"] = 2032127; // Full access
userACE["AceFlags"] = AceFlags.ObjectInherit | AceFlags.ContainerInherit;
userACE["AceType"] = AceType.AccessAllowed;
userACE["Trustee"] = userTrustee;

// SecurityDescriptor
ManagementClass userSecurityDescriptor = new ManagementClass("Win32_SecurityDescriptor");
userSecurityDescriptor["ControlFlags"] = 4; // SE_DACL_PRESENT 
userSecurityDescriptor["DACL"] = new object[] { userACE };

// 共有フォルダーに権限をセット
ManagementObject myNewShare = new ManagementObject(share.Path + ".Name='MyNewShare'");
object result = myNewShare.InvokeMethod("SetShareInfo", new object[] { Int32.MaxValue, null, userSecurityDescriptor });
if ((uint)result != 0)
{
    throw new Exception("権限の設定に失敗しました。");
}

解説

net shareコマンドを使おう。

と言いたいところだが、もっと汎用的な作りにしたいのなら、引数を文字列で組み立てなければならないnet shareよりWin32 Apiのほうがいいかもしれない。また、権限の設定を省略するとEveryoneにRead権限のみが付与されるのだが、それでよければWin32 Apiでもかなりコードを短縮*1できる。

参考

social.msdn.microsoft.com

*1:"権限の設定"というコメント以降を省略できる