2011-09-20 12 views
6

当社の製品内で特定の動作が発生した場合に呼び出されるVBScript機能を求める顧客がいます。私はWindows Scripting技術を研究しようとしていましたが、私が必要とするものを正確に見つけるのが難しいです。うまくいけばあなたの何人かが助けることができます。C++からVBScript関数を読み込んで呼び出す方法は?

当社の製品は、ネイティブのC++ Windows製品です。顧客は、ロードするVBScriptファイルを指定し、特定のイベントが発生するたびに、VBScript内の特定の関数を呼び出して、それを実行させます。スクリプトの名前空間内にオブジェクトを提供して、製品に関する情報にもアクセスできるようにすることがあります。

MSctに関するIActiveScriptインターフェイスと関連するいくつかの情報が見つかりましたが、このインターフェイスを実装するCOMオブジェクトをVBScript用にインスタンス化する例は見つかりません。

私はPowerShellがおそらくこれのためのより良い選択肢だと知っていますが、顧客は多くのレガシーシステムに悩まされており、VBScriptは彼らが知っているものです。

あなたが提供できるヘルプ(リンクなど)をいただければ幸いです!

+0

これは良い質問ですが、StackOverflowに適している可能性があります。このサイトは本当に主観的な話題です。 IActiveScriptは、あなたが調査する正しい方向です。 – GrandmasterB

答えて

2

は、いくつかのサンプルコード http://support.microsoft.com/kb/221992

ため、このを見てください、あなたを助けることができるmsscript.ocxがありますが、あなたはC++ http://msdn.microsoft.com/en-us/magazine/cc302278.aspx

+0

ありがとうございます。あなたが指しているサンプルコード(最初のリンク)はとても役に立ちます。私はMFCなしで​​それを行う方法を理解する必要があります(私たちのプロジェクトはMFCを使用しないので)。しかし、それは始めるのに最適な場所です。 – tyrel

+1

http://www.codeproject.com/KB/COM/com_in_c6.aspx参照 –

1

IActiveScriptを書くことができれば、おそらくその価値よりも多くのトラブルで、関連するインターフェイスがうまく機能します。私はあなたが記述したのとまったく同じ方法で私の製品でそれらを使用します。顧客の中には、独自のVBScriptスクリプトとJScriptスクリプトを作成して、データベースにポストされる前にアプリケーションデータを分析および更新するユーザーもいます。

CoCreateInstance()を使用すると、他のCOMオブジェクトと同様にIActiveScriptをインスタンス化できます。 QueryInterface()メソッドを呼び出して、スクリプトコードのスニペットを読み込むためのIActiveScriptParseインターフェイスを取得してから、IActiveScriptの状態を更新してコードを実行します。 由来のクラスを実装し、IActiveScript::AddNamedItem()IActiveScriptSite::GetItemInfo()コールバックを使用してエンジンに渡すことで、カスタムオブジェクトをスクリプトに追加できます。

MSDNにはIActiveScriptの使用例があります。

+0

これは基本的に私がすでに理解しているものですが、ありがとうございます。 MSDNでこの情報が見つかりましたが、例は見つけられませんでした。例があるが、何かを指していないことを教えてくれてありがとう。 (リチャードの答えは私のためにこれを提供した) – tyrel

10

私は一緒に "Hello World" のIActiveScript C++ ATLコンソールアプリケーション入れている:

  • IActiveScriptSiteIActiveScriptSiteWindowインタフェースを実装
  • (必須)インターフェース(オプション)を実装

    • CSimpleScriptSiteクラス定義を
    • ほとんどの機能がダミースタブで実装された最小実装
    • エラー処理はありません。 MSDN IActiveScriptErrorを参照してください。
  • 使用CoCreateInstance新しいIActiveSiteオブジェクト
    • IActiveScriptParseインターフェース
    • 使用IActiveScriptParseを取得するIActiveSite::SetScriptSite
    • コールQueryInterfaceを使用して両方のVBScriptJScript
    • リンクIActiveScriptSiteIActiveSiteのインスタンスを作成します。 VBScriptまたはを実行します。コード
    • サンプル
    • JScriptにおける発現はVBScript
    • における発現を評価評価はVBScript

コードでコマンドを実行

#include "stdafx.h" 
#include <atlbase.h> 
#include <activscp.h> 

class CSimpleScriptSite : 
    public IActiveScriptSite, 
    public IActiveScriptSiteWindow 
{ 
public: 
    CSimpleScriptSite() : m_cRefCount(1), m_hWnd(NULL) { } 

    // IUnknown 

    STDMETHOD_(ULONG, AddRef)(); 
    STDMETHOD_(ULONG, Release)(); 
    STDMETHOD(QueryInterface)(REFIID riid, void **ppvObject); 

    // IActiveScriptSite 

    STDMETHOD(GetLCID)(LCID *plcid){ *plcid = 0; return S_OK; } 
    STDMETHOD(GetItemInfo)(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti) { return TYPE_E_ELEMENTNOTFOUND; } 
    STDMETHOD(GetDocVersionString)(BSTR *pbstrVersion) { *pbstrVersion = SysAllocString(L"1.0"); return S_OK; } 
    STDMETHOD(OnScriptTerminate)(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo) { return S_OK; } 
    STDMETHOD(OnStateChange)(SCRIPTSTATE ssScriptState) { return S_OK; } 
    STDMETHOD(OnScriptError)(IActiveScriptError *pIActiveScriptError) { return S_OK; } 
    STDMETHOD(OnEnterScript)(void) { return S_OK; } 
    STDMETHOD(OnLeaveScript)(void) { return S_OK; } 

    // IActiveScriptSiteWindow 

    STDMETHOD(GetWindow)(HWND *phWnd) { *phWnd = m_hWnd; return S_OK; } 
    STDMETHOD(EnableModeless)(BOOL fEnable) { return S_OK; } 

    // Miscellaneous 

    HRESULT SetWindow(HWND hWnd) { m_hWnd = hWnd; return S_OK; } 

public: 
    LONG m_cRefCount; 
    HWND m_hWnd; 
}; 

STDMETHODIMP_(ULONG) CSimpleScriptSite::AddRef() 
{ 
    return InterlockedIncrement(&m_cRefCount); 
} 

STDMETHODIMP_(ULONG) CSimpleScriptSite::Release() 
{ 
    if (!InterlockedDecrement(&m_cRefCount)) 
    { 
     delete this; 
     return 0; 
    } 
    return m_cRefCount; 
} 

STDMETHODIMP CSimpleScriptSite::QueryInterface(REFIID riid, void **ppvObject) 
{ 
    if (riid == IID_IUnknown || riid == IID_IActiveScriptSiteWindow) 
    { 
     *ppvObject = (IActiveScriptSiteWindow *) this; 
     AddRef(); 
     return NOERROR; 
    } 
    if (riid == IID_IActiveScriptSite) 
    { 
     *ppvObject = (IActiveScriptSite *) this; 
     AddRef(); 
     return NOERROR; 
    } 
    return E_NOINTERFACE; 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    HRESULT hr = S_OK; 
    hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); 

    // Initialize 
    CSimpleScriptSite* pScriptSite = new CSimpleScriptSite(); 
    CComPtr<IActiveScript> spJScript; 
    CComPtr<IActiveScriptParse> spJScriptParse; 
    hr = spJScript.CoCreateInstance(OLESTR("JScript")); 
    hr = spJScript->SetScriptSite(pScriptSite); 
    hr = spJScript->QueryInterface(&spJScriptParse); 
    hr = spJScriptParse->InitNew(); 
    CComPtr<IActiveScript> spVBScript; 
    CComPtr<IActiveScriptParse> spVBScriptParse; 
    hr = spVBScript.CoCreateInstance(OLESTR("VBScript")); 
    hr = spVBScript->SetScriptSite(pScriptSite); 
    hr = spVBScript->QueryInterface(&spVBScriptParse); 
    hr = spVBScriptParse->InitNew(); 

    // Run some scripts 
    CComVariant result; 
    EXCEPINFO ei = { }; 
    hr = spJScriptParse->ParseScriptText(OLESTR("(new Date()).getTime()"), NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei); 
    hr = spVBScriptParse->ParseScriptText(OLESTR("Now"), NULL, NULL, NULL, 0, 0, SCRIPTTEXT_ISEXPRESSION, &result, &ei); 
    hr = spVBScriptParse->ParseScriptText(OLESTR("MsgBox \"Hello World! The current time is: \" & Now"), NULL, NULL, NULL, 0, 0, 0, &result, &ei); 

    // Cleanup 
    spVBScriptParse = NULL; 
    spVBScript = NULL; 
    spJScriptParse = NULL; 
    spJScript = NULL; 
    pScriptSite->Release(); 
    pScriptSite = NULL; 

    ::CoUninitialize(); 
    return 0; 
} 
関連する問題