Class: WIN32OLE

Inherits:
Object
  • Object
show all
Defined in:
win32ole.c

Overview

WIN32OLE objects represent OLE Automation object in Ruby.

 By using WIN32OLE, you can access OLE server like VBScript.

 Here is sample script.

   require 'win32ole'

   excel = WIN32OLE.new('Excel.Application')
   excel.visible = true
   workbook = excel.Workbooks.Add();
   worksheet = workbook.Worksheets(1);
   worksheet.Range("A1:D1").value = ["North","South","East","West"];
   worksheet.Range("A2:B2").value = [5.2, 10];
   worksheet.Range("C2").value = 8;
   worksheet.Range("D2").value = 20;

   range = worksheet.Range("A1:D2");
   range.select
   chart = workbook.Charts.Add;

   workbook.saved = true;

   excel.ActiveWorkbook.Close(0);
   excel.Quit();

Unfortunately, Win32OLE doesn't support the argument passed by
reference directly.
Instead, Win32OLE provides WIN32OLE::ARGV.
If you want to get the result value of argument passed by reference,
you can use WIN32OLE::ARGV.

   oleobj.method(arg1, arg2, refargv3)
   puts WIN32OLE::ARGV[2]   # the value of refargv3 after called oleobj.method

Defined Under Namespace

Modules: VARIANT

Constant Summary collapse

VERSION =
rb_str_new2(WIN32OLE_VERSION)
ARGV =
rb_ary_new()
CP_ACP =
INT2FIX(CP_ACP)
CP_OEMCP =
INT2FIX(CP_OEMCP)
CP_MACCP =
INT2FIX(CP_MACCP)
CP_THREAD_ACP =
INT2FIX(CP_THREAD_ACP)
CP_SYMBOL =
INT2FIX(CP_SYMBOL)
CP_UTF7 =
INT2FIX(CP_UTF7)
CP_UTF8 =
INT2FIX(CP_UTF8)
LOCALE_SYSTEM_DEFAULT =
INT2FIX(LOCALE_SYSTEM_DEFAULT)
LOCALE_USER_DEFAULT =
INT2FIX(LOCALE_USER_DEFAULT)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#new(server, [host]) ⇒ WIN32OLE object

Returns a new WIN32OLE object(OLE Automation object). The first argument server specifies OLE Automation server. The first argument should be CLSID or PROGID. If second argument host specified, then returns OLE Automation object on host.

WIN32OLE.new('Excel.Application') # => Excel OLE Automation WIN32OLE object.
WIN32OLE.new('{00024500-0000-0000-C000-000000000046}') # => Excel OLE Automation WIN32OLE object.


3219
3220
3221
3222
3223
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240
3241
3242
3243
3244
3245
3246
3247
3248
3249
3250
3251
3252
3253
3254
3255
3256
3257
3258
3259
3260
3261
3262
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
# File 'win32ole.c', line 3219

static VALUE
fole_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE host;
    VALUE others;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    IDispatch *pDispatch;
    void *p;
    rb_secure(4);
    rb_call_super(0, 0);
    rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);

    SafeStringValue(svr_name);
    if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
        rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
                 StringValuePtr(svr_name));
    }
    if (!NIL_P(host)) {
	SafeStringValue(host);
        if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
            rb_raise(rb_eSecurityError, "Insecure Object Creation - %s",
                     StringValuePtr(svr_name));
        }
        return ole_create_dcom(argc, argv, self);
    }

    /* get CLSID from OLE server name */
    pBuf  = ole_vstr2wc(svr_name);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "unknown OLE server: `%s'",
                  StringValuePtr(svr_name));
    }

    /* get IDispatch interface */
    hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
                          &IID_IDispatch, &p);
    pDispatch = p;
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE object from `%s'",
                  StringValuePtr(svr_name));
    }

    ole_set_member(self, pDispatch);
    return self;
}

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(id[,arg1, arg2, ...]) ⇒ Object

Calls WIN32OLE#invoke method.



4066
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077
4078
4079
4080
4081
4082
4083
4084
4085
4086
4087
# File 'win32ole.c', line 4066

static VALUE
fole_missing(int argc, VALUE *argv, VALUE self)
{
    ID id;
    const char* mname;
    int n;
    id = rb_to_id(argv[0]);
    mname = rb_id2name(id);
    if(!mname) {
        rb_raise(rb_eRuntimeError, "fail: unknown method or property");
    }
    n = strlen(mname);
    if(mname[n-1] == '=') {
        argv[0] = rb_enc_str_new(mname, n-1, cWIN32OLE_enc);

        return ole_propertyput(self, argv[0], argv[1]);
    }
    else {
        argv[0] = rb_enc_str_new(mname, n, cWIN32OLE_enc);
        return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
    }
}

Class Method Details

.codepageObject

Returns current codepage.

WIN32OLE.codepage # => WIN32OLE::CP_ACP


2994
2995
2996
2997
2998
# File 'win32ole.c', line 2994

static VALUE
fole_s_get_code_page(VALUE self)
{
    return INT2FIX(cWIN32OLE_cp);
}

.codepage=(CP) ⇒ Object

Sets current codepage. The WIN32OLE.codepage is initialized according to Encoding.default_internal. If Encoding.default_internal is nil then WIN32OLE.codepage is initialized according to Encoding.default_external.

WIN32OLE.codepage = WIN32OLE::CP_UTF8
WIN32OLE.codepage = 65001


3031
3032
3033
3034
3035
3036
3037
3038
3039
3040
# File 'win32ole.c', line 3031

static VALUE
fole_s_set_code_page(VALUE self, VALUE vcp)
{
    UINT cp = FIX2INT(vcp);
    set_ole_codepage(cp);
    /*
     * Should this method return old codepage?
     */
    return Qnil;
}

.connect(ole) ⇒ Object

Returns running OLE Automation object or WIN32OLE object from moniker. 1st argument should be OLE program id or class id or moniker.

WIN32OLE.connect('Excel.Application') # => WIN32OLE object which represents running Excel.


2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
# File 'win32ole.c', line 2693

static VALUE
fole_s_connect(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE others;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    IDispatch *pDispatch;
    void *p;
    IUnknown *pUnknown;

    rb_secure(4);
    /* initialize to use OLE */
    ole_initialize();

    rb_scan_args(argc, argv, "1*", &svr_name, &others);
    SafeStringValue(svr_name);
    if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
        rb_raise(rb_eSecurityError, "Insecure Object Connection - %s",
		 StringValuePtr(svr_name));
    }

    /* get CLSID from OLE server name */
    pBuf = ole_vstr2wc(svr_name);
    hr = CLSIDFromProgID(pBuf, &clsid);
    if(FAILED(hr)) {
        hr = CLSIDFromString(pBuf, &clsid);
    }
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        return ole_bind_obj(svr_name, argc, argv, self);
    }

    hr = GetActiveObject(&clsid, 0, &pUnknown);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "OLE server `%s' not running", StringValuePtr(svr_name));
    }
    hr = pUnknown->lpVtbl->QueryInterface(pUnknown, &IID_IDispatch, &p);
    pDispatch = p;
    if(FAILED(hr)) {
        OLE_RELEASE(pUnknown);
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE server `%s'",
                  StringValuePtr(svr_name));
    }

    OLE_RELEASE(pUnknown);

    return create_win32ole_object(self, pDispatch, argc, argv);
}

.const_load(ole, mod = WIN32OLE) ⇒ Object

Defines the constants of OLE Automation server as mod's constants. The first argument is WIN32OLE object or type library name. If 2nd argument is omitted, the default is WIN32OLE. The first letter of Ruby's constant variable name is upper case, so constant variable name of WIN32OLE object is capitalized. For example, the 'xlTop' constant of Excel is changed to 'XlTop' in WIN32OLE. If the first letter of constant variabl is not [A-Z], then the constant is defined as CONSTANTS hash element.

module EXCEL_CONST
end
excel = WIN32OLE.new('Excel.Application')
WIN32OLE.const_load(excel, EXCEL_CONST)
puts EXCEL_CONST::XlTop # => -4160
puts EXCEL_CONST::CONSTANTS['_xlDialogChartSourceData'] # => 541

WIN32OLE.const_load(excel)
puts WIN32OLE::XlTop # => -4160

module MSO
end
WIN32OLE.const_load('Microsoft Office 9.0 Object Library', MSO)
puts MSO::MsoLineSingle # => 1


2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
# File 'win32ole.c', line 2775

static VALUE
fole_s_const_load(int argc, VALUE *argv, VALUE self)
{
    VALUE ole;
    VALUE klass;
    struct oledata *pole;
    ITypeInfo *pTypeInfo;
    ITypeLib *pTypeLib;
    unsigned int index;
    HRESULT hr;
    OLECHAR *pBuf;
    VALUE file;
    LCID    lcid = cWIN32OLE_lcid;

    rb_secure(4);
    rb_scan_args(argc, argv, "11", &ole, &klass);
    if (TYPE(klass) != T_CLASS &&
        TYPE(klass) != T_MODULE &&
        TYPE(klass) != T_NIL) {
        rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
    }
    if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
        OLEData_Get_Struct(ole, pole);
        hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
                                                  0, lcid, &pTypeInfo);
        if(FAILED(hr)) {
            ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
        }
        hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
        if(FAILED(hr)) {
            OLE_RELEASE(pTypeInfo);
            ole_raise(hr, rb_eRuntimeError, "failed to GetContainingTypeLib");
        }
        OLE_RELEASE(pTypeInfo);
        if(TYPE(klass) != T_NIL) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else if(TYPE(ole) == T_STRING) {
        file = typelib_file(ole);
        if (file == Qnil) {
            file = ole;
        }
        pBuf = ole_vstr2wc(file);
        hr = LoadTypeLibEx(pBuf, REGKIND_NONE, &pTypeLib);
        SysFreeString(pBuf);
        if (FAILED(hr))
          ole_raise(hr, eWIN32OLERuntimeError, "failed to LoadTypeLibEx");
        if(TYPE(klass) != T_NIL) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else {
        rb_raise(rb_eTypeError, "1st parameter must be WIN32OLE instance");
    }
    return Qnil;
}

.create_guidObject

Creates GUID.

WIN32OLE.create_guid # => {1CB530F1-F6B1-404D-BCE6-1959BF91F4A8}


3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
# File 'win32ole.c', line 3112

static VALUE
fole_s_create_guid(VALUE self)
{
    GUID guid;
    HRESULT hr;
    OLECHAR bstr[80];
    int len = 0;
    hr = CoCreateGuid(&guid);
    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "failed to create GUID");
    }
    len = StringFromGUID2(&guid, bstr, sizeof(bstr)/sizeof(OLECHAR));
    if (len == 0) {
        rb_raise(rb_eRuntimeError, "failed to create GUID(buffer over)");
    }
    return ole_wc2vstr(bstr, FALSE);
}

.localeObject

Returns current locale id (lcid). The default locale is LOCALE_SYSTEM_DEFAULT.

lcid = WIN32OLE.locale


3051
3052
3053
3054
3055
# File 'win32ole.c', line 3051

static VALUE
fole_s_get_locale(VALUE self)
{
    return INT2FIX(cWIN32OLE_lcid);
}

.locale=(lcid) ⇒ Object

Sets current locale id (lcid).

WIN32OLE.locale = 1033 # set locale English(U.S)
obj = WIN32OLE_VARIANT.new("$100,000", WIN32OLE::VARIANT::VT_CY)


3086
3087
3088
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101
3102
3103
# File 'win32ole.c', line 3086

static VALUE
fole_s_set_locale(VALUE self, VALUE vlcid)
{
    LCID lcid = FIX2INT(vlcid);
    if (lcid_installed(lcid)) {
        cWIN32OLE_lcid = lcid;
    } else {
        switch (lcid) {
        case LOCALE_SYSTEM_DEFAULT:
        case LOCALE_USER_DEFAULT:
            cWIN32OLE_lcid = lcid;
            break;
        default:
            rb_raise(eWIN32OLERuntimeError, "not installed locale: %u", (unsigned int)lcid);
        }
    }
    return Qnil;
}

.ole_free(aWIN32OLE) ⇒ Object

Invokes Release method of Dispatch interface of WIN32OLE object. You should not use this method because this method exists only for debugging WIN32OLE. The return value is reference counter of OLE object.



2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
# File 'win32ole.c', line 2909

static VALUE
fole_s_free(VALUE self, VALUE obj)
{
    ULONG n = 0;
    struct oledata * pole;
    OLEData_Get_Struct(obj, pole);
    if(pole->pDispatch) {
        if (reference_count(pole) > 0) {
            n = OLE_RELEASE(pole->pDispatch);
        }
    }
    return INT2NUM(n);
}

.ole_initializeObject

:nodoc



3151
3152
3153
3154
3155
3156
# File 'win32ole.c', line 3151

static VALUE
fole_s_ole_initialize(VALUE self)
{
    ole_pure_initialize();
    return Qnil;
}

.ole_reference_count(aWIN32OLE) ⇒ Object

Returns reference counter of Dispatch interface of WIN32OLE object. You should not use this method because this method exists only for debugging WIN32OLE.



2892
2893
2894
2895
2896
2897
2898
# File 'win32ole.c', line 2892

static VALUE
fole_s_reference_count(VALUE self, VALUE obj)
{
    struct oledata * pole;
    OLEData_Get_Struct(obj, pole);
    return INT2NUM(reference_count(pole));
}

.ole_show_help(obj[,helpcontext]) ⇒ Object

Displays helpfile. The 1st argument specifies WIN32OLE_TYPE object or WIN32OLE_METHOD object or helpfile.

excel = WIN32OLE.new('Excel.Application')
typeobj = excel.ole_type
WIN32OLE.ole_show_help(typeobj)


2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
# File 'win32ole.c', line 2955

static VALUE
fole_s_show_help(int argc, VALUE *argv, VALUE self)
{
    VALUE target;
    VALUE helpcontext;
    VALUE helpfile;
    VALUE name;
    HWND  hwnd;
    rb_scan_args(argc, argv, "11", &target, &helpcontext);
    if (rb_obj_is_kind_of(target, cWIN32OLE_TYPE) ||
        rb_obj_is_kind_of(target, cWIN32OLE_METHOD)) {
        helpfile = rb_funcall(target, rb_intern("helpfile"), 0);
        if(strlen(StringValuePtr(helpfile)) == 0) {
            name = rb_ivar_get(target, rb_intern("name"));
            rb_raise(rb_eRuntimeError, "no helpfile of `%s'",
                     StringValuePtr(name));
        }
        helpcontext = rb_funcall(target, rb_intern("helpcontext"), 0);
    } else {
        helpfile = target;
    }
    if (TYPE(helpfile) != T_STRING) {
        rb_raise(rb_eTypeError, "1st parameter must be (String|WIN32OLE_TYPE|WIN32OLE_METHOD)");
    }
    hwnd = ole_show_help(helpfile, helpcontext);
    if(hwnd == 0) {
        rb_raise(rb_eRuntimeError, "failed to open help file `%s'",
                 StringValuePtr(helpfile));
    }
    return Qnil;
}

.ole_uninitializeObject

:nodoc



3159
3160
3161
3162
3163
3164
# File 'win32ole.c', line 3159

static VALUE
fole_s_ole_uninitialize(VALUE self)
{
    ole_pure_uninitialize();
    return Qnil;
}

Instance Method Details

#[](a1, a2, ...) ⇒ Object

Returns the value of Collection specified by a1, a2,....

dict = WIN32OLE.new('Scripting.Dictionary')
dict.add('ruby', 'Ruby')
puts dict['ruby'] # => 'Ruby' (same as `puts dict.item('ruby')')

Remark: You can not use this method to get the property.

excel = WIN32OLE.new('Excel.Application')
# puts excel['Visible']  This is error !!!
puts excel.Visible # You should to use this style to get the property.


3882
3883
3884
3885
3886
# File 'win32ole.c', line 3882

static VALUE
fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
}

#[]=(a1, a2, ...) ⇒ Object

Sets the value to WIN32OLE object specified by a1, a2, ...

dict = WIN32OLE.new('Scripting.Dictionary')
dict.add('ruby', 'RUBY')
dict['ruby'] = 'Ruby'
puts dict['ruby'] # => 'Ruby'

Remark: You can not use this method to set the property value.

excel = WIN32OLE.new('Excel.Application')
# excel['Visible'] = true # This is error !!!
excel.Visible = true # You should to use this style to set the property.


3841
3842
3843
3844
3845
# File 'win32ole.c', line 3841

static VALUE
fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
}

#_getproperty(dispid, args, types) ⇒ Object

Runs the early binding method to get property. The 1st argument specifies dispatch ID, the 2nd argument specifies the array of arguments, the 3rd argument specifies the array of the type of arguments.

excel = WIN32OLE.new('Excel.Application')
puts excel._getproperty(558, [], []) # same effect as puts excel.visible


3799
3800
3801
3802
3803
# File 'win32ole.c', line 3799

static VALUE
fole_getproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYGET);
}

#_invoke(dispid, args, types) ⇒ Object

Runs the early binding method. The 1st argument specifies dispatch ID, the 2nd argument specifies the array of arguments, the 3rd argument specifies the array of the type of arguments.

excel = WIN32OLE.new('Excel.Application')
excel._invoke(302, [], []) #  same effect as excel.Quit


3781
3782
3783
3784
3785
# File 'win32ole.c', line 3781

static VALUE
fole_invoke2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_METHOD);
}

#_setproperty(dispid, args, types) ⇒ Object

Runs the early binding method to set property. The 1st argument specifies dispatch ID, the 2nd argument specifies the array of arguments, the 3rd argument specifies the array of the type of arguments.

excel = WIN32OLE.new('Excel.Application')
excel._setproperty(558, [true], [WIN32OLE::VARIANT::VT_BOOL]) # same effect as excel.visible = true


3817
3818
3819
3820
3821
# File 'win32ole.c', line 3817

static VALUE
fole_setproperty2(VALUE self, VALUE dispid, VALUE args, VALUE types)
{
    return ole_invoke2(self, dispid, args, types, DISPATCH_PROPERTYPUT);
}

#each {|i| ... } ⇒ Object

Iterates over each item of OLE collection which has IEnumVARIANT interface.

excel = WIN32OLE.new('Excel.Application')
book = excel.workbooks.add
sheets = book.worksheets(1)
cells = sheets.cells("A1:A5")
cells.each do |cell|
  cell.value = 10
end

Yields:

  • (i)


4003
4004
4005
4006
4007
4008
4009
4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
4025
4026
4027
4028
4029
4030
4031
4032
4033
4034
4035
4036
4037
4038
4039
4040
4041
4042
4043
4044
4045
4046
4047
4048
4049
4050
4051
4052
4053
4054
4055
4056
4057
4058
# File 'win32ole.c', line 4003

static VALUE
fole_each(VALUE self)
{
    LCID    lcid = cWIN32OLE_lcid;

    struct oledata *pole;

    unsigned int argErr;
    EXCEPINFO excepinfo;
    DISPPARAMS dispParams;
    VARIANT result;
    HRESULT hr;
    IEnumVARIANT *pEnum = NULL;
    void *p;

    RETURN_ENUMERATOR(self, 0, 0);

    VariantInit(&result);
    dispParams.rgvarg = NULL;
    dispParams.rgdispidNamedArgs = NULL;
    dispParams.cNamedArgs = 0;
    dispParams.cArgs = 0;
    memset(&excepinfo, 0, sizeof(excepinfo));

    OLEData_Get_Struct(self, pole);
    hr = pole->pDispatch->lpVtbl->Invoke(pole->pDispatch, DISPID_NEWENUM,
                                         &IID_NULL, lcid,
                                         DISPATCH_METHOD | DISPATCH_PROPERTYGET,
                                         &dispParams, &result,
                                         &excepinfo, &argErr);

    if (FAILED(hr)) {
        VariantClear(&result);
        ole_raise(hr, eWIN32OLERuntimeError, "failed to get IEnum Interface");
    }

    if (V_VT(&result) == VT_UNKNOWN) {
        hr = V_UNKNOWN(&result)->lpVtbl->QueryInterface(V_UNKNOWN(&result),
                                                        &IID_IEnumVARIANT,
                                                        &p);
        pEnum = p;
    } else if (V_VT(&result) == VT_DISPATCH) {
        hr = V_DISPATCH(&result)->lpVtbl->QueryInterface(V_DISPATCH(&result),
                                                         &IID_IEnumVARIANT,
                                                         &p);
        pEnum = p;
    }
    if (FAILED(hr) || !pEnum) {
        VariantClear(&result);
        ole_raise(hr, rb_eRuntimeError, "failed to get IEnum Interface");
    }

    VariantClear(&result);
    rb_ensure(ole_each_sub, (VALUE)pEnum, ole_ienum_free, (VALUE)pEnum);
    return Qnil;
}

#invoke(method, [arg1,...]) ⇒ Object

Runs OLE method. The first argument specifies the method name of OLE Automation object. The others specify argument of the method. If you can not execute method directly, then use this method instead.

excel = WIN32OLE.new('Excel.Application')
excel.invoke('Quit')  # => same as excel.Quit


3573
3574
3575
3576
3577
# File 'win32ole.c', line 3573

static VALUE
fole_invoke(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
}

#ole_activex_initializeQnil

Initialize WIN32OLE object(ActiveX Control) by calling IPersistMemory::InitNew.

Before calling OLE method, some kind of the ActiveX controls created with MFC should be initialized by calling IPersistXXX::InitNew.

If and only if you received the exception "HRESULT error code: 0x8000ffff catastrophic failure", try this method before invoking any ole_method.

obj = WIN32OLE.new("ProgID_or_GUID_of_ActiveX_Control")
obj.ole_activex_initialize
obj.method(...)

Returns:

  • (Qnil)


4765
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784
4785
4786
4787
4788
4789
4790
4791
# File 'win32ole.c', line 4765

static VALUE
fole_activex_initialize(VALUE self)
{
    struct oledata *pole;
    IPersistMemory *pPersistMemory;
    void *p;

    HRESULT hr = S_OK;

    OLEData_Get_Struct(self, pole);

    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &IID_IPersistMemory, &p);
    pPersistMemory = p;
    if (SUCCEEDED(hr)) {
        hr = pPersistMemory->lpVtbl->InitNew(pPersistMemory);
        OLE_RELEASE(pPersistMemory);
        if (SUCCEEDED(hr)) {
            return Qnil;
        }
    }

    if (FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError, "fail to initialize ActiveX control");
    }

    return Qnil;
}

#ole_freeObject

invokes Release method of Dispatch interface of WIN32OLE object. Usually, you do not need to call this method because Release method called automatically when WIN32OLE object garbaged.



3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
# File 'win32ole.c', line 3954

static VALUE
fole_free(VALUE self)
{
    struct oledata *pole;
    rb_secure(4);
    OLEData_Get_Struct(self, pole);
    OLE_FREE(pole->pDispatch);
    pole->pDispatch = NULL;
    return Qnil;
}

#ole_func_methodsObject

Returns the array of WIN32OLE_METHOD object . The element of the array is property (settable) of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_func_methods


4346
4347
4348
4349
4350
# File 'win32ole.c', line 4346

static VALUE
fole_func_methods(VALUE self)
{
    return ole_methods( self, INVOKE_FUNC);
}

#ole_get_methodsObject

Returns the array of WIN32OLE_METHOD object . The element of the array is property (gettable) of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_get_methods


4313
4314
4315
4316
4317
# File 'win32ole.c', line 4313

static VALUE
fole_get_methods(VALUE self)
{
    return ole_methods( self, INVOKE_PROPERTYGET);
}

#ole_method_help(method) ⇒ Object Also known as: ole_method_help

Returns WIN32OLE_METHOD object corresponding with method specified by 1st argument.

excel = WIN32OLE.new('Excel.Application')
method = excel.ole_method_help('Quit')


4723
4724
4725
4726
4727
4728
4729
4730
4731
4732
4733
4734
4735
4736
4737
4738
4739
4740
4741
4742
4743
# File 'win32ole.c', line 4723

static VALUE
fole_method_help(VALUE self, VALUE cmdname)
{
    ITypeInfo *pTypeInfo;
    HRESULT hr;
    struct oledata *pole;
    VALUE method, obj;

    SafeStringValue(cmdname);
    OLEData_Get_Struct(self, pole);
    hr = typeinfo_from_ole(pole, &pTypeInfo);
    if(FAILED(hr))
        ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");
    method = folemethod_s_allocate(cWIN32OLE_METHOD);
    obj = olemethod_from_typeinfo(method, pTypeInfo, cmdname);
    OLE_RELEASE(pTypeInfo);
    if (obj == Qnil)
        rb_raise(eWIN32OLERuntimeError, "not found %s",
                 StringValuePtr(cmdname));
    return obj;
}

#ole_methodsObject

Returns the array of WIN32OLE_METHOD object. The element is OLE method of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
methods = excel.ole_methods


4297
4298
4299
4300
4301
# File 'win32ole.c', line 4297

static VALUE
fole_methods(VALUE self)
{
    return ole_methods( self, INVOKE_FUNC | INVOKE_PROPERTYGET | INVOKE_PROPERTYPUT | INVOKE_PROPERTYPUTREF);
}

#ole_put_methodsObject

Returns the array of WIN32OLE_METHOD object . The element of the array is property (settable) of WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
properties = excel.ole_put_methods


4329
4330
4331
4332
4333
# File 'win32ole.c', line 4329

static VALUE
fole_put_methods(VALUE self)
{
    return ole_methods( self, INVOKE_PROPERTYPUT|INVOKE_PROPERTYPUTREF);
}

#ole_query_interface(iid) ⇒ WIN32OLE object

Returns WIN32OLE object for a specific dispatch or dual interface specified by iid.

ie = WIN32OLE.new('InternetExplorer.Application')
ie_web_app = ie.ole_query_interface('{0002DF05-0000-0000-C000-000000000046}') # => WIN32OLE object for dispinterface IWebBrowserApp

Returns:



4469
4470
4471
4472
4473
4474
4475
4476
4477
4478
4479
4480
4481
4482
4483
4484
4485
4486
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501
4502
4503
# File 'win32ole.c', line 4469

static VALUE
fole_query_interface(VALUE self, VALUE str_iid)
{
    HRESULT hr;
    OLECHAR *pBuf;
    IID iid;
    struct oledata *pole;
    IDispatch *pDispatch;
    void *p;

    pBuf  = ole_vstr2wc(str_iid);
    hr = CLSIDFromString(pBuf, &iid);
    SysFreeString(pBuf);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "invalid iid: `%s'",
                  StringValuePtr(str_iid));
    }

    OLEData_Get_Struct(self, pole);
    if(!pole->pDispatch) {
        rb_raise(rb_eRuntimeError, "failed to get dispatch interface");
    }

    hr = pole->pDispatch->lpVtbl->QueryInterface(pole->pDispatch, &iid,
                                                 &p);
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to get interface `%s'",
                  StringValuePtr(str_iid));
    }

    pDispatch = p;
    return create_win32ole_object(cWIN32OLE, pDispatch, 0, 0);
}

#ole_respond_to?(method) ⇒ Boolean

Returns true when OLE object has OLE method, otherwise returns false.

ie = WIN32OLE.new('InternetExplorer.Application')
ie.ole_respond_to?("gohome") => true

Returns:

  • (Boolean)

Returns:

  • (Boolean)


4514
4515
4516
4517
4518
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531
4532
4533
4534
# File 'win32ole.c', line 4514

static VALUE
fole_respond_to(VALUE self, VALUE method)
{
    struct oledata *pole;
    BSTR wcmdname;
    DISPID DispID;
    HRESULT hr;
    rb_secure(4);
    if(TYPE(method) != T_STRING && TYPE(method) != T_SYMBOL) {
	rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
    }
    if (TYPE(method) == T_SYMBOL) {
	method = rb_sym_to_s(method);
    }
    OLEData_Get_Struct(self, pole);
    wcmdname = ole_vstr2wc(method);
    hr = pole->pDispatch->lpVtbl->GetIDsOfNames( pole->pDispatch, &IID_NULL,
	    &wcmdname, 1, cWIN32OLE_lcid, &DispID);
    SysFreeString(wcmdname);
    return SUCCEEDED(hr) ? Qtrue : Qfalse;
}

#ole_typeObject Also known as: ole_obj_help

Returns WIN32OLE_TYPE object.

excel = WIN32OLE.new('Excel.Application')
tobj = excel.ole_type


4385
4386
4387
4388
4389
4390
4391
4392
4393
4394
4395
4396
4397
4398
4399
4400
4401
4402
4403
4404
4405
4406
# File 'win32ole.c', line 4385

static VALUE
fole_type(VALUE self)
{
    ITypeInfo *pTypeInfo;
    HRESULT hr;
    struct oledata *pole;
    LCID  lcid = cWIN32OLE_lcid;
    VALUE type = Qnil;

    OLEData_Get_Struct(self, pole);

    hr = pole->pDispatch->lpVtbl->GetTypeInfo( pole->pDispatch, 0, lcid, &pTypeInfo );
    if(FAILED(hr)) {
        ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
    }
    type = ole_type_from_itypeinfo(pTypeInfo);
    OLE_RELEASE(pTypeInfo);
    if (type == Qnil) {
        rb_raise(rb_eRuntimeError, "failed to create WIN32OLE_TYPE obj from ITypeInfo");
    }
    return type;
}

#ole_typelibThe WIN32OLE_TYPELIB object

Returns the WIN32OLE_TYPELIB object. The object represents the type library which contains the WIN32OLE object.

excel = WIN32OLE.new('Excel.Application')
tlib = excel.ole_typelib
puts tlib.name  # -> 'Microsoft Excel 9.0 Object Library'

Returns:



4436
4437
4438
4439
4440
4441
4442
4443
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454
4455
4456
4457
# File 'win32ole.c', line 4436

static VALUE
fole_typelib(VALUE self)
{
    struct oledata *pole;
    HRESULT hr;
    ITypeInfo *pTypeInfo;
    LCID  lcid = cWIN32OLE_lcid;
    VALUE vtlib = Qnil;

    OLEData_Get_Struct(self, pole);
    hr = pole->pDispatch->lpVtbl->GetTypeInfo(pole->pDispatch,
                                              0, lcid, &pTypeInfo);
    if(FAILED(hr)) {
        ole_raise(hr, rb_eRuntimeError, "failed to GetTypeInfo");
    }
    vtlib = ole_typelib_from_itypeinfo(pTypeInfo);
    OLE_RELEASE(pTypeInfo);
    if (vtlib == Qnil) {
        rb_raise(rb_eRuntimeError, "failed to get type library info.");
    }
    return vtlib;
}

#setproperty('property', [arg1, arg2,...]) ⇒ Object

Sets property of OLE object. When you want to set property with argument, you can use this method.

excel = WIN32OLE.new('Excel.Application')
excel.Visible = true
book = excel.workbooks.add
sheet = book.worksheets(1)
sheet.setproperty('Cells', 1, 2, 10) # => The B1 cell value is 10.


3860
3861
3862
3863
3864
# File 'win32ole.c', line 3860

static VALUE
fole_setproperty(int argc, VALUE *argv, VALUE self)
{
    return ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
}