質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.37%
VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

WSH

WSH(Windows Script Host)とは、Windows上でテキストファイルに記述したJavaScriptやVBScriptなどのスクリプトを実行するホスト環境のことです。COMを通じたレジストリ操作やWMIへのアクセスが可能で、複雑な処理も行うことができます。

Q&A

解決済

2回答

17452閲覧

どうやってVBScriptやJScript (それぞれWSHあり )から WinAPIを使うか

BeatStar

総合スコア4962

VBScript

VBScript(Visual Basic Scripting Edition)はMicrosftが開発したスクリプト言語であり、Visual Basicのサブセットです。

Win32 API

Win32 APIはMicrosoft Windowsの32bitプロセッサのOSで動作するAPIです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

WSH

WSH(Windows Script Host)とは、Windows上でテキストファイルに記述したJavaScriptやVBScriptなどのスクリプトを実行するホスト環境のことです。COMを通じたレジストリ操作やWMIへのアクセスが可能で、複雑な処理も行うことができます。

0グッド

1クリップ

投稿2018/05/18 03:27

基本的にはC++ ( BetterCってやつですが )で趣味でやっています。
C++の実行ファイルとは別にバッチファイルなりJScriptなりでショートカットファイルを生成してエンドユーザが使いやすくするための処理ができたらなぁと思い、

JScriptでショートカットファイルを生成するファイルを生成しました。
で、欲が出てきて、Tip系のサイトを見ると WSH を使う場合 「ファイルを開くダイアログ」見たいなのを出すことができるようなので試してみました。

ですが、「オートメーションエラー」なんちゃらでエラーが出て、ggって見ると「Windowsではあっても"XPのみ"しか使えない」ようです。
( ピンポイントすぎ... )

で、ほかに方法はないかなと探してみたところ、Excelの機能を使う方法とIEを使う方法がありました。

でも何気に重たい ( 遅い ) です。

で、VBScript と JScriptを混合させることができる WSFなるものを見つけました。

WSHでJScriptとVBScriptを共存させてみる

このWSFなるものを使ってVBScript側でもいいからどうにか実現できないものでしょうか?

VBA ( Excel VBA )とかだと

【エクセルVBA】Windows APIで外部プログラムを呼び出すための第一歩

のようなやり方でWindows APIのDLL ( カーネルとか? ) を呼び出せるようですが、VBScriptには declare がありません。

で、Excelの機能を使う方法もありますが、上記で言ったようにちょっと重い。

できるなら C++で組んだ DLL ( WinAPIのファイルを開くダイアログをさらに呼び出しやすくラップしただけ。 ) を呼び出したいのですが、

Stack Overflowさんの過去質問とかでは「不可能。使えるとしてもせめて中間にVBのDLLをおいて"間接的に"操作しろ」みたいな回答か「カテゴリが違う」みたいな回答ばかりでどうやればいいのか...

VBScriptであれば VBAみたいに使うことが可能ならそのまま組めるのですが...

つまり聞きたいこととしては、

■ どうやって「ファイルを開くダイアログ」なんかを使うか ( できるだけ IEやExcelは使わずに )

■ どうやって Windows APIのDLLなんかを使うことができるか ( オプショナルですが、これがわかれば 上のやつが簡単に解消できるので )

です。

[情報]
言語: WSF? ( VBScriptとJScriptを混在させている )
OS: Windows XP/7/10
Excel: ネットカフェ等ではインストールされていないことがあるのでなるべく使いたくない...

宜しくお願い致します。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

WSHから直接dllを呼び出すことはできません。
DynaWrapやDynaCallなどのCOMモジュールがフリーで提供されていますので、それを使うことでWIN32APIにアクセスできるようになります。
私は以下のサイトにあるSFC mini(DynaCall)で試してみました(日本の方が作成していていくらか安心なので)
https://ja.osdn.net/projects/sfcmini/
ダウンロードして展開したフォルダの中にサンプルプログラムがあります。
今回の例だとOpenFile.vbsを参照すると良いでしょう。

備忘
私だけかもしれませんが、実行に少々手間取りました。
というのも実行環境は64bitなんですが、WSHからCOMを利用する場合、COMが32bitか64bitかで使用するWscriptを切り替える必要がありました。
DynaCallは32bitのようですが、単純にvbsファイルを実行すると64bit版のwscriptが起動され失敗します。
以下のように明示的に32bit版wscriptを使うようにする必要がありました。

C:\Windows\SysWOW64\wscript OpenFile.vbs

投稿2018/05/18 06:08

ttyp03

総合スコア17000

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2018/05/23 02:16

返信遅れてすみません。 ご回答ありがとうございます。 SFC miniを試してみました。 "vbsjs"ディレクトリを用意し、その中に + sfcminiディレクトリ + supponディレクトリ + run.bat + start.vbs を置いて、run.batには suppon\suppon.exe start.vbs と記述しています。 これ( run.bat ) を起動するとダイアログが出ますが、単にcaptionで "Error"と出て使えません。 ( start.vbs はsfcmini同梱のsampleディレクトリにあるサンプル( 試しにMsgBox.vbs ) をコピーしています。 ) supponを使わない方法 () だとご指摘の通り「明示的に32bit版wscriptを使うようにする」と rem run.bat cscript sfcmini\install.vbs echo off C:\Windows\SysWOW64\wscript start.vbs pause とするとうまくいきました。 ですが、install.vbs側のレジストリを変更するためにダイアログ「このアプリがディバイスに変更を加えることを...」 っていうやつと、「レジストリ登録完了しました」みたいなやつが 私としては邪魔かなぁと。 同梱のsupponを使うとそもそも動かないです。( "Error"メッセージが出てくるが、理由が出てこない。 ) suppon側のreadme.txtを読むと、「利用する際は、ActiveX-DLL/OCXファイルをsuppon.exeと同じフォルダに起き、 suppon.jpを編集して、プログラムID・ファイル名・CLSIDを設定してください。」とあります。 コレの意味がわからないです。 必要なDLL ( C++とかだと 7-Zip32.dllを使う場合は同梱しろ...みたいな意味? )を同梱すればいいのか、 なんなのかよくわかりません。 あと、同梱のファイルを読むとLGPLみたいです。 そのまま sfcmini + suppon を一つにまとめて [ sfcmini ] + helpディレクトリ // sfcmini + libディレクトリ // sfcmini ... + install.vbs // sfcmini + uninstall.vbs // sfcmini + suppon.exe // suppon + suppon.js // suppon とやってもいいのでしょうか? ( 配布目的で。 )
ttyp03

2018/05/23 02:20

supponは試していないのでちょっとわかりません。 時間があれば試して見ますが今忙しくて…。 ちなみにsupponを使わない方法で、install.vbsは一回だけ実行すればシステムに登録されます。 なのでバッチファイルに組み込む必要はありません。
BeatStar

2018/05/23 03:32

>> ちなみにsupponを使わない方法で、... そうですか。 後出しで済みません ( 自分では入れたつもりだったのに... ) が、ネットカフェとかでも使うことができるようにしようとしています。 ネットカフェとかだとログオン時に初期化されるようなので、毎回登録しないといけないと思います。 そのために、バッチファイルから install.vbs を呼び出しています。 後出しで済みません...
ttyp03

2018/05/23 04:06

いや、すみません。 Excelのことは頭にあったのですが、COMもそうですよね。 むしろネットカフェのPCに勝手にCOMを登録するのもダメですね。 うっかりしてました。
ttyp03

2018/05/23 04:41

suppon使ってみました。 suppon.exe suppon.js sfcmini.dll の3つが同じフォルダに置いてあれば動くと思います。 vbsの場所はどこでもよさそうです。
BeatStar

2018/05/25 02:29

余裕があるときに試してみました。 ※ 回答を頂いたときに試してみましたが、 (簡易的だからか)エラーが出たので余裕があるときに挑戦しようと思い、 先延ばしにしたためです。 sfcmini.dll suppon.js suppon.exe と同じディレクトリに実際に動かしたいwsfを置いて、(TestA.wsfとすると) バッチファイルに suppon.exe TestA.wsf と記述して(バッチファイルを)ダブルクリックすると ( "Error", "文字列が正しくありません" ) と出ます。 suppon.exe をダブルクリックするとコマンドライン引数がないので"%1が見つかりませんでした"と出るのはわかりますが、 suppon.exe TestA.wsf とsupponにコマンドライン引数として TestA.wsf (実際に動かしたい処理) を渡しているのに...です。 「suppon "文字列が正しくありません"」とエラーメッセージ?をキーワードにして検索してみましたが、 しっくりくる答えがありませんでした。 ( よくてC#とか。suppon内部なんて触れないから意味ない... )
ttyp03

2018/05/25 02:35

ん?wsf? supponのreadmeには、 作成したWSHファイル(*.vbs, *.js, *.vbe, *.jse)は、suppon.exeにコマンドライン(%1)として与えると、実行できます。 とあるので、wsfは対応していないような気がします。 純粋にvbsとして作成することはできないのでしょうか(スクリプト部分だけ抜き出して拡張子vbsで保存)
BeatStar

2018/05/25 02:50 編集

サンプルとして同梱されているやつを sample.vbs( うまくいけばウィンドウが2つ表示されるらしい... ) として試してみてもwsfのときみたいに「"文字列が正しくありません"」と出ます。 最初は別のエラー( メッセージが表示されない... ) で、サンプルのコードを読むとC言語でいうインクルードをしているみたいなので必要なvbsファイルをsfcminiに同梱のlibディレクトリにあるやつを同じディレクトリに置くと 「"文字列が正しくありません"」と出ます。
ttyp03

2018/05/25 02:57

サンプルはTwoForms.vbsでしょうかね。 確かにこちらの環境でも動きませんでした(空のメッセージボックスが出るだけ) MsgBox.vbsはどうでしょうか。 これはきちんと動くようですが。
ttyp03

2018/05/25 03:02

展開したsfcminiフォルダ内に、suppon.exe と suppon.js を置いて実行したら動きました。 suppon sample\twoforms.vbs
BeatStar

2018/05/25 03:35

おお! 動きました! でも問題のwsfファイルは「"ステートメントがありません"」と出て使えませんでした。 でも、これならvbsまたはjsで可能なので、これをメインにやろうかなと思っています。 ありがとうございます!
BeatStar

2018/05/27 02:57

何度もすみません... 「これはいいね!」と思い、同梱のMsgBox.js をまねて https://pastebin.com/eXxzpZxA を main.js として保存し、supponを介して動かしてみました。 一応動きますが、なぜか文字化けします。 C言語 + Windows API だと ANSIとUNICODEそれぞれ別の関数で定義されていることが多いため、 MessageBoxA関数じゃなくて MessageBoxW関数でやってみましたが、同じ結果です。 supponを使わないでinstall.vbs 辺りを使う場合は普通に表示されます。 たぶんsupponがJavaとかみたいに読み込む際に ANSIとして読み込んでいるとかが原因だと思われますが、suppon側及びsfcmini側のreadme.txtを読んでもsupponのコマンドライン引数については言及されていません。これってあきらめるしかないのでしょうか? できれば日本語(表示)がいいのですが。 ( 上記のソースコードが記載されているURLのコードのWScript.Echo のところの文字列を "おはよう"みたいな日本語にするとそこも文字化けする... install.vbs を使うほうだと普通にどちらも可能だけど... )
ttyp03

2018/05/28 04:07

少し試してみましたけど、確かに日本語が化けますね。 supponだと無理かもしれませんね。 作者の方に連絡してみてはいかがでしょうか。 修正版をリリースしてくれるかもしれません。
BeatStar

2018/05/29 01:30

製作者に問い合わせてみました。 Windows APIのANSI <-> Unicode変換の関数を使ってやればいいみたいです。 ご協力ありがとうございました。
ttyp03

2018/05/29 01:32

協力的な方でよかったですね。 しかし面倒ですね…。
guest

0

ご質問の主旨が「どうやってVBScriptやJScript (それぞれWSHあり )から WinAPIを使うか」なので直接の回答ではなく、代替案の提示にとどまりますが、PowerShellで書き換える、あるいはPowerShellを併用する、と言う手がありますのでご案内します。※こんな方法もある、程度にとらえてください。

PowerShellでは.NET FrameworkのSystem.windows.formsを使ってファイル選択ダイアログを表示することができ、それで取り出したファイル名を標準出力に出すことができます。

Windows Scripting Hostでは使えるオブジェクトのひとつにWshScriptExecがあり、これは標準入出力が使えます。
WshScriptExec オブジェクト

これらを組み合わせます。流れとしては、

  1. WSHのVBScriptからPowerShellのスクリプトでファイル選択ダイアログを表示させ、
  2. ファイル選択ダイアログで取得したファイル名を標準出力に流し、
  3. VBScriptで取り込んで処理をさせる。

となります。例として、VBScript側のコードです。

VBScript

1' sample.vbs 2 3Dim WshShell, oExec, fileName, c 4 5Set WshShell = CreateObject("WScript.Shell") 6Set oExec = WshShell.Exec("powershell .\OpenFileDialog.ps1") 7 8fileName = "" 9Do While True 10 11 If Not oExec.StdOut.AtEndOfStream Then 12 ' 1文字標準入力より読み出し 13 c = oExec.StdOut.Read(1) 14 If c = ";" Then 15 Exit Do 16 End If 17 18 fileName = fileName & c 19' WScript.Echo("生成中... " & fileName) 20 End If 21' WScript.Sleep 100 22Loop 23 24WScript.Echo(fileName & " が選択されました。") 25

PowerShellでのファイル選択ダイアログボックスを表示するコードです。このコードではファイルを選択するとそのファイル名の末尾にセミコロン';' を追加します。(VBScript側で、末尾の検出をさせる為です)

PowerShell

1# 2# FileOpenDialog.ps1 3 4[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms") 5 6$dialog = New-Object System.Windows.Forms.OpenFileDialog 7$dialog.Filter = "全てのファイル(*.*)|*.*" 8$dialog.InitialDirectory = "C:\" 9$dialog.Title = "ファイルを選択してください" 10 11# 複数選択時は Multiselect 12$dialog.Multiselect = $false 13$dialog.ShowHelp = $true 14 15# ファイル選択ダイアログボックスを表示 16if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) { 17 # 複数選択を許可している時は $dialog.FileNames を利用 18 # 行端に";"を追加 19 Write-Output ($dialog.FileName + ";") 20} else { 21 # キャンセルの場合 22 Write-Output (";") 23}

この2つのファイルを同じディレクトリ上に配置し、sample.vbs をCScriptで実行させます。以下は、Windows 7上で実行した例です。実行するとすぐにファイル選択ダイアログボックスが表示されます。例では、「D:\TEMP\WindowsApp1\bin\Debug\WindowsApp1.xml」を指定し、[OK]ボタンを押しています。

CMD

1D:\project\test\powershell>cd D:\project\test\powershell 2 3D:\project\test\powershell>cscript sample.vbs 4Microsoft (R) Windows Script Host Version 5.8 5Copyright (C) Microsoft Corporation 1996-2001. All rights reserved. 6 7D:\TEMP\WindowsApp1\bin\Debug\WindowsApp1.xml が選択されました。 8 9D:\project\test\powershell>

難点と言えば、

  • 標準入出力を使うので、CScript.exeを使う必要がある。WScript.exeではダメ。
  • PowerShellスクリプトを実行できるようにしておく必要がある。
  • PowerShellが使えるのであればWin32 APIも使えるようになるので、そもそもWSHのVBScript/JScriptと併用する必然性が無くなる。(≒WSHを使ったスクリプトの存在意義が無くなる)

でしょうか。

投稿2018/05/18 09:57

編集2018/05/18 10:11
dodox86

総合スコア9254

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2018/05/23 02:16

返信遅れてすみません。 ご回答ありがとうございます。 PowerShellですか...今までノータッチだったので、 そもそもPowerShellが使えません。(使い方がわかりません...) PowerShellの入門系のサイトでチェックしてトライしてみます!
BeatStar

2018/05/25 02:26

PowerShellは使ったことないので試してみました。 ちょっと、私にはハードルが高いです。というか、私が考えていたやつとはちょっと違いました... ( イメージ的には最悪、$cscript main.wsf みたいにワンライン程度でしたが、初期設定がめんどくさい... 一般ユーザからすると使用不可能なレベルかも? ) ですが、こういうことができるってわかったので、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.37%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問