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

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

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

Re[14]: VBSからVB内のメソッド処理を行う


(過去ログ 140 を表示中)

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

■82132 / inTopicNo.1)  VBSからVB内のメソッド処理を行う
  
□投稿者/ hama (1回)-(2016/12/13(Tue) 13:49:00)

分類:[VB.NET/VB2005 以降] 

VBSから、VBのメソッドを起動したいのですが、
「ActiveXコンポーネントはオブジェクトを作成できません。」が表示されて止まります。
元々は、html内のVBコード(ASPでしょうか?)ですが、動かないので、VBSに切り出しました。

---test.vbs---
msgbox "VBS起動"
set obj = createObject("LVE01000.clsLVE01001")

msgbox "VBメソッド起動"
obj.Proc1()

msgbox "VBS終了"
--------------

---LVE01000.exeソース---
Module LVE01001
Sub Main()
MsgBox("VB起動")
End Sub

End Module

Public Class LVE01000
Sub Proc1()
MsgBox("Proc1起動")
End Sub
End Class
-----------------------

※あらかじめ、ActiveXのレジストリ登録はしてあります。
C:\test\LVE01000.exe /REGSERVER

test.vbsを起動して、"VBS起動"、"VB起動"が表示後、
30秒ほどして、「ActiveXコンポーネントはオブジェクトを作成できません。」が表示されて止まります。
元はVB6で動いている処理のVB.net化(2015)をしています。
元の作成者は居ないので、聞くことが出来ない状態です。
よろしくお願いします。

引用返信 編集キー/
■82136 / inTopicNo.2)  Re[1]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1012回)-(2016/12/13(Tue) 15:07:31)
No82132 (hama さん) に返信
> 元々は、html内のVBコード(ASPでしょうか?)ですが、
HTML 系だとすると、スクリプティングホストとしては
*.html(IE)、*.asp(IIS+asp.dll)、*.hta(mshta.exe)、あるいは
*.htc、*.wsc あたりですかね。大穴で MSScriptControl とか。


> 「ActiveXコンポーネントはオブジェクトを作成できません。」が表示されて止まります。
VB.NET 側が x86 ビルドなら、VBScript のホストも
32bit である必要がありますし、x64 ビルドであるのなら、
VBScript 側も 64bit である必要がありますが、その点は大丈夫でしょうか。
(ASP にしても WSH にしても、32bit版と64bit版があります)


> set obj = createObject("LVE01000.clsLVE01001")
この ProgID がレジストリに登録されていることは確認済みでしょうか?


> ---LVE01000.exeソース---
ActiveX EXE としたいわけですね。

恐らく AssemlyInfo.vb で定義済みとは思いますが、
ComVisibleAttribute はどうされていますか?

それと、ProgIdAttribute や ClassInterfaceAttribute も
明示しておいた方が良いですよ。



> ※あらかじめ、ActiveXのレジストリ登録はしてあります。
> C:\test\LVE01000.exe /REGSERVER
これは VB6 の場合ですよね。

VB.NET なら、Visual Studio による自動登録に任せるか、
実行環境なら RegAsm を使う方法で対処してみてください。
(もしくは、Sub Main でコマンドラインオプションを解析して
 登録/解除の処理を実装するとか)

ユーザー配布を行うのなら、登録用のインストーラーを用意することも検討を。
引用返信 編集キー/
■82139 / inTopicNo.3)  Re[2]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1013回)-(2016/12/13(Tue) 16:08:37)
No82136 (魔界の仮面弁士) に追記
> 恐らく AssemlyInfo.vb で定義済みとは思いますが、
> ComVisibleAttribute はどうされていますか?
> それと、ProgIdAttribute や ClassInterfaceAttribute も
> 明示しておいた方が良いですよ。

以下サンプル。

ClassInterfaceType を AutoDual にすればもっと簡潔になりますが
メンバーの順番さえ変えられなくなりますし、
バイナリ互換性が保ちにくいので(テスト段階だと特に)、
ここでは None にして、インターフェイスも明示指定しています。


下記サンプルでは、コマンドラインから手動でビルドしていますが、
もちろん Visual Studio でコンパイルしても問題ありません。


'====== C:\temp\test.vb ======
Imports System.Runtime.InteropServices
<Assembly: Guid("7b3bd800-c5c6-431a-aa7b-7d99efc1b701")>
<Assembly: ComVisible(True)>

Module LVE01001
 '下記の GUID は一例。既に登録済みの LVE01000 がある場合は、
 '下記をそのまま使うのではなく、既存の GUID を使うなどします。
 Public Const CLSID_LVE01000 As String = "AA08B048-FF40-4865-B2AF-87F6AC164C3E"
 Public Const IID_ILVE01000 As String = "F690FA83-9EA6-40B0-A8EF-2B27886DB9B9"
 Public Const PROGID_ILVE01000 As String = "LVE01000.clsLVE01001"
 Sub Main()
  MsgBox("VB起動")
 End Sub
End Module

<CoClass(GetType(LVE01000))> _
<Guid(IID_ILVE01000)> _
Public Interface ILVE01000
 Sub Proc1()
End Interface

<ProgId("LVE01000.clsLVE01001")> _
<Guid(CLSID_LVE01000)> _
<ClassInterface(ClassInterfaceType.None)> _
Public Class LVE01000
 Implements ILVE01000
 Public Sub New()
  MsgBox("LVE01000生成")
 End Sub

 Public Sub Proc1() Implements ILVE01000.Proc1
  MsgBox("Proc1起動")
 End Sub
End Class


'====== コマンドライン ======
'レジストリ登録を伴うので、管理者コマンドプロンプトを使ってください
vbc.exe C:\temp\test.vb /out:C:\temp\test.exe /target:winexe

ECHO exe をパスの通った位置に配置
COPY C:\temp\test.exe %WINDIR%\system32\test.exe

REM RegAsm.exe C:\temp\test.exe /regfile:C:\temp\test.reg
REM RegAsm.exe C:\temp\test.exe /tlb:C:\temp\test.tlb
RegAsm.exe C:\temp\test.exe

ECHO 起動実験
%WINDIR%\system32\WScript.exe C:\temp\test.vbs



もし、VB6 同様に "/RegServer" や "/UnRegServer" をサポートしたい場合は、
Sub Main の中でコマンドラインを判定し、RegAsm で出力したレジストリ情報を
登録するためのコードを書けば何とかなるかも。
引用返信 編集キー/
■82141 / inTopicNo.4)  Re[2]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (2回)-(2016/12/13(Tue) 16:18:47)
魔界の仮面弁士さん、返信ありがとうございます。

開発環境がネットに繋げない為、別PCで伺っております。
ご面倒お掛けします。

@VB.NET 側が x86 ビルドなら、VBScript のホストも
>32bit である必要がありますし、x64 ビルドであるのなら、
>VBScript 側も 64bit である必要がありますが、その点は大丈夫でしょうか。
>(ASP にしても WSH にしても、32bit版と64bit版があります)
ソリューションプラットフォームでしょうか?
現在Any CPUとなっています。

A> set obj = createObject("LVE01000.clsLVE01001")
>この ProgID がレジストリに登録されていることは確認済みでしょうか?
レジストリに何か設定が必要なのでしょうか?

B恐らく AssemlyInfo.vb で定義済みとは思いますが、
>ComVisibleAttribute はどうされていますか?
すいません、ComVisibleAttributeが???です。

Cそれと、ProgIdAttribute や ClassInterfaceAttribute も
>明示しておいた方が良いですよ。
すいません、ProgIdAttribute、ClassInterfaceAttributeが???です。

D> ※あらかじめ、ActiveXのレジストリ登録はしてあります。
> C:\test\LVE01000.exe /REGSERVER
>これは VB6 の場合ですよね。
いいえ、レジストリ登録しないと、VB起動も出来ない為、今回(.net)用です。

EVB.NET なら、Visual Studio による自動登録に任せるか、
>実行環境なら RegAsm を使う方法で対処してみてください。
>(もしくは、Sub Main でコマンドラインオプションを解析して
> 登録/解除の処理を実装するとか)
すいませんRegAsmが???です。

Fユーザー配布を行うのなら、登録用のインストーラーを用意することも検討を。
今の所、特定ユーザーのみで使用予定なので、インストローラーは考えて無いです。

【その他】
"VB起動"のメッセージまでは表示されるので、VBは起動している様です。
引用返信 編集キー/
■82142 / inTopicNo.5)  Re[3]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (3回)-(2016/12/13(Tue) 16:22:22)
魔界の仮面弁士さん、お世話になります。
82139を読む前に、返信してしまい、内容が前後してしまいました、すいません。
今から、確認します。
引用返信 編集キー/
■82144 / inTopicNo.6)  Re[4]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (5回)-(2016/12/13(Tue) 17:20:48)
No82142 (hama さん) に返信
魔界の仮面弁士さん、お世話になります。

今まで、VBAをメインでやっていたのですが、知らない用語が多数出て来て、
混乱しております。

今回の処理はcgi(?)が抽出したhtmlのボタンからVB6を起動していて、
クラスメソッドからフォームを表示する処理です。
VB2008経由でバージョンアップしたのですが、web上のボタンを押しても無反応(エラーも出ない)為、
問題箇所の切り分けで、起動元をVBSにしております。

VB6では、
・レジストリ登録
 C:\test\LVE01000.exe /REGSERVER
・VBS起動
 set obj = createObject("LVE01000.clsLVE01001")
 obj.Proc1()
上記のみで動作しているように見えるのですが、
見えない箇所でGUID(?)の設定を、行っているのでしょうか?

それとも、.net化によって上記が動かなくなったのか検討がつきません。
VB6は開発環境が無いので、確認が出来ないです。
できれば、ソースの変更を最小にして動かしたいと思っています。
引用返信 編集キー/
■82145 / inTopicNo.7)  Re[3]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1014回)-(2016/12/13(Tue) 17:24:24)
No82141 (hama さん) に返信
> >この ProgID がレジストリに登録されていることは確認済みでしょうか?
> レジストリに何か設定が必要なのでしょうか?

CreateObject でロードするためには、そのコンポーネントが
レジストリに登録されていなければなりません。
VB6 の頃もそうでしたよね。

アプリケーション マニフェストで Side-by-Side な呼び出しも
行えるようですが、VBScript が相手だとそうもいかないでしょうし。


> すいません、ComVisibleAttributeが???です。
System.Runtime.InteropServices.ComVisibleAttribute 属性クラスのことです。

ソリューション エクスプローラーの [My Project] を開き、
[アプリケーション]タブの[アセンブリ情報]ボタンを押すと、
『アセンブリを COM 参照可能にする』というチェックがあります。
これを有効にしてください(重要)。

これを変更すると、AssemblyInfo.vb の中に、
「<Assembly: ComVisible(True)>」
のような記述が行われます。 No82139 のコードにもありますよね。

もしも ComVisible が True になっていない場合、COM コンポーネントとして
公開されないため、VBScript から呼び出すことはできません。

もしくは、アセンブリ全体を COM として公開するのではなく、
公開したいクラスのみに、「<ComVisible(True)>」という属性を
個別に指定する方法もあります。


アセンブリを COM 参照可能にした場合、コンパイル成功後に
開発環境のレジストリへの登録も行われると思いますが、
DLL ではなく EXE プロジェクトの場合にも
登録してもらえるのかどうかは未確認です。


> すいません、ProgIdAttribute、ClassInterfaceAttributeが???です。
これらも、System.Runtime.InteropServices 名前空間にあります。

ProgId とは、CreateObject の引数に渡す文字列のことです。
これをレジストリに登録しておかないと、VBScript から呼び出せません。

ClassInterface は、ザックリ言えば「参照設定して使うライブラリ」か
「Object/Variant 型に対してレイトバインドで呼ぶライブラリ」かを
示すものです。

2003 年当時の古い記事ですが、下記も参照してみてください。
http://bit.ly/2hyyNWz



>>> C:\test\LVE01000.exe /REGSERVER
>> これは VB6 の場合ですよね。
> いいえ、レジストリ登録しないと、VB起動も出来ない為、今回(.net)用です。

LVE01000.exe は VB.NET 製なのかも知れませんが、
ここで言っているのはそういうことではありません。

「/REGSERVER 付きで呼ぶと登録される」というのは、
VB6 製の ActiveX EXE の場合のルールである、という意味です。

もし、VB.NET 製のもので、/REGSERVER を解釈したいのであれば、
Sub Main にレジストリ登録処理を自分で書き込む必要があります。
(必要に応じて、ComRegisterFunctionAttribute も用意します)


> すいませんRegAsmが???です。
VB6 の頃は、COM コンポーネントをレジストリに登録するために
「REGSVR32 Project1.DLL」や「Project1.EXE /REGSERVER」
というコマンドが必要でしたが、.NET の場合はそれが
「RegAsm ファイル名 /Register」に変わったと言うことです。

RegAsm.exe は、VB6 や Excel 等から参照設定して使えるような
タイプライブラリ(*.tlb)を作成する機能や、レジストリ登録情報を
*.reg ファイルに書き出す機能などもあります。いずれも
No82139 に例として載せていますので、参考にしてみてください。


> 今の所、特定ユーザーのみで使用予定なので、インストローラーは考えて無いです。
インストローラー(inst-roller)ではなく
インストーラー(installer)ですね。
引用返信 編集キー/
■82148 / inTopicNo.8)  Re[4]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (6回)-(2016/12/13(Tue) 18:09:09)
No82145 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士さん、お世話になります。

@ソリューション エクスプローラーの [My Project] を開き、
>[アプリケーション]タブの[アセンブリ情報]ボタンを押すと、
>『アセンブリを COM 参照可能にする』というチェックがあります。
>これを有効にしてください(重要)。
>
>これを変更すると、AssemblyInfo.vb の中に、
>「<Assembly: ComVisible(True)>」
>のような記述が行われます。 No82139 のコードにもありますよね。
(1)『アセンブリを COM 参照可能にする』は有効になってました。
(2)AssemblyInfo.vb の中にあるのは、
   アセンブリ属性、アセンブリバージョンのみありました。

Bもしも ComVisible が True になっていない場合、COM コンポーネントとして
>公開されないため、VBScript から呼び出すことはできません。
>
>もしくは、アセンブリ全体を COM として公開するのではなく、
>公開したいクラスのみに、「<ComVisible(True)>」という属性を
>個別に指定する方法もあります。
AssemblyInfo.vb の中に<ComVisible(True)>の記述が無いです、
フレームワークのバージョンが2.0だからでしょうか?
表示上の最新(4.6.1)にした方がいいでしょうか?

CProgId とは、CreateObject の引数に渡す文字列のことです。
>これをレジストリに登録しておかないと、VBScript から呼び出せません。
>
>ClassInterface は、ザックリ言えば「参照設定して使うライブラリ」か
>「Object/Variant 型に対してレイトバインドで呼ぶライブラリ」かを
>示すものです。
>
>2003 年当時の古い記事ですが、下記も参照してみてください。
>http://bit.ly/2hyyNWz
記事の紹介、ありがとうございました。一度目を通しましたが、よく理解出来なかったので、自宅で読み直します。

DLVE01000.exe は VB.NET 製なのかも知れませんが、
>ここで言っているのはそういうことではありません。
>「/REGSERVER 付きで呼ぶと登録される」というのは、
>VB6 製の ActiveX EXE の場合のルールである、という意味です。
>もし、VB.NET 製のもので、/REGSERVER を解釈したいのであれば、
>Sub Main にレジストリ登録処理を自分で書き込む必要があります。
>(必要に応じて、ComRegisterFunctionAttribute も用意します)
理解不足ですいませんでした、了解しました。

EVB6 の頃は、COM コンポーネントをレジストリに登録するために
>「REGSVR32 Project1.DLL」や「Project1.EXE /REGSERVER」
>というコマンドが必要でしたが、.NET の場合はそれが
>「RegAsm ファイル名 /Register」に変わったと言うことです。
>RegAsm.exe は、VB6 や Excel 等から参照設定して使えるような
>タイプライブラリ(*.tlb)を作成する機能や、レジストリ登録情報を
>*.reg ファイルに書き出す機能などもあります。いずれも
>No82139 に例として載せていますので、参考にしてみてください。
RegAsm.exeの件、ありがとうございます。

Fインストローラー(inst-roller)ではなく
>インストーラー(installer)ですね。
なにげなく使ってましたが、間違っている事に気付きました。
ご指摘ありがとうございます。
引用返信 編集キー/
■82152 / inTopicNo.9)  Re[5]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1016回)-(2016/12/13(Tue) 19:03:42)
No82148 (hama さん) に返信
> AssemblyInfo.vb の中に<ComVisible(True)>の記述が無いです、

あってはいけません。AssemblyInfo.vb の中に記述される内容は、
> >「<Assembly: ComVisible(True)>」
のように、アセンブリに対して指定する属性のみが想定されています。


アセンブリ全体に対して ComVisible が設定された場合、
その中の Class や メソッドも同じ設定になるのですが、
個別に公開/非公開を切り替えたい場合には、クラスやメソッド単位で
> > 公開したいクラスのみに、「<ComVisible(True)>」という属性を
を指定して、その設定を上書きするようにします。


> > http://bit.ly/2hyyNWz
> 一度目を通しましたが、よく理解出来なかったので、自宅で読み直します。

この記事は、C# で書いた .NET コードを VB6 から使う場合の話ですが、内容的には
VB.NET にも通じます。COM(ActiveX) に関する最低限の知識は必要ですけれどね。

分からない点があれば、改めて再質問してみてください。
引用返信 編集キー/
■82153 / inTopicNo.10)  Re[5]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1017回)-(2016/12/13(Tue) 19:38:04)
2016/12/13(Tue) 20:01:24 編集(投稿者)

No82144 (hama さん) に返信
> 知らない用語が多数出て来て、
> 混乱しております。

VBA でも技術背景は同じなのですが(Excel COM アドイン等も含む)、
VBA は COM コンポーネントを利用することはあっても、
COM コンポーネントの作成のために使われるものではないですしね…。


呼び出せるようにするだけなら、サンプルを書いて終わりなのでしょうが、
後々の保守のことまで考えると、きちんと学んでおいた方が良いと思い、
情報過多な長文回答になっています。うまく纏め切れずに済みません。

蛇足的な情報も含まれているので、分かるところだけ
拾い集めて頂ければ幸いです。



> 上記のみで動作しているように見えるのですが、

VBScript からの呼出し手順を、大雑把に説明すると、

(1) CreateObject で "LVE01000.clsLVE01001" が指定される。

(2) レジストリの HKEY_CLASSES_ROOT\LVE01000.clsLVE01001\Clsid が参照される。
 ここには GUID 値(クラスID)が記録されている。

(3) レジストリの HKEY_CLASSES_ROOT\CLSID\{クラスID}\InprocServer32
 の情報などを元に、実際のファイルが読み込まれる。

という流れです。レジストリへの登録は事前に行っておく必要がありますが、
HKEY_CLASSES_ROOT 配下のエントリであるため、管理者権限が必要です。


たとえば CreateObject("ADODB.Recordset") であれば、
{00000535-0000-0010-8000-00AA006D2EA4} というクラスIDが得られ、
それを元に msado15.dll がロードされます。



ActiveX(COM)オブジェクトである以上、呼び出せるようにするために
レジストリ登録が必要ですので、無作為に実験プロジェクトを作ってしまうと、
レジストリにゴミ情報が残ってしまう結果にも繋がります。
これは VB6 でも VB.NET でも同じです。
(実験完了後、きちんとアンレジストまで行えば別ですが)



> 見えない箇所でGUID(?)の設定を、行っているのでしょうか?

そういうことになります。

そして VB6 の ActiveX EXE プロジェクトの場合、
プロジェクトのプロパティの[コンポーネント]タブが肝です。


「スタートモード」は、App.StartMode プロパティの事で、
「リモートサーバー」は、DCOM の設定。そして特に重要なのが
その下の「バージョン間の互換性」の欄です。


VB6 をお持ちでは無いようなので、イメージが湧かないかも
知れませんが、「バージョン間の互換性」の欄には、
  『互換なし』
  『プロジェクト互換』
  『バイナリ互換』
という 3 つの選択肢(RadioButton)があります。

そして『プロジェクト互換』や『バイナリ互換』を選んだ場合は、
その下の TextBox に、直前バージョンの EXE/DLL/OCX を指定します。


VB6 のコンパイラは、この旧ファイルから GUID を得ています。

まだコンパイルしたことのないプロジェクトの場合は、
必然的に『互換なし』を選ぶことになりますが、この場合、
自動的に GUID が割り当てられます。

.NET であれば明示的に指定することもできますが、
VB6 の場合、その GUID 値が何であったかは
コンパイルされたファイルを見てみないとわかりません。


自動生成に任せるなら、もっと短くすることもできるのですが、
実験後に、レジストリ情報を手動で削除することもできるよう、
先のサンプルでは、必要な情報を逐次埋め込んだコードにした次第です。



そうした懸念材料を理解した上で、VB.NET コードを短くするのなら、
下記のようにしてみてください。

・Guid 指定を省略し、自動生成に任せる
・Class に対応する Interface は用意しない。Implements もしない。
・ClassInterfaceType を None から AutoDispatch または AutoDual に変更する。

特に重要なのは、ClassInterfaceType です。


[None] の場合、インターフェイス実装などを明示する必要があるため、
レジストリ情報との連携などが明確になりますが、コードは冗長的になります。


[AutoDispatch] は、VBScript などのように、CreateObject して
使うタイプ向けの設定です。その代わり、VBA などから参照設定して
使うことはできなくなります。レイトバインド専用のモードです。


[AutoDual] はこの中間で、イメージ的には VB6 に一番近いモードです。
レイトバインドと参照設定利用の両方に対応できるというものではありますが、
このモードの利用は推奨されていません。

https://msdn.microsoft.com/ja-jp/library/system.runtime.interopservices.classinterfacetype%28vs.90%29.aspx
》 ClassInterfaceAttribute で説明したようなバージョン管理の制約があるため、AutoDual は使用しないことを強くお勧めします。



> それとも、.net化によって上記が動かなくなったのか検討がつきません。

技術背景的には VB6 でも同じだったのですが、細かいところは隠されており、
変更できない仕様でした。隠されると困る面もあるので一長一短ですね。


もし、VB6 時代の LVE01001.exe が残っているのなら、
Excel VBA からそれを「参照設定」してみてください。

参照設定していない場合は、
 Dim c As Object
 Set c = CreateObject("LVE01001.clsLVE01001")
 c.Proc1
ですが、参照設定していれば、ご存知かと思いますが
 Dim c As LVE01001.clsLVE01001
 Set c = New LVE01001.clsLVE01001
 c.Proc1
といった記述で呼び出せるはずです。


さてこの時、変数の型を
 Dim c As LVE01001.[_clsLVE01001]
と書く事もできたりします。

clsLVE01001 はクラスの名前、
_clsLVE01001 はインターフェイスの名前ですが、
VBA ではアンダーバーで始まる名前が使えないので、
角括弧でエスケープして表記します。


そしてこの _clsLVE01001 にあたるものが、
No82139 で記述した『Public Interface ILVE01000』であり、
先の <ClassInterface(ClassInterfaceType.何某)> の指定とも
関係してくるというわけですね。
引用返信 編集キー/
■82163 / inTopicNo.11)  Re[5]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (7回)-(2016/12/14(Wed) 11:08:19)
No82144 (hama さん) に返信
> ■No82142 (hama さん) に返信
> 魔界の仮面弁士さん、お世話になります。
>
> 今まで、VBAをメインでやっていたのですが、知らない用語が多数出て来て、
> 混乱しております。
>
> 今回の処理はcgi(?)が抽出したhtmlのボタンからVB6を起動していて、
> クラスメソッドからフォームを表示する処理です。
> VB2008経由でバージョンアップしたのですが、web上のボタンを押しても無反応(エラーも出ない)為、
> 問題箇所の切り分けで、起動元をVBSにしております。
>
> VB6では、
> ・レジストリ登録
>  C:\test\LVE01000.exe /REGSERVER
> ・VBS起動
>  set obj = createObject("LVE01000.clsLVE01001")
>  obj.Proc1()
> 上記のみで動作しているように見えるのですが、
> 見えない箇所でGUID(?)の設定を、行っているのでしょうか?
>
> それとも、.net化によって上記が動かなくなったのか検討がつきません。
> VB6は開発環境が無いので、確認が出来ないです。
> できれば、ソースの変更を最小にして動かしたいと思っています。
引用返信 編集キー/
■82165 / inTopicNo.12)  Re[6]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (8回)-(2016/12/14(Wed) 11:33:53)
魔界の仮面弁士さん、お世話になります。

インターネットが使えるPCが共有の1台だけで、他の人が使っていると使用出来ない為、
スマホで送ろうとして、失敗しました。失礼しました。

VB6の実行ファイルをVBSで起動すると、メソッドの実行が出来ました。
今回作成中実行ファイルの、GUID取得と設定を確認してみます。
引用返信 編集キー/
■82170 / inTopicNo.13)  Re[7]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (9回)-(2016/12/14(Wed) 14:34:34)
魔界の仮面弁士さん、お世話になります。

以下でコンパイル時にGUIDが取得出来る事が分かりました。
Dim myGuid As Guid = System.Guid.NewGuid()
Console.WriteLine(myGuid.ToString())

何点か質問させて頂いてもよろしいですか?
@実行形式(exe)ファイルから、GUIDを取得する方法はありますか?
AGUIDをレジストリに直接追加でいいでしょうか?
(今回分ですと、HKEY_CLASSES_ROOT\LVE01000.clsLVE01001\ClsidにGUID値追加)
B"LVE01000.clsLVE01001"の箇所は任意に変更していいのでしょうか?
引用返信 編集キー/
■82174 / inTopicNo.14)  Re[8]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (10回)-(2016/12/14(Wed) 16:09:40)
魔界の仮面弁士さん、お世話になります。

上記質問と関連すると思いますが、
ExcelVBAの参照設定で、VB6のLVE01000.exeは追加できました。
しかし、今回作成したexeを参照設定しようとすると、
「指定されたファイルへの参照は登録できません。」と表示されます。
.net上で「アセンブリをCOM参照可能にする」はチェックしています。
他に何か設定が必要なのでしょうか?
引用返信 編集キー/
■82176 / inTopicNo.15)  Re[8]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1020回)-(2016/12/14(Wed) 17:22:58)
No82170 (hama さん) に返信
> 以下でコンパイル時にGUIDが取得出来る事が分かりました。
> Dim myGuid As Guid = System.Guid.NewGuid()
> Console.WriteLine(myGuid.ToString())

「コンパイル時」では無く「実行時」です。
NewGuid メソッドを呼ぶたびに、新しい GUID が生成されます。

Visual Studio の場合、[ツール]-[GUID の作成]ツールからも生成できます。

もしくは、Visual Studio をインストールしたフォルダの
.\Common7\Tools\guidgen.exe を使う事もできますし、
コマンドライン版なら Uuidgen.exe を利用できます。


VBA/VBScript で生成するなら、
s = Left(CreateObject("Scriptlet.TypeLib").GUID, 38)
です。


> @実行形式(exe)ファイルから、GUIDを取得する方法はありますか?

一口に GUID といっても、タイプライブラリに付与されるものもあれば、
コクラスに付くもの、インターフェイスに付くもの、
ユーザー定義型に付くものといったように、役割の異なる
複数の GUID/UUID が記録されているわけですが、それはさておき。


プログラム的に取得したいというのであれば、VBA 等で
TypeLib Information (TLINFO32.DLL)を参照設定すれば、
調査することができます。レイトバインドで使うなら、
CreateObject("TLI.TLIApplication") です。


自身のプログラムからの取得では無く、ツール等による目視確認で良いのなら、
スタートメニューから Visual Studio コマンドプロンプトを起動し、
そこから『OLEVIEW.EXE』を呼び出してみてください。

このツールは、VBA でいうところの「オブジェクト ブラウザ」のように、
COM コンポーネントの型情報を得るためのものです。

左から 2 番目のアイコン [View TypeLib] から、調査対象の VB6 製
ActiveX コンポーネント(EXE / DLL / OCX) やタイプライブラリを選ぶと、
詳しい情報が得られます。
(開けるファイルは、COM の型情報が含まれているものに限ります)


なお .NET 製の EXE/DLL を調べる場合は、コンパイルしたファイルを
OLEVIEW で直接開くことはできません。この場合は、TlbExp.exe または
RegAsm.exe にてタイプライブラリファイルを作成してから、
そのタイプライブラリを OLEVIEW.EXE に読みこませるようにします。


HTML から OCX から呼び出す場合、object タグの classid 属性に
クラスの GUID 値を指定することになりますよね。

VB6 の場合、GUID をソースコードに埋め込めなかったので、コンパイル後に
こうしたツールを利用して調査する必要があったんですよね…。

GetObject("script:C:\temp\test.wsc") 等で呼び出される、*.wsc 製の
COM コンポーネントだと、レジストリ登録用に <registration> 要素が
用意されていて、そこで明示できたのですけれども。
https://msdn.microsoft.com/ja-jp/library/cc428189.aspx



> AGUIDをレジストリに直接追加でいいでしょうか?
> (今回分ですと、HKEY_CLASSES_ROOT\LVE01000.clsLVE01001\ClsidにGUID値追加)

このあたりもセットで指定してください。

HKEY_CLASSES_ROOT\TypeLib
HKEY_CLASSES_ROOT\CLSID
HKEY_CLASSES_ROOT\Interface

もちろん何を登録してもよいというわけではなく、タイプライブラリ内の
型情報とレジストリの型情報が一致していないといけません。

RegAsm の /regfile オプションを使う事で、記述すべき情報を
ファイルに書き出すことができますので、その .reg ファイルを
配布して登録してもらうというのも一つのやり方です。



> B"LVE01000.clsLVE01001"の箇所は任意に変更していいのでしょうか?

ファイルは書き換えずに、レジストリだけを変更するということでしょうか。

やろうと思えば変更もできなくはないですし、同じ CLSID のオブジェクトに対して、
複数の ProgID をエイリアス的に設ける事もできますが、そもそも何のために
既存の ProgID を変更したいのか、意図が読み取れませんでした。

レジストリ情報を後から変更しても、「VB6製.EXE /Register」や
「RegAsm VB.NET製.EXE」などで元の情報が再登録されることになるので、
あまり意味は無い気がします。

それにオブジェクトの定義や ProgID がいきなり変更されると、
既存アプリも直すことになるので、互換性上の問題が生じてしまいますので、
あとで変更せずに済むよう、最初の開発時にきちんと決めておきましょう。

引用返信 編集キー/
■82177 / inTopicNo.16)  Re[9]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1021回)-(2016/12/14(Wed) 17:24:25)
No82174 (hama さん) に返信
> ExcelVBAの参照設定で、VB6のLVE01000.exeは追加できました。
> しかし、今回作成したexeを参照設定しようとすると、
> 「指定されたファイルへの参照は登録できません。」と表示されます。

.NET 製のものには、タイプライブラリ情報が含まれていないためです。

LVE01000.exe を TLBEXP.EXE あるいは RegAsm.exe に渡して
タイプライブラリ(*.TLB)を作成し、それを参照設定すれば OK です。
引用返信 編集キー/
■82178 / inTopicNo.17)  Re[9]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (11回)-(2016/12/14(Wed) 18:36:07)
魔界の仮面弁士さん

お世話になります、いろいろ教えて頂きまして、すいません。

投稿82176でGUIDの取得方法について、お伺いしました、
レジストリに登録すれば、GUID値について、あまり意識しなくて良いと言う
認識でいます、細かく御教授頂きまして、ありがとうございます。
仕事が落ち着いたら読み直します。

投稿82177ですが、TLBを参照できました、ありがとうございます。

追加の質問ですいません。
新規で作成した「aaaaa.exe」をVBSから実行すると「指定されたファイルが見つかりません。」
と表示されます。どこか手順が悪いでしょうか?

【作成手順】
@VB.netでaaaaa.exe作成(「アセンブリをCOM参照可能にする」チェック済み)

Aレジストリ登録
regasm aaaaa.exe

Bレジストリエディタで登録確認
HKEY_CLASSES_ROOT\AAAAA.Form1\Clsid\{7FF・・・}

CVBS実行(以下ソース)
msgbox "テスト開始"
set obj = createObject("AAAAA.Form1")
msgbox "テスト終了"

引用返信 編集キー/
■82179 / inTopicNo.18)  Re[10]: VBSからVB内のメソッド処理を行う
□投稿者/ 魔界の仮面弁士 (1022回)-(2016/12/14(Wed) 18:42:17)
No82178 (hama さん) に返信
> レジストリに登録すれば、GUID値について、あまり意識しなくて良いと言う
> 認識でいます、細かく御教授頂きまして、ありがとうございます。

ActiveX オブジェクトなクラスには、コンパイルされた時点で
型を一意に識別する GUID 値(クラスID)が付与されます。

それをレジストリに登録する事で、他のアプリから利用できるようになります。

まぁ、CreateObject だけで呼び出すのであれば、重要なのは
ProgId の方なので、CLSID は自動生成でも構わないのですが、
後から「使わなくなった CLSID」がレジストリ内に溜まっていくのも
あまり気持ちのよい物ではないので、先の例では、CLSID を
事前に明示して埋め込んでおく方法を紹介しています。


> 新規で作成した「aaaaa.exe」をVBSから実行すると「指定されたファイルが見つかりません。」
> と表示されます。どこか手順が悪いでしょうか?
aaaaa.exe をシステムフォルダーまたは GAC に登録しておいてください。
引用返信 編集キー/
■82181 / inTopicNo.19)  Re[11]: VBSからVB内のメソッド処理を行う
□投稿者/ hama (12回)-(2016/12/14(Wed) 19:33:52)
No82179 (魔界の仮面弁士 さん) に返信

魔界の仮面弁士さん、お世話になります。

C:\Windows\System32\配下に置いたところ、「指定されたファイルが見つかりません。」
のメッセージは出なくなりました。

ただ、VB内に「VB起動しました。」が出るようにしたのですが、出ないです。
正常にVBが起動していないように見えます。
引用返信 編集キー/
■82183 / inTopicNo.20)  Re[12]: VBSからVB内のメソッド処理を行う
 
□投稿者/ hama (13回)-(2016/12/14(Wed) 23:17:23)
魔界の仮面弁士さん、お世話になります。

自己レスです。

起動時のメソッド(Form1_Load)のメッセージボックスは表示されませんが、
createObject後のメソッドからのメッセージボックスは表示出来ました。

明日、改めて動作確認してみます。
引用返信 編集キー/

次の20件>
トピック内ページ移動 / << 0 | 1 >>

管理者用

- Child Tree -