Skip to content

Instantly share code, notes, and snippets.

@223n 223n/DirSize.cs
Created May 24, 2017

Embed
What would you like to do?
指定したサーバー上の共有フォルダを探して、共有フォルダ内のサイズを探すC#コード
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace DirSize
{
internal class NetShare
{
const int NERR_Success = 0;
const uint MAX_PREFERRED_LENGTH = 0xFFFFFFFF;
/// <summary>
/// The SHARE_INFO_1 structure contains information about the shared resource, including the name and type of the resource, and a comment associated with the resource.
/// </summary>
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SHARE_INFO_1
{
/// <summary>
/// Pointer to a Unicode string specifying the share name of a resource. Calls to the NetShareSetInfo function ignore this member.
/// </summary>
public string shi1_netname;
/// <summary>
/// A bitmask of flags that specify the type of the shared resource. Calls to the NetShareSetInfo function ignore this member.
/// </summary>
public uint shi1_type;
/// <summary>
/// Pointer to a Unicode string specifying an optional comment about the shared resource.
/// </summary>
public string shi1_remark;
public SHARE_INFO_1(string sharename, uint sharetype, string remark)
{
shi1_netname = sharename;
shi1_type = sharetype;
shi1_remark = remark;
}
public override string ToString() { return shi1_netname; }
}
/// <summary>
/// サーバ上の共有ファイル一覧を取得。
/// </summary>
/// <param name="Server">対象サーバ。</param>
/// <returns></returns>
public static List<SHARE_INFO_1> GetNetShares(string server)
{
int entriesread;
IntPtr bufPtr = GetBufPtr(server, out entriesread);
try
{
return GetShareInfos(bufPtr, entriesread);
}
finally
{
NativeMethods.NetApiBufferFree(bufPtr);
}
}
private static List<SHARE_INFO_1> GetShareInfos(IntPtr bufPtr, int entriesread)
{
IntPtr currentPtr = bufPtr;
List<SHARE_INFO_1> shareInfos = new List<SHARE_INFO_1>();
int nStructSize = Marshal.SizeOf(typeof(SHARE_INFO_1));
for (int i = 0; i < entriesread; i++)
{
SHARE_INFO_1 shi1 = (SHARE_INFO_1)Marshal.PtrToStructure(currentPtr, typeof(SHARE_INFO_1));
shareInfos.Add(shi1);
currentPtr = new IntPtr(currentPtr.ToInt32() + nStructSize);
}
return shareInfos;
}
private static IntPtr GetBufPtr(string server, out int entriesread)
{
int totalentries;
int resume_handle = 0;
IntPtr bufPtr = IntPtr.Zero;
int result = NativeMethods.NetShareEnum(
new StringBuilder(server), NativeMethods.DataInformationLevel.Level1, ref bufPtr
, MAX_PREFERRED_LENGTH, out entriesread, out totalentries, ref resume_handle
);
if (result != NERR_Success)
{
throw new Win32Exception(result);
}
return bufPtr;
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace DirSize
{
internal static class NativeMethods
{
public enum DataInformationLevel
{
/// <summary>
/// 共有の名前を取得します。関数から制御が返ると、bufptr パラメータが指すバッファに、複数の 構造体からなる 1 つの配列が格納されます。
/// </summary>
Level0 = 0,
/// <summary>
/// リソースの名前、タイプ、リソースに関連付けられているコメントなど、共有リソースに関する情報を取得します。
/// 関数から制御が返ると、bufptr パラメータが指すバッファに、複数の 構造体からなる 1 つの配列が格納されます。
/// </summary>
Level1 = 1,
/// <summary>
/// リソースの名前、タイプ、アクセス許可、パスワード、接続の数など、共有リソースに関する情報を取得します。関数から制御が返ると、bufptr パラメータが指すバッファに、複数の 構造体からなる 1 つの配列が格納されます。
/// </summary>
Level2 = 2,
/// <summary>
/// リソースの名前、タイプ、アクセス許可、接続の数、他の固有情報など、共有リソースに関する情報を取得します。関数から制御が返ると、bufptr パラメータが指すバッファに、複数の 構造体からなる 1 つの配列が格納されます。
/// </summary>
Level502 = 502,
}
/// <summary>
/// 特定のサーバー上の各共有資源に関する情報を取得します。Windows 95/98 では使用できません。
/// </summary>
/// <param name="ServerName">この関数を実行するリモートサーバーの名前を表す、Unicode 文字列へのポインタを指定します。この文字列の先頭は "\\" でなければなりません。このパラメータで NULL を指定すると、ローカルコンピュータが使われます。</param>
/// <param name="level">データの情報レベルを指定します。次の値のいずれかを指定します。</param>
/// <param name="bufPtr">1 個のバッファへのポインタを指定します。関数から制御が返ると、このバッファに、指定したデータが格納されます。このデータの形式は、level パラメータの値によって異なります。このバッファはシステムによって割り当てられたものであり、NetApiBufferFree 関数を使って解放しなければなりません。この関数が失敗して ERROR_MORE_DATA が返った場合でも、このバッファを解放しなければならないことに注意してください。</param>
/// <param name="prefmaxlen">取得するべきデータの最大の長さ(上限)をバイト単位で指定します。このパラメータが MAX_PREFERRED_LENGTH の場合、この関数はデータが必要とする量のメモリを割り当てます。このパラメータで他の値を指定すると、その値は、この関数が返すバイト数に制限を加えることがあります。バッファサイズが不足して一部のエントリを格納できない場合は、ERROR_MORE_DATA が返ります。詳細については、MSDN ライブラリの「Network Management Function Buffers」と「Network Management Function Buffer Lengths」を参照してください。</param>
/// <param name="entriesread">1 つの DWORD 値へのポインタを指定します。関数から制御が返ると、この値に、実際に列挙された要素の数が格納されます。</param>
/// <param name="totalentries">1 つの DWORD 値へのポインタを指定します。関数から制御が返ると、この値に、現在のレジューム位置以降で列挙できるはずのエントリの総数が格納されます。</param>
/// <param name="resume_handle">引き続き既存の共有を検索するために使われるレジュームハンドルを保持している、1 つの DWORD 値へのポインタを指定します。このハンドルは最初の呼び出しのときに 0 であるべきで、それ以降の呼び出しでも変更しないでください。resume_handle パラメータで NULL を指定すると、レジュームハンドルは格納されません。</param>
/// <returns>関数が成功すると、NERR_Success が返ります。関数が失敗すると、Win32 API のエラーコードが返ります。エラーコードのリストについては、MSDN ライブラリの「System Error Codes」を参照してください。</returns>
/// <remarks>特定の共有が、DFS ルート内の DFS リンクであるかどうかを示す値を取得するには、情報レベル 1005 を指定して NetShareGetInfo 関数を呼び出してください。</remarks>
[DllImport("Netapi32.dll", CharSet = CharSet.Unicode)]
public static extern int NetShareEnum(
StringBuilder serverName,
DataInformationLevel level,
ref IntPtr bufPtr,
uint prefmaxlen,
out int entriesread,
out int totalentries,
ref int resume_handle
);
/// <summary>
/// NetApiBufferAllocate が割り当てたメモリを解放します。Windows NT/2000 上で他のネットワーク管理関数が返したメモリを解放するには、この関数を使ってください。
/// </summary>
/// <param name="Buffer">既に他のネットワーク管理関数が返したバッファへのポインタを指定します。</param>
/// <returns>関数が成功すると、NERR_Success が返ります。</returns>
[DllImport("Netapi32.dll", SetLastError = true)]
public static extern int NetApiBufferFree(IntPtr Buffer);
}
}
@223n

This comment has been minimized.

Copy link
Owner Author

223n commented May 25, 2017

Programs.csが漏れてる...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.