Class: WIN32OLE

Inherits:
Object
  • Object
show all
Defined in:
win32ole.c,
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 or WIN32OLE_VARIANT object.
If you want to get the result value of argument passed by reference,
you can use WIN32OLE::ARGV or WIN32OLE_VARIANT.

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

or

  refargv3 = WIN32OLE_VARIANT.new(XXX,
              WIN32OLE::VARIANT::VT_BYREF|WIN32OLE::VARIANT::VT_XXX)
  oleobj.method(arg1, arg2, refargv3)
  p refargv3.value # the value of refargv3 after called oleobj.method.

Defined Under Namespace

Modules: VARIANT

Constant Summary collapse

VERSION =

Version string of WIN32OLE.

rb_str_new2(WIN32OLE_VERSION)
ARGV =

void calcsum(int a, int b, out int c) {

    c = a + b;
}

then, the Ruby OLE(COM) client script to retrieve the value of argument c after invoking calcsum method is following:

a = 10
b = 20
c = 0
comserver.calcsum(a, b, c)
p c # => 0
p WIN32OLE::ARGV # => [10, 20, 30]

You can use WIN32OLE_VARIANT object to retrieve the value of reference arguments instead of refering WIN32OLE::ARGV.

After invoking OLE methods with reference arguments, you can access
the value of arguments by using ARGV.

If the method of OLE(COM) server written by C#.NET is following
CP_ACP =

ANSI code page. See WIN32OLE.codepage and WIN32OLE.codepage=.

0
CP_OEMCP =

OEM code page. See WIN32OLE.codepage and WIN32OLE.codepage=.

1
CP_MACCP =

2

INT2FIX(CP_MACCP)
CP_THREAD_ACP =

current thread ANSI code page. See WIN32OLE.codepage and WIN32OLE.codepage=.

3
CP_SYMBOL =

symbol code page. See WIN32OLE.codepage and WIN32OLE.codepage=.

42
CP_UTF7 =

UTF-7 code page. See WIN32OLE.codepage and WIN32OLE.codepage=.

65000
CP_UTF8 =

UTF-8 code page. See WIN32OLE.codepage and WIN32OLE.codepage=.

65001
LOCALE_SYSTEM_DEFAULT =

default locale for the operating system. See WIN32OLE.locale and WIN32OLE.locale=.

0x0800
LOCALE_USER_DEFAULT =

default locale for the user or process. See WIN32OLE.locale and WIN32OLE.locale=.

0x0400

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.

2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
# File 'win32ole.c', line 2439

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_call_super(0, 0);
    rb_scan_args(argc, argv, "11*", &svr_name, &host, &others);

    StringValue(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)) {
        StringValue(host);
        if (rb_safe_level() > 0 && OBJ_TAINTED(host)) {
            rb_raise(rb_eSecurityError, "insecure object creation - `%s'",
                     StringValuePtr(host));
        }
        return ole_create_dcom(self, svr_name, host, others);
    }

    /* 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.


3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
3314
3315
3316
3317
3318
3319
3320
# File 'win32ole.c', line 3292

static VALUE
fole_missing(int argc, VALUE *argv, VALUE self)
{
    ID id;
    const char* mname;
    size_t n;
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    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 SIZEOF_SIZE_T > SIZEOF_LONG
    if (n >= LONG_MAX) {
	rb_raise(rb_eRuntimeError, "too long method or property name");
    }
#endif
    if(mname[n-1] == '=') {
        rb_check_arity(argc, 2, 2);
        argv[0] = rb_enc_str_new(mname, (long)(n-1), cWIN32OLE_enc);

        return ole_propertyput(self, argv[0], argv[1]);
    }
    else {
        argv[0] = rb_enc_str_new(mname, (long)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

2221
2222
2223
2224
2225
# File 'win32ole.c', line 2221

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

2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
# File 'win32ole.c', line 2258

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.

1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
# File 'win32ole.c', line 1954

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;

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

    rb_scan_args(argc, argv, "1*", &svr_name, &others);
    StringValue(svr_name);
    if (rb_safe_level() > 0 && OBJ_TAINTED(svr_name)) {
        rb_raise(rb_eSecurityError, "insecure 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 variable 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

2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
# File 'win32ole.c', line 2035

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

    rb_scan_args(argc, argv, "11", &ole, &klass);
    if (!RB_TYPE_P(klass, T_CLASS) &&
        !RB_TYPE_P(klass, T_MODULE) &&
        !RB_TYPE_P(klass, T_NIL)) {
        rb_raise(rb_eTypeError, "2nd parameter must be Class or Module");
    }
    if (rb_obj_is_kind_of(ole, cWIN32OLE)) {
        pole = oledata_get_struct(ole);
        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(!RB_TYPE_P(klass, T_NIL)) {
            ole_const_load(pTypeLib, klass, self);
        }
        else {
            ole_const_load(pTypeLib, cWIN32OLE, self);
        }
        OLE_RELEASE(pTypeLib);
    }
    else if(RB_TYPE_P(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(!RB_TYPE_P(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}

2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
# File 'win32ole.c', line 2339

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 WIN32OLE::LOCALE_SYSTEM_DEFAULT.

lcid = WIN32OLE.locale

2278
2279
2280
2281
2282
# File 'win32ole.c', line 2278

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)

2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
# File 'win32ole.c', line 2313

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.


2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
# File 'win32ole.c', line 2136

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

.ole_initializeObject

:nodoc:


2364
2365
2366
2367
2368
2369
# File 'win32ole.c', line 2364

static VALUE
fole_s_ole_initialize(VALUE self)
{
    ole_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.


2119
2120
2121
2122
2123
2124
2125
# File 'win32ole.c', line 2119

static VALUE
fole_s_reference_count(VALUE self, VALUE obj)
{
    struct oledata * pole = NULL;
    pole = oledata_get_struct(obj);
    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)

2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
# File 'win32ole.c', line 2182

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 (!RB_TYPE_P(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:


2372
2373
2374
2375
2376
2377
# File 'win32ole.c', line 2372

static VALUE
fole_s_ole_uninitialize(VALUE self)
{
    ole_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.

3109
3110
3111
3112
3113
# File 'win32ole.c', line 3109

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.

3068
3069
3070
3071
3072
# File 'win32ole.c', line 3068

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

3026
3027
3028
3029
3030
# File 'win32ole.c', line 3026

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

3008
3009
3010
3011
3012
# File 'win32ole.c', line 3008

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

3044
3045
3046
3047
3048
# File 'win32ole.c', line 3044

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)

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
3274
3275
3276
3277
3278
3279
3280
3281
3282
3283
3284
# File 'win32ole.c', line 3229

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

    struct oledata *pole = NULL;

    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));

    pole = oledata_get_struct(self);
    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

2800
2801
2802
2803
2804
# File 'win32ole.c', line 2800

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)

3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
3843
3844
3845
3846
3847
3848
3849
# File 'win32ole.c', line 3823

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

    HRESULT hr = S_OK;

    pole = oledata_get_struct(self);

    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.


3181
3182
3183
3184
3185
3186
3187
3188
3189
# File 'win32ole.c', line 3181

static VALUE
fole_free(VALUE self)
{
    struct oledata *pole = NULL;
    pole = oledata_get_struct(self);
    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

3442
3443
3444
3445
3446
# File 'win32ole.c', line 3442

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

3409
3410
3411
3412
3413
# File 'win32ole.c', line 3409

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')

3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
3795
3796
3797
3798
3799
3800
3801
# File 'win32ole.c', line 3780

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

    SafeStringValue(cmdname);
    pole = oledata_get_struct(self);
    hr = typeinfo_from_ole(pole, &pTypeInfo);
    if(FAILED(hr))
        ole_raise(hr, rb_eRuntimeError, "failed to get ITypeInfo");

    obj = create_win32ole_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

3393
3394
3395
3396
3397
# File 'win32ole.c', line 3393

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

3425
3426
3427
3428
3429
# File 'win32ole.c', line 3425

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:


3524
3525
3526
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537
3538
3539
3540
3541
3542
3543
3544
3545
3546
3547
3548
3549
3550
3551
3552
3553
3554
3555
3556
3557
3558
# File 'win32ole.c', line 3524

static VALUE
fole_query_interface(VALUE self, VALUE str_iid)
{
    HRESULT hr;
    OLECHAR *pBuf;
    IID iid;
    struct oledata *pole = NULL;
    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));
    }

    pole = oledata_get_struct(self);
    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)

3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
3582
3583
3584
3585
3586
3587
3588
# File 'win32ole.c', line 3569

static VALUE
fole_respond_to(VALUE self, VALUE method)
{
    struct oledata *pole = NULL;
    BSTR wcmdname;
    DISPID DispID;
    HRESULT hr;
    if(!RB_TYPE_P(method, T_STRING) && !RB_TYPE_P(method, T_SYMBOL)) {
        rb_raise(rb_eTypeError, "wrong argument type (expected String or Symbol)");
    }
    if (RB_TYPE_P(method, T_SYMBOL)) {
        method = rb_sym_to_s(method);
    }
    pole = oledata_get_struct(self);
    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

3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
# File 'win32ole.c', line 3457

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

    pole = oledata_get_struct(self);

    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:


3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
3506
3507
3508
3509
3510
3511
3512
# File 'win32ole.c', line 3491

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

    pole = oledata_get_struct(self);
    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.

3087
3088
3089
3090
3091
# File 'win32ole.c', line 3087

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