- PR -

VB-Script と VB からの Object の扱いって違うの?

投稿者投稿内容
わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2007-05-02 12:48
いつもお世話になっております。

さて、適切なタイトルがつけれなくて申し訳ないのですが、
現在、Internet Connection Firewall の設定を vb. net からしたいと
思っています。

どうにも、Internet Connection Firewall の設定を手動でやっていたために、
設定のもれていた機械がありまして、それを自動で設定したいと考えています。

ICF で、MSDN を検索したところ、vbs でのサンプルがありましたので、そこから
いろいろやってみて、そこそこ期待どおりの動きにはなりました。

しかしながら、次のような、ユーザからすると意味不明なメッセージが
ダイアログとして表示されてしまい、なかなかいい気持ちがしません。

>c:\windows\system32\cscript.exe は、このコンピュータのインターネット
>接続の保護設定を変更または、表示しようとしています。(以下略)

そこで、vbs の中身を vb で作ればいいかと思い、コードを作ってみたのですが、
どうにも、うまくいきませんでした。具体的には、EnumEveryConnection で取得される
Connection の個数が違うのです。

vbs では、
コード:
Main( )

sub Main( )
    DIM NetSharingManager
    set NetSharingManager = Wscript.CreateObject("HNetCfg.HNetShare.1")
    Dim Connection
    set Connection = NetSharingManager.EnumEveryConnection
    WScript.Echo( "C:" & CStr(Connection.Count) )
end sub



と実行すると、「5」が表示されます。

しかし、vb で、
コード:
    NetSharingManager = CreateObject("HNetCfg.HNetShare.1")
    Dim Connection = NetSharingManager.EnumEveryConnection
    Console.WriteLine( "C:" & CStr(Connection.Count))



と、実行すると、「1」が表示されてしまいます。

そこで、教えていただければと思っている事なのですが、、、

1.そもそも、vbs のコードを VB に移植してもうまく動かない事がある
 もんなんでしょうか?.

2.CreateObject は、あまり好きでないので、いっそ API を
 直接呼び出そうとも思うのですが、Internet Connectin Firewall を始め、
 最近の API では、Windows の C++ ヘッダファイルを見ると class で
 定義されているものが、あります。このような API 群は、VB で
 declare などできるのでしょうか?

よろしくお願いいたします。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-05-02 15:21
こんばんは。

引用:

わちゃさんの書き込み (2007-05-02 12:48) より:
1.そもそも、vbs のコードを VB に移植してもうまく動かない事がある
 もんなんでしょうか?.



VBScriptコードをVB6以前に移植する場合は、ほとんどそのままで大丈夫だと思いますが、
VBScriptコードをVB.NETに移植する場合には、根本的な動作原理が異なるので注意が必要です。

VBScriptやVB6のObjectとは、いわゆるCOM(Component Object Model)オブジェクト(というかIDispatchインターフェイス)のことでしたが、
VB.NETのObjectはCOMオブジェクトであるとは限りません。

引用:

2.CreateObject は、あまり好きでないので、いっそ API を
 直接呼び出そうとも思うのですが、Internet Connectin Firewall を始め、
 最近の API では、Windows の C++ ヘッダファイルを見ると class で
 定義されているものが、あります。このような API 群は、VB で
 declare などできるのでしょうか?



おっしゃられているC/C++ヘッダファイルで定義されているclassとは、COMインターフェイスのことだと思います。
COMインターフェイスはDeclare文では呼び出すことができません。

わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2007-05-02 17:07
Tdnr_Sym 殿

どうも、回答ありがとうございます。

なんか、どうにもならん感じですね、、、、

COM っていうと、なんとなくリソースの管理とか、
ややこしそうな気がしてやめていたのですが、
とりあえず、ちょっといろいろとみてみたいと
思います。

昔は、BIOS と I/O 関係の本を2〜3冊読んだら、
なんでもできた感じでしたが、だんだんややこしく
なっていきますね、、、、

ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2007-05-02 17:17
引用:

Tdnr_Symさんの書き込み (2007-05-02 15:21) より:
おっしゃられているC/C++ヘッダファイルで定義されているclassとは、COMインターフェイスのことだと思います。
COMインターフェイスはDeclare文では呼び出すことができません。



ですけど、COM を扱う関数(CoCreateInstance, DispCallFunc, etc)を呼び出すことはできるので、ゴリゴリやればできちゃいます。
ただ、めちゃくちゃ面倒でしょう。
_________________
unibon
ぬし
会議室デビュー日: 2002/08/22
投稿数: 1532
お住まい・勤務地: 美人谷        良回答(20pt)
投稿日時: 2007-05-02 17:58
引用:

わちゃさんの書き込み (2007-05-02 12:48) より:
vbs では、
コード:
Main( )

sub Main( )
    DIM NetSharingManager
    set NetSharingManager = Wscript.CreateObject("HNetCfg.HNetShare.1")
    Dim Connection
    set Connection = NetSharingManager.EnumEveryConnection
    WScript.Echo( "C:" & CStr(Connection.Count) )
end sub



と実行すると、「5」が表示されます。


良くは知りませんが、
set NetSharingManager = Wscript.CreateObject("HNetCfg.HNetShare.1")
の部分は
set NetSharingManager = CreateObject("HNetCfg.HNetShare.1")
のほうが、VB.NET のほうのコードと近いのではないでしょうか。

あと、環境の相似度は VBScript --- VB(VB5 や VB6) --- VB.NET(VB2005) だと思いますので、いきなり VBScript と VB.NET と比較するよりも、いったん、VB(VB5 や VB6) も交えて検証するという手もあるかもしれません。
Tdnr_Sym
ぬし
会議室デビュー日: 2005/09/13
投稿数: 464
お住まい・勤務地: 明石・神戸
投稿日時: 2007-05-02 18:27
こんにちは。

引用:

ちゃっぴさんの書き込み (2007-05-02 17:17) より:
ですけど、COM を扱う関数(CoCreateInstance, DispCallFunc, etc)を呼び出すことはできるので、ゴリゴリやればできちゃいます。
ただ、めちゃくちゃ面倒でしょう。



ヘルパー関数があること忘れてました^^;
面倒ですができなくもなさそうですね。
ご指摘ありがとうございます。


CreateObjectを使うのが嫌であれば
「NetCon Type Library」を参照追加してこんな感じではどうですか?

コード:
Dim netSharingManager As New NETCONLib.NetSharingManager

Dim connection As NETCONLib.INetSharingEveryConnectionCollection
connection = netSharingManager.EnumEveryConnection
Console.WriteLine("C:" & CStr(connection.Count))

System.Runtime.InteropServices.Marshal.ReleaseComObject(connection)
System.Runtime.InteropServices.Marshal.ReleaseComObject(netSharingManager)



#例外処理は省いてます
わちゃ
大ベテラン
会議室デビュー日: 2005/12/05
投稿数: 162
お住まい・勤務地: 東京
投稿日時: 2007-05-02 19:04
ちゃっぴさん、unibon さん、Tdnr_Sym さん、どうもありがとうございます。

とりあえず、pinvoke.net を見ながら、ole32.dll の API をひたすら
追加していたとこでした。
# 正直、先を考えて、ちょっと思いやられているとこでした。

で、こんな、単純なスクリプトでなんで、結果が変わるんだろうと
思いつつ、いただきましたコメントをもとにいろいろとやってみました。

で、ちょっと違うマシンに移動して、やってみました。

前と同じVB .Net の exe
 結果は、2

前と同じVBScript
 結果は、7

unibon さんのおっしゃるように、WScript を除いた VBScript
 結果は、7

VB6 がなかったので、Excel2007-VBA
 結果は、2

NetCon Type Library を参照したところ、
 結果は、2

ん〜。やっぱ、謎です。

[ メッセージ編集済み 編集者: わちゃ 編集日時 2007-05-02 19:08 ]
ちゃっぴ
ぬし
会議室デビュー日: 2004/12/10
投稿数: 873
投稿日時: 2007-05-02 20:45
VBA と VBS で試してみましたけど変化しますねぇ。。。

となるとやはり、VBS はすべて Variant で受けるというのが影響しているような気が。。。

INetSharingEveryConnectionCollection::get_Count

何だろこれ。long* で受けるのが VB の Long ?

ちなみに collection を loop でまわして count すると VBS の値が正しいようですね。
ざっとみたところ、この library 自体 legacy の VB で積極的に扱うようにできていないようなので別の方法模索したほうがいいかもしれません。
_________________

スキルアップ/キャリアアップ(JOB@IT)