【问题标题】:How to set byte[] property of ActiveX component from Javascript?如何从 Javascript 设置 ActiveX 组件的 byte[] 属性?
【发布时间】:2017-02-24 15:40:28
【问题描述】:

我想设置 RTF 格式的日历条目,但不知道如何将 byte[] 传递给 ActiveX 对象,即RTFBody 属性。

以下代码在设置了一些内容后读取RTFBody 属性 - 因此读取字节[] 是有效的,但是当我尝试写回完全相同的内容(+ 尾随 0)时,U/Int8Array 都没有Scripting.Directory 也不起作用。

也许可以解决一些.NET objects,但我不知道如何实例化那些非ActiveX 组件。替代解决方案不应要求编写格式脚本,例如“转到第 2 行并使其变为粗体”,即我喜欢通过模板生成 rtf,并且只将结果粘贴到日历对象中。

我知道这最终必须以Windows-1252 编码,但首先我只想看到相同的字节被成功写入。该脚本在 HTA 上下文中执行 - 因此脚本安全不是问题。

<html>
    <head>
        <hta:application id="foo" applicationname="foo" version="1" navigable="yes" sysMenu="yes"></hta>
    </head>
    <script language="JavaScript" type="text/javascript">
function doit2() {
    var rtfBody = 
        "{\\rtf1\\ansi\\ansicpg1252\\deff0\\nouicompat\\deflang1031{\\fonttbl{\\f0\\fswiss\\fcharset0 Calibri;}}\r\n"+
        "{\\*\\generator Riched20 14.0.7155.5000;}{\\*\\mmathPr\\mwrapIndent1440}\\viewkind4\\uc1\r\n"+
        "\\pard\\f0\\fs22 bla\\par\r\n"+
        "}\r\n";
    // https://github.com/mathiasbynens/windows-1252
    var rtfBody1252 = rtfBody; // windows1252.encode(rtfBody);

    var dict = new ActiveXObject("Scripting.Dictionary");

    for (var i = 0; i < rtfBody1252.length; i++) {
        dict.add(i, rtfBody1252.charCodeAt(i));
    }

    dict.add(rtfBody1252.length, 0);

    // Alternative setting via U/Int8Array also doesn't work ...
    // var buf = new ArrayBuffer(rtfBody1252.length+1);
    // var bufView = new Int8Array(buf);
    // for (var i=0, strLen=rtfBody1252.length; i<strLen; i++) {
    //  bufView[i] = rtfBody1252.charCodeAt(i);
    // }
    // bufView[rtfBody1252.length] = 0;

    var myOlApp = new ActiveXObject("Outlook.Application");
    var nameSpace = myOlApp.GetNameSpace("MAPI");
    var recipient = nameSpace.CreateRecipient("user@host.com");
    var cFolder = nameSpace.GetSharedDefaultFolder(recipient,9);

    var appointment = cFolder.Items.Add(1);
    appointment.Subject = "Subject";
    appointment.Location = "Location";
    appointment.Start = "22.02.2017 17:00";
    appointment.Duration = "120";
    appointment.Categories = "deleteme";
    appointment.Body = "bla";

    var va = new VBArray(appointment.RTFBody).toArray();
    var bla = String.fromCharCode.apply(null, va);
    document.forms[0].output.value = bla;
    // var bla2 = windows1252.decode(bla);

    appointment.RTFBody = dict.Items();
    appointment.ReminderSet = "true";
    appointment.Save();
    entryId = appointment.EntryId;
    appointment.Display();

    delete appointment;
    delete cFolder;
    delete recipient;
    delete nameSpace;
    delete myOlApp;
}
    </script>
    <body>
        <form>
            <input type="button" onclick="doit2()" value="doit"/>
            <textarea name="output" rows="5" cols="50"></textarea>
        </form>
    </body>
</html>

【问题讨论】:

标签: javascript vba outlook activex typeconverter


【解决方案1】:

使用后期绑定设置 MailItem.RtfBody 属性存在一个已知问题(这是 JS 使用的 - IDispatch.GetIDsOfNames / Invoke)。提前出价(通过 v-table 调用)效果很好。

上次我听说过这个,没有变通办法,至少在你使用 JS 时没有。您可以尝试使用Redemption(它在其 Safe*Item 对象和 RDOMail 对象上公开 RtfBody 属性),但随后您需要在运行脚本的每台机器上安装它。..

【讨论】:

  • 感谢您指出这一点-在寻找解决方案时,我通过绑定解释来了,但不明白。现在有了新的搜索表达式,我找到了your post - 不幸的是,这里不能提供赎回选项。也许提到的扩展 MAPI 有任何帮助......但可能我只会保留未格式化的内容......
  • ...正如您在site 中所述...“赎回使用扩展 MAPI(不受安全补丁影响,因为脚本语言无法访问它)”:(
  • 是的,JS不能做Extended MAPI。甚至 C# 也不能使用它(至少不容易),
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
  • 2010-09-20
  • 1970-01-01
相关资源
最近更新 更多