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

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

ただいまの
回答率

90.52%

  • JavaScript

    16362questions

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

  • VBScript

    221questions

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

  • Win32 API

    221questions

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

  • WSH

    33questions

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

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

解決済

回答 2

投稿

  • 評価
  • クリップ 1
  • VIEW 866

BeatStar

score 1015

基本的には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: ネットカフェ等ではインストールされていないことがあるのでなるべく使いたくない...

宜しくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

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/23 11: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

    とやってもいいのでしょうか? ( 配布目的で。 )

    キャンセル

  • 2018/05/23 11:20

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

    キャンセル

  • 2018/05/23 12:32

    >> ちなみにsupponを使わない方法で、...

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

    キャンセル

  • 2018/05/23 13:06

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

    キャンセル

  • 2018/05/23 13:41

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

    キャンセル

  • 2018/05/25 11: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内部なんて触れないから意味ない... )

    キャンセル

  • 2018/05/25 11:35

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

    キャンセル

  • 2018/05/25 11:50 編集

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

    キャンセル

  • 2018/05/25 11:57

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

    キャンセル

  • 2018/05/25 12:02

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

    キャンセル

  • 2018/05/25 12:35

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

    キャンセル

  • 2018/05/27 11: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 を使うほうだと普通にどちらも可能だけど... )

    キャンセル

  • 2018/05/28 13:07

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

    キャンセル

  • 2018/05/29 10:30

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

    キャンセル

  • 2018/05/29 10:32

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

    キャンセル

+1

ご質問の主旨が「どうやって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側のコードです。

' sample.vbs

Dim WshShell, oExec, fileName, c

Set WshShell = CreateObject("WScript.Shell")
Set oExec = WshShell.Exec("powershell .\OpenFileDialog.ps1")

fileName = ""
Do While True

    If Not oExec.StdOut.AtEndOfStream Then
        ' 1文字標準入力より読み出し
        c = oExec.StdOut.Read(1)
        If c = ";" Then
            Exit Do
        End If

        fileName = fileName & c
'        WScript.Echo("生成中... " & fileName)
      End If
'     WScript.Sleep 100
Loop

WScript.Echo(fileName & " が選択されました。")


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

#
# FileOpenDialog.ps1

[void][System.Reflection.Assembly]::LoadWithPartialName("System.windows.forms")

$dialog = New-Object System.Windows.Forms.OpenFileDialog
$dialog.Filter = "全てのファイル(*.*)|*.*"
$dialog.InitialDirectory = "C:\"
$dialog.Title = "ファイルを選択してください"

# 複数選択時は Multiselect
$dialog.Multiselect = $false
$dialog.ShowHelp = $true

# ファイル選択ダイアログボックスを表示
if ($dialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
    # 複数選択を許可している時は $dialog.FileNames を利用
    # 行端に";"を追加
    Write-Output ($dialog.FileName + ";")
} else {
    # キャンセルの場合
    Write-Output (";")
}

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

D:\project\test\powershell>cd D:\project\test\powershell

D:\project\test\powershell>cscript sample.vbs
Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

D:\TEMP\WindowsApp1\bin\Debug\WindowsApp1.xml が選択されました。

D:\project\test\powershell>


難点と言えば、

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

でしょうか。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/23 11:16

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

    キャンセル

  • 2018/05/25 11:26

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

    キャンセル

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

  • ただいまの回答率 90.52%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • JavaScript

    16362questions

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

  • VBScript

    221questions

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

  • Win32 API

    221questions

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

  • WSH

    33questions

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