C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[10]: ネットワークパスのアクセス/存在確認


(過去ログ 11 を表示中)

[トピック内 15 記事 (1 - 15 表示)]  << 0 >>

■2412 / inTopicNo.1)  ネットワークパスのアクセス/存在確認
  
□投稿者/ asuka (8回)-(2007/04/06(Fri) 14:06:32)

分類:[C# (Windows)] 

お世話になっております。

PC AからPC Bの共有フォルダにアクセスしたいと考えております。

PC Bの共有フォルダが存在した場合、そこにファイルを書き出したいのですが、

存在チェックの仕方が分かりません。

PC Bには共有のsharedフォルダがあり、PC Aからエクスプローラでフルアクセス可能です。



ところが、C#のプログラムから存在確認をDirectory.Exists( Path )で実行すると、

falseが返ってきます。

Directory.Existsはネットワーク越しでは使えないのでしょうか?

使えない場合、他に方法はありますでしょうか?


ノートンなのでセキュリティプログラムはオフにして実行しています。



引用返信 編集キー/
■2414 / inTopicNo.2)  Re[1]: ネットワークパスのアクセス/存在確認
□投稿者/ Moo (51回)-(2007/04/06(Fri) 15:10:25)
Moo さんの Web サイト
適切なアクセス権があれば
Directory.Existsを使ってネットワークパスを確認することは出来ます

以下は参考にならないかもしれませんが...

DOSコマンドのCACLSあたりを使って
本当にアクセス権利があるかどうか確認することが出来ます。

実行例:

コマンド>cacls \\redmond07\seattle$\0312

\\redmond07\seattle$\0312 BUILTIN\Administrators:F
                          BUILTIN\Administrators:(OI)(CI)(IO)F
                          ...
                          Everyone:F

引用返信 編集キー/
■2417 / inTopicNo.3)  Re[2]: ネットワークパスのアクセス/存在確認
□投稿者/ HIRO (19回)-(2007/04/06(Fri) 16:24:21)
HIRO さんの Web サイト
僕はMooさんの仰る Directory.Exists を使用する方法で確認しています。
引用返信 編集キー/
■2426 / inTopicNo.4)  Re[3]: ネットワークパスのアクセス/存在確認
□投稿者/ ダッチ (119回)-(2007/04/06(Fri) 22:44:19)
MSDN には以下のように記載されています。

Directory.Exists メソッド
http://msdn2.microsoft.com/ja-jp/library/system.io.directory.exists(VS.80).aspx
> Exists メソッドは、ネットワーク認証を実行しません。事前に認証を行わずに既存のネットワーク共有を照会すると、Exists メソッドが false を返します。

このため、事前にネットワーク認証が行われていないため False が返ってきているのでしょう。
エクスプローラなどで一度認証してからだと True が返ってくると思います。

しかし認証をコードでやるにはどうするかといわれると、私にはわかりかねます。
引用返信 編集キー/
■2430 / inTopicNo.5)  Re[1]: ネットワークパスのアクセス/存在確認
□投稿者/ 渋木宏明(ひどり) (161回)-(2007/04/07(Sat) 03:23:50)
渋木宏明(ひどり) さんの Web サイト
> PC Bの共有フォルダが存在した場合、そこにファイルを書き出したいのですが、
> 存在チェックの仕方が分かりません。

もっとも確実なのは、その共有フォルダに接続してみることです。

.NET の標準クラスライブラリは共有フォルダへの接続をサポートしていないので、P/INVOKE で WNetAddConnection3() API を呼び出すことで共有フォルダに接続します。

引用返信 編集キー/
■2452 / inTopicNo.6)  Re[2]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (9回)-(2007/04/09(Mon) 11:08:45)
皆様御返答ありがとうございます。

大変助かっております。

しどろもどろ、たじろいでおりまして、いろいろ思考/施行している最中でございます。

やはり、どうも始めに接続してからでないとDirectory.Existsは使えないという結論に達しました。

現状、渋木様のおっしゃる通りAPIで直接接続接続してから、Directory.Existsの実行結果を確認してみるといった段階です。

本日中にはなんとか結果をお伝え出来ればと思います。

ありがとうございます。

引用返信 編集キー/
■2474 / inTopicNo.7)  Re[3]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (10回)-(2007/04/09(Mon) 19:15:44)

お世話になっております。asukaです。

結局本日中に終わらなかったわけですが、

渋木さんのおっしゃるとおり、WNetAddConnection2(サービスなので今回は2を使用することにしました。)

をDLLインポートしなければならないのかな?と思い、

[DllImport("mpr.DLL")]
public static extern uint
WNetAddConnection2(
 LPNETRESOURCE lpNetResource, // 接続の詳細
 StringBuilder lpPassword,  // パスワードの文字列
 StringBuilder lpUserName,  // ユーザー名の文字列
 uint dwFlags   // 接続オプション
);

としたところ、第一引数は構造体へのポインタですので、

当然C#ではコンパイルで怒られてしまいます。

LPNETRESOURCEの構造体はどのようにしてインポートすればよろしいでしょうか?

この構造体さえC#で使える形にすればWNetAddConnection2()が使えるのかな?

と思っているのですが、甘いでしょうか?^^;

引用返信 編集キー/
■2484 / inTopicNo.8)  Re[4]: ネットワークパスのアクセス/存在確認
□投稿者/ 渋木宏明(ひどり) (162回)-(2007/04/10(Tue) 00:39:56)
渋木宏明(ひどり) さんの Web サイト
> LPNETRESOURCEの構造体はどのようにしてインポートすればよろしいでしょうか?

SDK の定義を参考に C# のコードを書き起こします。

> この構造体さえC#で使える形にすればWNetAddConnection2()が使えるのかな?

でしょうね。

http://www.pinvoke.net/

とか見てないんですか?

あと、自分でガリガリ書かなくても、検索すれば WNetAddConnectionX() の使用事例は幾らでも見つかると思いますよ。

引用返信 編集キー/
■2493 / inTopicNo.9)  Re[5]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (11回)-(2007/04/10(Tue) 20:01:46)
WNetAddConnection2をC#で実装し、目的のサーバに接続するところまで確認致しました。

どころがその後もDirectory.Exists()はfalseを返します。

現状WNetAddConnection2で目的のサーバに接続しても、

そのサーバ内の共有フォルダにアクセス出来ない状況です。

WNetAddConnection2で接続してもDirectory.Exists()は使えないのではないか?

という結論に達しているのですが、他に確認するような項目はありますでしょうか?




PCAからPCBにWNetAddConnection2()でNO_ERRORが返ることを確認。

引数のサーバ名は[\\\\B]とし、成功しています。

共有フォルダは、

\\B\Shared\test

なのですが、Directory.Exists()に上記パスを入れても失敗します。

WNetAddConnection2()の構造体にて、dwTypeは〜_DISKを設定しています。

その他のメンバに共有フォルダアクセス用のフラグがありましたが、現在は0を指定しています。

これが原因かな?

と思ったのですが、プロジェクトを閉じてしまったので明後日以降に再トライしてみます。

VC++だと上手く行くのですが・・・




引用返信 編集キー/
■2495 / inTopicNo.10)  Re[6]: ネットワークパスのアクセス/存在確認
□投稿者/ 渋木宏明(ひどり) (163回)-(2007/04/10(Tue) 20:52:00)
渋木宏明(ひどり) さんの Web サイト
> どころがその後もDirectory.Exists()はfalseを返します。

中で何やってるんでしょうね?>Directory.Exists()

> 現状WNetAddConnection2で目的のサーバに接続しても、
> そのサーバ内の共有フォルダにアクセス出来ない状況です。

Directory.Exists() 以外も失敗するんですか?

> WNetAddConnection2で接続してもDirectory.Exists()は使えないのではないか?
> という結論に達しているのですが、他に確認するような項目はありますでしょうか?

Directory.Exitsts() 以外も失敗するのであれば、接続自体がうまくいってないのでは?

> \\B\Shared\test
>
> なのですが、Directory.Exists()に上記パスを入れても失敗します。

具体的にはどんなコードを書いていますか?
\ のエスケープを忘れていたりはしませんか?

> WNetAddConnection2()の構造体にて、dwTypeは〜_DISKを設定しています。
> その他のメンバに共有フォルダアクセス用のフラグがありましたが、現在は0を指定しています。
> これが原因かな?

かもしれません。

0を与えた根拠は何ですか?
SDK で定数値を確認して、然るべき値を入れるのがスジってもんです。

また、NETRESOURCE 構造体以外の引数には、何を与えていますか?

> VC++だと上手く行くのですが・・・

具体的にはどんなコードを書いていますか?
VC++ なら Directory.Exists() が期待通りの値を返すのですか?

引用返信 編集キー/
■2583 / inTopicNo.11)  Re[7]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (12回)-(2007/04/12(Thu) 14:29:10)

お世話になっております。asukaです。

>>現状WNetAddConnection2で目的のサーバに接続しても、
>>そのサーバ内の共有フォルダにアクセス出来ない状況です。
>
> Directory.Exists() 以外も失敗するんですか?

Directory.Exists( path )でfalseが返ってきて処理を中断していたのですが、

path = \\B\Shared\test\

に無理矢理ファイルを書込んでみたところ、

例外が発生し、『Access to the path "\\B\Shared\test\test.txt" is denied.

と、アクセスが拒否されている模様です。TT



>>WNetAddConnection2で接続してもDirectory.Exists()は使えないのではないか?
>>という結論に達しているのですが、他に確認するような項目はありますでしょうか?
>
> Directory.Exitsts() 以外も失敗するのであれば、接続自体がうまくいってないのでは?

WNetAddConnection2()は成功しており、不正なパスを指定したりするとそれなりのエラー番号が返ってきますので、このAPIは正常に動作していると思っております。



>>\\B\Shared\test
>>
>>なのですが、Directory.Exists()に上記パスを入れても失敗します。
>
> 具体的にはどんなコードを書いていますか?
> \ のエスケープを忘れていたりはしませんか?

すいません、『\\B\Shared\test\』で試しております。

>>WNetAddConnection2()の構造体にて、dwTypeは〜_DISKを設定しています。
>>その他のメンバに共有フォルダアクセス用のフラグがありましたが、現在は0を指定しています。
>>これが原因かな?
>
> かもしれません。
>
> 0を与えた根拠は何ですか?
> SDK で定数値を確認して、然るべき値を入れるのがスジってもんです。

NETRESOURCE構造体のdwDisplayTypeに、0からRESOURCEDISPLAYTYPE_SHAREに値を変えてみても駄目でした。



> また、NETRESOURCE 構造体以外の引数には、何を与えていますか?
>
>>VC++だと上手く行くのですが・・・
>
> 具体的にはどんなコードを書いていますか?
> VC++ なら Directory.Exists() が期待通りの値を返すのですか?

VC++の場合は、WNetAddConnection2で接続後、共有フォルダへの書込みに成功します。



ちょっとMooさんに教わったコマンドを実行した結果、

cacls \\B\Shared\test
\\B\Shared\test Everyone (OI)(CI)C
       <アカウント ドメインが見つかりません>F
       <アカウント ドメインが見つかりません>(OI)(CI)(IO)F

       NT AUTHORITY\SYSTEM:F
       NT AUTHORITY\SYSTEM:(OI)(CI)(IO)F
       BUILTIN\Administorators:F
       NT AUTHORITY\SYSTEM:(OI)(CI)(IO)F

と表示され、誰でも触れそうな雰囲気なのですが・・・

ちなみに共有フォルダはアカウント、パスワードなしでネットワーク接続していれば誰でもアクセス出来、

読み書き可能です・・・

なぜ拒否されてしまうのでしょうか?

サービスプログラムだからでしょうか?

万策つきてしまいました、何か手立てがあれば御教授お願い致します。

引用返信 編集キー/
■2587 / inTopicNo.12)  Re[8]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (13回)-(2007/04/12(Thu) 14:48:50)

度々すいません。

asukaです。

NETRESOURCE構造体をクラスにした一部です。

こんなことやってます、、、

namespace WNetAddConnectionX
{
 public enum ResourceScope
 {
  RESOURCE_CONNECTED = 1,
  RESOURCE_GLOBALNET,
  RESOURCE_REMEMBERED,
  RESOURCE_RECENT,
  RESOURCE_CONTEXT
 };

 public enum ResourceType
 {
  RESOURCETYPE_ANY,
  RESOURCETYPE_DISK,
  RESOURCETYPE_PRINT,
  RESOURCETYPE_RESERVED
 };

 public enum ResourceUsage
 {
  RESOURCEUSAGE_CONNECTABLE = 0x00000001,
  RESOURCEUSAGE_CONTAINER = 0x00000002,
  RESOURCEUSAGE_NOLOCALDEVICE = 0x00000004,
  RESOURCEUSAGE_SIBLING = 0x00000008,
  RESOURCEUSAGE_ATTACHED = 0x00000010,
  RESOURCEUSAGE_ALL =
  (RESOURCEUSAGE_CONNECTABLE | RESOURCEUSAGE_CONTAINER | RESOURCEUSAGE_ATTACHED),
 };

 public enum ResourceDisplayType
 {
  RESOURCEDISPLAYTYPE_GENERIC,
  RESOURCEDISPLAYTYPE_DOMAIN,
  RESOURCEDISPLAYTYPE_SERVER,
  RESOURCEDISPLAYTYPE_SHARE,
  RESOURCEDISPLAYTYPE_FILE,
  RESOURCEDISPLAYTYPE_GROUP,
  RESOURCEDISPLAYTYPE_NETWORK,
  RESOURCEDISPLAYTYPE_ROOT,
  RESOURCEDISPLAYTYPE_SHAREADMIN,
  RESOURCEDISPLAYTYPE_DIRECTORY,
  RESOURCEDISPLAYTYPE_TREE,
  RESOURCEDISPLAYTYPE_NDSCONTAINER
 };

 public class IWNetCon
 {
  enum ErrorCodes
  {
   NO_ERROR = 0,
   // Error codes from error.h
   ERROR_ACCESS_DENIED = 5,
   ERROR_ALREADY_ASSIGNED = 85,
   ERROR_INVALID_PASSWORD = 86,
   // Error codes from winerror.h
   ERROR_BAD_NETPATH = 53,
   ERROR_BAD_DEV_TYPE = 66,
   ERROR_BAD_NET_NAME = 67,
   ERROR_BUSY = 170,
   ERROR_INVALID_ADDRESS = 487,
   ERROR_BAD_DEVICE = 1200,
   ERROR_DEVICE_ALREADY_REMEMBERED = 1202,
   ERROR_NO_NET_OR_BAD_PATH = 1203,
   ERROR_BAD_PROVIDER = 1204,
   ERROR_CANNOT_OPEN_PROFILE = 1205,
   ERROR_BAD_PROFILE = 1206,
   ERROR_EXTENDED_ERROR = 1208,
   ERROR_NO_NETWORK = 1222,
   ERROR_CANCELLED = 1223,
   ERROR_NOT_CONNECTED = 2250,
   ERROR_DEVICE_IN_USE = 2404,
  };

  [StructLayout(LayoutKind.Sequential)]
  private class NETRESOURCE
  {
   public ResourceScope dwScope = 0;
   public ResourceType dwType = ResourceType.RESOURCETYPE_DISK;
   //public ResourceDisplayType dwDisplayType = 0;
   public ResourceDisplayType dwDisplayType = ResourceDisplayType.RESOURCEDISPLAYTYPE_SHARE;
   public ResourceUsage dwUsage = 0;
   public string lpLocalName = null;
   public string lpRemoteName = "\\\\B";
   public string lpComment = null;
   public string lpProvider = null;
  };

・・・

引用返信 編集キー/
■2594 / inTopicNo.13)  Re[8]: ネットワークパスのアクセス/存在確認
□投稿者/ 渋木宏明(ひどり) (166回)-(2007/04/12(Thu) 15:22:40)
渋木宏明(ひどり) さんの Web サイト
> サービスプログラムだからでしょうか?

そうです。

そんなこと1度も書いてないですよね?
まぁ、よくあることですが ;-p

Windows サービスの実行に良く使われる Local System アカウントには、ネットワーク資源への接続権限がありません。

Windows サービスでネットワーク資源にアクセスする必要がある場合、「ネットワーク資源にアクセスする必要がある Windows サービスを実行するための専用アカウント(=必要最低限の権限に絞込み、余分な処理は許さない)」を作成して、そのアカウントでサービスを実行するのが一般的な解決策です。


引用返信 編集キー/
■2620 / inTopicNo.14)  Re[9]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (14回)-(2007/04/12(Thu) 17:00:22)

お世話になっております。asukaです。

>>サービスプログラムだからでしょうか?
>
> そうです。

ぐはっ…

> そんなこと1度も書いてないですよね?
> まぁ、よくあることですが ;-p

はい、記載しませんでした。

すいません、、、

> Windows サービスの実行に良く使われる Local System アカウントには、ネットワーク資源への接続権限がありません。
>
> Windows サービスでネットワーク資源にアクセスする必要がある場合、「ネットワーク資源にアクセスする必要がある Windows サービスを実行するための専用アカウント(=必要最低限の権限に絞込み、余分な処理は許さない)」を作成して、そのアカウントでサービスを実行するのが一般的な解決策です。

『サービス側からではどう頑張ってもアクセス出来ない。』

と解釈致しました。

WindowsXP Proで動作させているのですが、

[管理ツール]からtestというユーザを作成し、

Administoratorsと、

Network Configuration Operators
(ネットワークにアクセス出来るっぽいグループだったので)

のグループをtestユーザに含ませました。



作成したWindowsサービスのプロパティの[ログオン]タブにて、

[ローカルシステム システム アカウント]から[アカウント]に変更し、

testユーザを選択し、パスワードを空にして実行すると『ログオンに失敗しました。』と警告されます。

サービスにログオンという概念がよく分からないのですが、

サービスに作成したアカウントユーザがログオン出来るとして、

そのアカウントとパスワードというのはどこで持てばよいのでしょうか?

無知ですいません・・・TT



C#で作成しているWindowsサービスのソース内で設定する箇所があるのでしょうか?

InitializeComponent()で何か設定出来るのかと、this.でメンバ関数やらメソッドやらを探してみたのですがそれらしきものが見当たりませんでした・・・

もう少しヒントを頂けると幸いです。


引用返信 編集キー/
■2634 / inTopicNo.15)  Re[10]: ネットワークパスのアクセス/存在確認
□投稿者/ asuka (15回)-(2007/04/12(Thu) 17:56:50)

asukaです。



う、うごきました、すいません。

訳の分からない世迷言をほざいておりました。

[管理ツール]からユーザを作成し、AdministoratorsやNetwork…のグループを付加することなく、

単なるデフォルトのUsersのまま、パスワードを設定しておきます。

サービスのプロパティでアカウントを作成したユーザにし、設定したパスワードを入力することで

ネットワーク上の共有フォルダに書き込むことが出来ました。TT

皆様ありがとうございます。



ともあれ、本番では共有フォルダがsambaの共有フォルダになるのでまたまた一山ありそうですが・・・

とりあえず解決致しました。

感謝多謝でございます。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -