内容
C#で共有フォルダを作成するプログラムを作成したいと思っています。
以下のネット情報を参考にそのまま実装したところAccessViolationExceptionが発生し、共有フォルダ作成に失敗してしまいます。
http://niyodiary.cocolog-nifty.com/blog/2009/08/c-3e14.html
例外が発生する原因や回避策について何かご存じの人いましたら、お手数ですが教えていただけないでしょうか?
環境
- OS:Windows10
- フレームワーク:.NET Framework 3.5
試したこと
fnShareAddメソッドには以下の引数を設定しているのですが、3つの環境で実行し、どの環境でも同様の例外が発生してしまいます。
- サーバ名:null
- 共有名:"share"
※共有名は重複していません
- 最大接続数:10
- コメント:""
- パス:"C:"
※他のパスを設定しても例外は発生します
- パスワード:""
NetShareAddメソッドの引数は上記URLと同様のものを設定しています。
調べたこと
以下のNetShareAddに関するMSDNは確認したのですが、例外についての記載はありませんでした。
https://docs.microsoft.com/en-us/windows/win32/api/lmshare/nf-lmshare-netshareadd
また、AccessViolationExceptionについても調べたのですが、アンマネージコードで割り当てられていないメモリにアクセスしているから例外が発生していると解釈したのですが、対処としてどのようにすればよいかわかりませんでした。
https://docs.microsoft.com/ja-jp/dotnet/api/system.accessviolationexception?view=net-5.0
ソースコード(文字数オーバーのためコメントは一部消しています)
ShareFolderManager.cs
1 2using System; 3using System.Runtime.InteropServices; 4 5namespace ShareFolderSample 6{ 7 public static class ShareFolderManager 8 { 9 private const short STYPE_DISKETREE = 0; 10 private const int NERR_Success = 0; 11 /// <summary> 12 /// ユーザーには、要求した情報へのアクセス権がありません。 13 /// <summary> 14 private const int ERROR_ACCESS_DENIED = 5; 15 /// <summary> 16 /// level パラメータで指定した値が無効です。 17 /// <summary> 18 private const int ERROR_INVALID_LEVEL = 124; 19 /// <summary> 20 /// 文字またはファイルシステム名が無効です。 21 /// <summary> 22 private const int ERROR_INVALID_NAME = 123; 23 /// <summary> 24 /// 指定されたパラメータは無効です。 25 /// <summary> 26 private const int ERROR_INVALID_PARAMETER = 87; 27 /// <summary> 28 /// 指定した共有名は、既にこのサーバーで使われています。 29 /// <summary> 30 private const int NERR_DuplicateShare = 2118; 31 /// <summary> 32 /// リダイレクトされたリソースに対して、この操作は無効です。指定されたデバイス名は、 33 /// 共有リソースに割り当てられています。 34 /// <summary> 35 private const int NERR_RedirectedPath = 2117; 36 /// <summary> 37 /// デバイスまたはディレクトリが存在しません。 38 /// <summary> 39 private const int NERR_UnknownDevDir = 2116; 40 /// <summary> 41 /// 利用可能なメモリが不足しています。 42 /// <summary> 43 private const int ERROR_NOT_ENOUGH_MEMORY = 8; 44 /// <summary> 45 /// 指定された共有名が存在しません。 46 /// <summary> 47 private const int NERR_NetNameNotFound = 2310; 48 49 private struct SHARE_INFO_2 50 { 51 public int shi2_netname; 52 /// <summary> 53 /// 共有タイプ 54 /// </summary> 55 public int shi2_type; 56 /// <summary> 57 /// コメント 58 /// </summary> 59 public int shi2_remark; 60 /// <summary> 61 /// パーミッション 62 /// </summary> 63 public int shi2_permissions; 64 /// <summary> 65 /// 最大接続数 66 /// </summary> 67 public int shi2_max_uses; 68 /// <summary> 69 /// ? 70 /// </summary> 71 public int shi2_current_uses; 72 /// <summary> 73 /// 共有フォルダの絶対パス 74 /// </summary> 75 public int shi2_path; 76 /// <summary> 77 /// パスワード 78 /// </summary> 79 public int shi2_passwd; 80 81 private SHARE_INFO_2( 82 int shi2_netname, int shi2_type, int shi2_remark, int shi2_permissions, 83 int shi2_max_uses, int shi2_current_uses, int shi2_path, int shi2_passwd) 84 { 85 // VisualStudio2008でビルド警告を防ぐためだけに設定している 86 // この初期化処理は全く意味がない 87 this.shi2_netname = 0; // 文字列:null 88 this.shi2_type = 0; // 数値:0 89 this.shi2_remark = 0; // 文字列:null 90 this.shi2_permissions = 0; // 数値:0 91 this.shi2_max_uses = 0; // 数値:0 92 this.shi2_current_uses = 0; // 数値:0 93 this.shi2_path = 0; // 文字列:null 94 this.shi2_passwd = 0; // 文字列:null 95 } 96 } 97 [DllImport("Netapi32.dll", CharSet = CharSet.Unicode)] 98 private static extern int NetShareAdd( 99 string servername, int level, ref SHARE_INFO_2 buf, ref int parm_err); 100 101 [DllImport("Netapi32.dll", CharSet = CharSet.Unicode)] 102 private static extern int NetShareDel(string servername, string netname, int reserved); 103 104 public static void fnShareAdd( 105 string sServerName, string sShareName, int iMaxUses, string sComment, 106 string sPhysicsFolderPath, string sPassword) 107 { 108 SHARE_INFO_2 si2; 109 //------------------------------------------------------------------------------------- 110 // 共有フォルダの設定 111 //------------------------------------------------------------------------------------- 112 // 共有名 113 GCHandle gchNetName = GCHandle.Alloc(sShareName, GCHandleType.Pinned); 114 si2.shi2_netname = gchNetName.AddrOfPinnedObject().ToInt32(); 115 // 共有タイプ 116 si2.shi2_type = STYPE_DISKETREE; 117 // コメント 118 GCHandle gchNetRemark = GCHandle.Alloc(sComment, GCHandleType.Pinned); 119 si2.shi2_remark = gchNetRemark.AddrOfPinnedObject().ToInt32(); 120 // パーミッション 121 si2.shi2_permissions = 0; 122 // 最大接続数 123 si2.shi2_max_uses = iMaxUses; 124 // ? 125 si2.shi2_current_uses = 0; 126 // 共有フォルダパス 127 GCHandle gchPath = GCHandle.Alloc(sPhysicsFolderPath, GCHandleType.Pinned); 128 si2.shi2_path = gchPath.AddrOfPinnedObject().ToInt32(); 129 // パスワード 130 GCHandle gchPassword = GCHandle.Alloc(sPassword, GCHandleType.Pinned); 131 si2.shi2_passwd = gchPassword.AddrOfPinnedObject().ToInt32(); 132 //------------------------------------------------------------------------------------- 133 // 共有フォルダ作成 134 //------------------------------------------------------------------------------------- 135 int iParamErr = 0; 136 // 第二引数はSHARE_INFO_2構造体を使うことを示している(らしい) 137 int iResult = NetShareAdd(sServerName, 2, ref si2, ref iParamErr); 138 //------------------------------------------------------------------------------------- 139 // GCHandle解放 140 //------------------------------------------------------------------------------------- 141 gchNetName.Free(); 142 gchNetRemark.Free(); 143 gchPath.Free(); 144 gchPassword.Free(); 145 //------------------------------------------------------------------------------------- 146 // 戻り値判定 147 //------------------------------------------------------------------------------------- 148 switch (iResult) 149 { 150 case NERR_Success: 151 return; 152 case ERROR_ACCESS_DENIED: 153 throw new SystemException( 154 "ユーザーには、要求した情報へのアクセス権がありません。"); 155 case ERROR_INVALID_LEVEL: 156 throw new SystemException("level パラメータで指定した値が無効です。"); 157 case ERROR_INVALID_NAME: 158 throw new SystemException("文字またはファイルシステム名が無効です。"); 159 case ERROR_INVALID_PARAMETER: 160 throw new SystemException("指定されたパラメータは無効です。"); 161 case NERR_DuplicateShare: 162 throw new SystemException( 163 "指定した共有名は、既にこのサーバーで使われています。"); 164 case NERR_RedirectedPath: 165 throw new SystemException( 166 "リダイレクトされたリソースに対して、この操作は無効です。" + 167 "指定されたデバイス名は、共有リソースに割り当てられています。"); 168 case NERR_UnknownDevDir: 169 throw new SystemException("デバイスまたはディレクトリが存在しません。 "); 170 default: 171 string sMsg = string.Format( 172 "不明なエラー。NetShareAdd戻り値:{0}、iParamErr:{1}", 173 iResult, iParamErr); 174 throw new SystemException(sMsg); 175 } 176 } 177 public static void fnShareDel(string sServerName, string sShareName) 178 { 179 //------------------------------------------------------------------------------------- 180 // 共有フォルダ削除 181 //------------------------------------------------------------------------------------- 182 int iResult = NetShareDel(sServerName, sShareName, 0); 183 //------------------------------------------------------------------------------------- 184 // 戻り値判定 185 //------------------------------------------------------------------------------------- 186 switch (iResult) 187 { 188 case NERR_Success: 189 return; 190 case ERROR_ACCESS_DENIED: 191 throw new SystemException( 192 "ユーザーには、要求した情報へのアクセス権がありません。"); 193 case ERROR_INVALID_PARAMETER: 194 throw new SystemException("指定されたパラメータは無効です。"); 195 case ERROR_NOT_ENOUGH_MEMORY: 196 throw new SystemException("利用可能なメモリが不足しています。"); 197 case NERR_NetNameNotFound: 198 throw new SystemException("指定された共有名が存在しません。"); 199 default: 200 string sMsg = string.Format( 201 "不明なエラー。NetShareDel戻り値:{0}", iResult); 202 throw new SystemException(sMsg); 203 } 204 } 205 } 206} 207
回答1件
あなたの回答
tips
プレビュー