9x系のフォルダ共有を解除するには?

解決


フムフム2  2003-08-06 17:31:01  No: 107994  IP: [192.*.*.*]

こんにちは、初めて投稿します。
一週間考えても探しても分からないので教えて下さい。
NT系(XP)のフォルダ共有を解除することはできたのですが、
9x系(98・ME)の解除の仕方が分かりません。
NTの宣言で「netapi32.dll」を「svrapi.dll」に変えてみたのですが、
当然ダメでした…。
どうかお分かりになる方、ご経験された方、教えて下さい。
どうぞよろしくお願い致します。m-v-m

Private Declare Function NetShareDel Lib "svrapi.dll" _
   (ByVal servername As String, _
   ByVal netname As String, _
   ByVal reserved As Long) As Long

Private Const NERR_Success = 0
'-----------------------------
Sub 9x系フォルダ共有解除()

    Dim strServerName         As String
    Dim strNetName            As String
    Dim lngReserved           As Long
    Dim lngWin32apiResultCode As Long

        strServerName = StrConv("", vbUnicode)
        strNetName = "ABC" & vbNullChar

        lngWin32apiResultCode = NetShareDel(strServerName, _
        strNetName, lngReserved)

    If lngWin32apiResultCode = NERR_Success Then
        MsgBox "フォルダの共有を解除しました。", vbInformation
    Else
        MsgBox "フォルダの共有を解除できません。", vbExclamation
    End If
    
End Sub

編集 削除
魔界の仮面弁士  2003-08-07 02:48:21  No: 107995  IP: [192.*.*.*]

> NTの宣言で「netapi32.dll」を「svrapi.dll」に変えてみたのですが、
> 当然ダメでした…。
あれれ? (SVRAPI.DLLの)NetShareDel でいけると思いますけれども。。。

現在、手元に9X系のOSを残していないので確認する事は出来ませんが、
3年ほど前に、下記メーリングリストの[VB-ML:04436]で回答した時には、
少なくとも、きちんと動作していましたから。。。(^_^;)
http://www.sfdata.jp/ML/menu.php?ml=VB-ML


> 当然ダメでした…。
…………まさかとは思いますが、
> Sub 9x系フォルダ共有解除()
の部分でエラーになっていたりはしませんよね?(^_^;)

数字から始まるプロシージャ名は宣言できないはずですので。。。

もし、実際のコードは数字から始めているわけでは無かったにしても、
日本語のプロシージャ名の使用は、避けておいた方が無難でしょう。
http://support.microsoft.com/default.aspx?scid=kb;ja;418924
》 Visual Basic では、プロジェクト、コントロール、フォーム モジュール、クラス
》 モジュール、標準モジュール、変数、定数、およびプロシージャの名前に
》 日本語の文字を使用することができません。 


>    strServerName = StrConv("", vbUnicode)
これは、strServerName = "" と同義です。(^^;)
空文字列なのであれば、StrConvする意味はありません。

また、VBの文字列変数は、通常、Unicodeとして扱われていますので、
それをさらに vbUnicode 変換すると、2重に文字コード変換が
行われてしまい、文字列の一部が化けてしまう可能性があります。
(ちなみに、逆方向のvbFromUnicode変換も、今回は不要です)


>  strNetName = "ABC" & vbNullChar
この部分が、実存する『共有名』であるかどうかを確認してみて下さい。
例えば、C:\ABC\ というフォルダを共有させていたとしても、
そのフォルダは『ABC』以外の名前で共有させている事があります。


>    If lngWin32apiResultCode = NERR_Success Then
>        MsgBox "フォルダの共有を解除しました。", vbInformation
>    Else
>        MsgBox "フォルダの共有を解除できません。", vbExclamation
>    End If
共有を解除できないとの事ですが、それは、NERR_Success が返されるのに、
実際には解除されていない、という事ですか?
それとも、NERR_Success以外の値が返されるという事ですか?

編集 削除
フムフム2  2003-08-12 22:56:44  No: 107996  IP: [192.*.*.*]

魔界の仮面弁士さん、ご丁寧なお返事有難う御座いました。mQm
無事、フォルダ共有解除できました!!
原因は、自分自身もよく分からないのですが、?_?
多分、上下のソースにも問題があったみたいです。
ただ、少し9x系とNT系の書き方が少し違うみたいなので書いときます。
今回の「strNetName」のところで
9x系だと「strNetName = "ABC" & vbNullChar」
NT系だと「strNetName = StrConv("ABC", vbUnicode)」
でした。どっちかに統一しようとするとエラーになってしまいます。
私の環境だけかな?
「strServerName = ""」は、お蔭様でこれでどちらもOKでした。
本当にありがとうございました。m__m

編集 削除
魔界の仮面弁士  2003-08-13 09:50:55  No: 107997  IP: [192.*.*.*]

# もう見てないかな…?


> 多分、上下のソースにも問題があったみたいです。
『上下』のソースとは、どういう意味でしょうか?

> ただ、少し9x系とNT系の書き方が少し違うみたいなので書いときます。
多くのAPIでは、9X系はANSI系のみ、NT系ではWide系とANSI系の両方のエントリが
用意されているため、通常は、ANSI系のエントリを宣言するのが一般的です。
(ANSI系を使えば、9X系とNT系の両方に対応できるため)

しかし、NetShareDel APIの場合は、そのような仕組みになっておらず、
NT系では、常にWide系のエントリを使用し、9X系ではANSI系のエントリを
使用しなければいけません。
そのため、この関数では 9x系とNT系で書き方が異なってしまうのです。


> strNetName = StrConv("ABC", vbUnicode)

NT系でこれでうまくいっているなら、その方が問題ですよ。(^^;
もしかして、NT系でも ByVal servername As String で宣言していませんか?

たまたま動いてしまう事もありますが、"ABC"はそれ自体がUnicodeですから、
さらに vbUnicode 指定で StrConv すれば、文字列の内容によっては、
元の文字列データが破壊されてしまう事がありえます。


Wide系の(つまり、Unicode文字列を扱う)APIの場合は、String型ではなく、
Byte型の配列を利用してください。この場合は文字コードの変換が
伴わないので、文字化けする心配があります。

この場合、Declare宣言では、ByVal As Stringの替わりに、
ByRef As Byte、ByRef As Any、ByVal As Long のいずれかを使います。

# なお、ByRef As Byteの場合は、(C言語でいうところの)NULLを渡す事ができないので、
# NetShareDel APIの第1引数のように、NULLを渡す必要がある時には向きません。


たとえば、ByVal As Long を利用する場合は、こんな感じです。

'NT系専用
Private Declare Function NetShareDel Lib "netapi32" _
   (ByVal lpServerName As Long, _
    ByVal lpNetName As Long, _
    ByVal reserved As Long) As Long

Private Sub Command1_Click()
    'Text1に共有名が書かれている物とする

    Dim NetName() As Byte
    Dim ret As Long
    NetName = Text1.Text & vbNullChar  '最後の vbNullCharを忘れずに!

    ret = NetShareDel(0&, VarPtr(NetName(0)), 0&)
End Sub



また、As Any を利用する場合はこんな感じです。

'NT系専用
Private Declare Function NetShareDel Lib "netapi32" _
   (ByRef lpServerName As Any, _
    ByRef lpNetName As Any, _
    ByVal reserved As Long) As Long

Private Sub Command1_Click()
    'Text1に共有名が書かれている物とする

    Dim NetName() As Byte
    Dim ret As Long
    NetName = Text1.Text & vbNullChar  '最後の vbNullCharを忘れずに!

    ret = NetShareDel(ByVal 0&, NetName(0), 0&)
End Sub

編集 削除
魔界の仮面弁士  2003-08-13 10:23:10  No: 107998  IP: [192.*.*.*]

上記回答への補足:

》 もしかして、NT系でも ByVal servername As String で宣言していませんか?
そして、第2引数の ByVal netname As String の方もですね。


》 Wide系の(つまり、Unicode文字列を扱う)APIの場合は、String型ではなく、
》 Byte型の配列を利用してください。この場合は文字コードの変換が
》 伴わないので、文字化けする心配があります。

えぇとこれは、Wide系APIをDeclareする時に、
    String型を使うと文字化けの心配がありますが、
    Byte配列を使えば、化ける事はありません
…という意味です。


ついでに、9X系の宣言例についても書いておきます。
(最初の回答に書いた、VB-MLの過去ログと、ほぼ同内容ですけど)

'9X系専用
Private Declare Function NetShareDel Lib "svrapi" _
  (ByVal servername As String, _
   ByVal netname As String, _
   ByVal reserved As Long) As Long

Private Sub Command1_Click()
    'Text1に共有名が書かれている物とする

    Dim strNetName As String
    Dim lngResult  As Long

    strNetName = Text1.Text & vbNullChar
    lngResult = NetShareDel(vbNullString, strNetName, 0&)
End Sub

編集 削除