Class: WIN32OLE

Inherits:
Object
  • Object
show all
Defined in:
ext/win32ole/win32ole.c,
ext/win32ole/win32ole.c,
lib/win32ole.rb,
lib/win32ole/property.rb

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: VariantType Classes: Event, Method, Param, Property, QueryInterfaceError, Record, RuntimeError, Type, TypeLib, Variable, 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 referring 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

RB_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
VARIANT =

:VariantType, for the backward compatibility

Alias of WIN32OLE

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#new(server, [host]) ⇒ WIN32OLE object #new(server, license: 'key') ⇒ 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. If :license keyword argument is provided, IClassFactory2::CreateInstanceLic is used to create instance of licensed server.

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

Overloads:

  • #new(server, [host]) ⇒ WIN32OLE object
  • #new(server, license: 'key') ⇒ WIN32OLE object


2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
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
# File 'ext/win32ole/win32ole.c', line 2393

static VALUE
fole_initialize(int argc, VALUE *argv, VALUE self)
{
    VALUE svr_name;
    VALUE host;
    VALUE others;
    VALUE opts;
    HRESULT hr;
    CLSID   clsid;
    OLECHAR *pBuf;
    OLECHAR *key_buf;
    IDispatch *pDispatch;
    IClassFactory2 * pIClassFactory2;
    void *p;
    static ID keyword_ids[1];
    VALUE kwargs[1];

    rb_call_super(0, 0);
    rb_scan_args(argc, argv, "11*:", &svr_name, &host, &others, &opts);

    StringValue(svr_name);
    if (!NIL_P(host)) {
        StringValue(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));
    }

    if (!keyword_ids[0]) {
        keyword_ids[0] = rb_intern_const("license");
    }
    rb_get_kwargs(opts, keyword_ids, 0, 1, kwargs);

    if (kwargs[0] == Qundef) {
        /* get IDispatch interface */
        hr = CoCreateInstance(
            &clsid,
            NULL,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
            &IID_IDispatch,
            &p
        );
    } else {
        hr = CoGetClassObject(
            &clsid,
            CLSCTX_INPROC_SERVER | CLSCTX_LOCAL_SERVER,
            NULL,
            &IID_IClassFactory2,
            (LPVOID)&pIClassFactory2
        );
        if (hr == S_OK) {
            key_buf = ole_vstr2wc(kwargs[0]);
            hr = pIClassFactory2->lpVtbl->CreateInstanceLic(pIClassFactory2, NULL, NULL, &IID_IDispatch, key_buf, &p);
            SysFreeString(key_buf);
            OLE_RELEASE(pIClassFactory2);
        }
    }
    if(FAILED(hr)) {
        ole_raise(hr, eWIN32OLERuntimeError,
                  "failed to create WIN32OLE object from `%s'",
                  StringValuePtr(svr_name));
    }
    pDispatch = p;

    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.



3283
3284
3285
3286
3287
3288
3289
3290
3291
3292
3293
3294
3295
3296
3297
3298
3299
3300
3301
3302
3303
3304
3305
3306
3307
3308
3309
3310
3311
3312
3313
# File 'ext/win32ole/win32ole.c', line 3283

static VALUE
fole_missing(int argc, VALUE *argv, VALUE self)
{
    VALUE mid, org_mid, sym, v;
    const char* mname;
    long n;
    rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
    mid = org_mid = argv[0];
    sym = rb_check_symbol(&mid);
    if (!NIL_P(sym)) mid = rb_sym2str(sym);
    mname = StringValueCStr(mid);
    if(!mname) {
        rb_raise(rb_eRuntimeError, "fail: unknown method or property");
    }
    n = RSTRING_LEN(mid);
    if(mname[n-1] == '=') {
        rb_check_arity(argc, 2, 2);
        argv[0] = rb_enc_associate(rb_str_subseq(mid, 0, n-1), cWIN32OLE_enc);

        return ole_propertyput(self, argv[0], argv[1]);
    }
    else {
        argv[0] = rb_enc_associate(rb_str_dup(mid), cWIN32OLE_enc);
        v = ole_invoke(argc, argv, self, DISPATCH_METHOD|DISPATCH_PROPERTYGET, FALSE);
        if (v == rb_eNoMethodError) {
            argv[0] = org_mid;
            return rb_call_super(argc, argv);
        }
        return v;
    }
}

Class Method Details

.codepageObject

Returns current codepage.

WIN32OLE.codepage # => WIN32OLE::CP_ACP


2171
2172
2173
2174
2175
# File 'ext/win32ole/win32ole.c', line 2171

static VALUE
fole_s_get_code_page(VALUE self)
{
    return RB_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


2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
# File 'ext/win32ole/win32ole.c', line 2208

static VALUE
fole_s_set_code_page(VALUE self, VALUE vcp)
{
    UINT cp = RB_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.


1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
# File 'ext/win32ole/win32ole.c', line 1908

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

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


1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
# File 'ext/win32ole/win32ole.c', line 1985

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, eWIN32OLEQueryInterfaceError, "failed to GetTypeInfo");
        }
        hr = pTypeInfo->lpVtbl->GetContainingTypeLib(pTypeInfo, &pTypeLib, &index);
        if(FAILED(hr)) {
            OLE_RELEASE(pTypeInfo);
            ole_raise(hr, eWIN32OLEQueryInterfaceError, "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}


2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
# File 'ext/win32ole/win32ole.c', line 2289

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


2228
2229
2230
2231
2232
# File 'ext/win32ole/win32ole.c', line 2228

static VALUE
fole_s_get_locale(VALUE self)
{
    return RB_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)


2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
# File 'ext/win32ole/win32ole.c', line 2263

static VALUE
fole_s_set_locale(VALUE self, VALUE vlcid)
{
    LCID lcid = RB_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.



2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
# File 'ext/win32ole/win32ole.c', line 2086

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 RB_INT2NUM(n);
}

.ole_initializeObject

:nodoc:



2314
2315
2316
2317
2318
2319
# File 'ext/win32ole/win32ole.c', line 2314

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.



2069
2070
2071
2072
2073
2074
2075
# File 'ext/win32ole/win32ole.c', line 2069

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


2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
# File 'ext/win32ole/win32ole.c', line 2132

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:



2322
2323
2324
2325
2326
2327
# File 'ext/win32ole/win32ole.c', line 2322

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.


3096
3097
3098
3099
3100
3101
3102
3103
3104
# File 'ext/win32ole/win32ole.c', line 3096

static VALUE
fole_getproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYGET, TRUE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}

#[]=(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.


3047
3048
3049
3050
3051
3052
3053
3054
3055
# File 'ext/win32ole/win32ole.c', line 3047

static VALUE
fole_setproperty_with_bracket(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, TRUE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}

#_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


3005
3006
3007
3008
3009
# File 'ext/win32ole/win32ole.c', line 3005

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


2987
2988
2989
2990
2991
# File 'ext/win32ole/win32ole.c', line 2987

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


3023
3024
3025
3026
3027
# File 'ext/win32ole/win32ole.c', line 3023

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)


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
3274
3275
# File 'ext/win32ole/win32ole.c', line 3220

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, eWIN32OLEQueryInterfaceError, "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, eWIN32OLEQueryInterfaceError, "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


2776
2777
2778
2779
2780
2781
2782
2783
2784
# File 'ext/win32ole/win32ole.c', line 2776

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

#methods(*args) ⇒ Object

By overriding Object#methods, WIN32OLE might work well with did_you_mean gem. This is experimental.

require 'win32ole'
dict = WIN32OLE.new('Scripting.Dictionary')
dict.Ade('a', 1)
#=> Did you mean?  Add


20
21
22
# File 'lib/win32ole.rb', line 20

def methods(*args)
  super + ole_methods_safely.map(&:name).map(&:to_sym)
end

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


3816
3817
3818
3819
3820
3821
3822
3823
3824
3825
3826
3827
3828
3829
3830
3831
3832
3833
3834
3835
3836
3837
3838
3839
3840
3841
3842
# File 'ext/win32ole/win32ole.c', line 3816

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.



3172
3173
3174
3175
3176
3177
3178
3179
3180
# File 'ext/win32ole/win32ole.c', line 3172

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


3435
3436
3437
3438
3439
# File 'ext/win32ole/win32ole.c', line 3435

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


3402
3403
3404
3405
3406
# File 'ext/win32ole/win32ole.c', line 3402

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


3773
3774
3775
3776
3777
3778
3779
3780
3781
3782
3783
3784
3785
3786
3787
3788
3789
3790
3791
3792
3793
3794
# File 'ext/win32ole/win32ole.c', line 3773

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, eWIN32OLEQueryInterfaceError, "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


3386
3387
3388
3389
3390
# File 'ext/win32ole/win32ole.c', line 3386

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


3418
3419
3420
3421
3422
# File 'ext/win32ole/win32ole.c', line 3418

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:



3517
3518
3519
3520
3521
3522
3523
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
# File 'ext/win32ole/win32ole.c', line 3517

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, eWIN32OLEQueryInterfaceError,
                  "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)


3562
3563
3564
3565
3566
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577
3578
3579
3580
3581
# File 'ext/win32ole/win32ole.c', line 3562

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_sym2str(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


3450
3451
3452
3453
3454
3455
3456
3457
3458
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471
# File 'ext/win32ole/win32ole.c', line 3450

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, eWIN32OLEQueryInterfaceError, "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:

  • (The WIN32OLE_TYPELIB object)


3484
3485
3486
3487
3488
3489
3490
3491
3492
3493
3494
3495
3496
3497
3498
3499
3500
3501
3502
3503
3504
3505
# File 'ext/win32ole/win32ole.c', line 3484

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, eWIN32OLEQueryInterfaceError, "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.


3070
3071
3072
3073
3074
3075
3076
3077
3078
# File 'ext/win32ole/win32ole.c', line 3070

static VALUE
fole_setproperty(int argc, VALUE *argv, VALUE self)
{
    VALUE v = ole_invoke(argc, argv, self, DISPATCH_PROPERTYPUT, FALSE);
    if (v == rb_eNoMethodError) {
        return rb_call_super(argc, argv);
    }
    return v;
}