I have checked that question, but I don't understand what happens.

Finally I have used this instruction "openssl rsautl -in fileIn.txt -out fileOut-enc.txt -pubin -inkey public.key -encrypt" using $ZF(-100) and having OpenSSL installed on the server and it works.

I want to do it with Encryption methods, there must be a way to do this with COS and not using shell instructions, right?

Thank you very much for your answer. I don't know what algorithm uses openssl_public_encrypt.

I've tried this:

set json = "{""api_key"":""XXXXX"", ""id"":""1""}"
set file = ##class(%FileCharacterStream).%New()
set file.Filename = "public.key"
set key = file.Read(file.Size) 
set jsonEncrypt = $System.Encryption.RSAEncrypt(json, key)

But it doesn't work, it returns an empty string. I try to see the error using RSAGetLastError() and I don't get anything. The public.key has this format:

-----BEGIN PUBLIC KEY-----
......
......
......
......
-----END PUBLIC KEY-----

The line breaks are LF and it is in UTF-8. What format should the public key be in order to work in Ensemble? I am doing something wrong?

Hello.

I'm having the same problem, when I try to open a BPL class with the Atelier BPL Editor I get this error:

Bad editor input: org.eclipse.ui.part.FileEditorInput(/TEST/bp/Proceso.cls)

And the option "Open diagram editor" is not available.

I have this installed:

Eclipse IDE for JavaScript and Web Developers
Version: Photon Release (4.8.0)
Build id: 20180619-1200

 And the last version of Atelier in the marketplace (1.2).

What can I do? I have a macOS High Sierra v10.13.4, but it happens too on a Windows 10.

Thank you in advance.

Thanks to all of you.

I have extended the original class and tunned the method  %ObjectToJSON like this:

ClassMethod %ObjectToJSON(pObject As %RegisteredObject, ByRef pVisited, pLevel As %Integer = 0, pFormat As %String = "aceloqtw") As %Status
{
    Set tSC = $$$OK
    Try {
        If ((pObject="")||'$IsObject(pObject)||($D(pVisited(pObject)))) {
            // cycle
            Write:pFormat["a"||'pLevel "null"
            Quit
        }
        Set pVisited(pObject) = ""
        Set tClass = $classname(pObject)
        If (tClass = "%ZEN.proxyObject") {
            Set tSC = pObject.%ToJSON(pLevel,pFormat)
            Quit
        }
        Set tLF=$S(pFormat["w":$C(13,10), pFormat["n":$C(10), 1:"")
        If pFormat'=$TR(pFormat,"it123456789") { Set tN=+$ZStrip(pFormat,"<E'N"), $P(tTab,$S(pFormat["t":$C(9),1:" "),1+$S(tN:tN,pFormat["t":1,1:4))="" }
        Else { Set tTab="" }
        Set tIncludeWhitespace = (tLF_tTab'="")
        If (pObject.%Extends("%Collection.AbstractList")) {
            Set tList = pObject
            Set tCount = tList.Count()
            If (pFormat["l" || tCount) {
                Write "["
                For n = 1:1:tCount {
                    Set tValue = tList.GetAt(n)
                    Write:n>1 ","
                    If $IsObject(tValue) {
                        If (tValue.%IsA("%ZEN.proxyObject")) {
                            Set tSC = tValue.%ToJSON(pLevel+1,pFormat)
                            Quit:$$$ISERR(tSC)
                        } Else {
                            Set tSC = ..%ObjectToJSON(tValue,.pVisited, pLevel+1, pFormat)
                            Quit:$$$ISERR(tSC)
                        }
                    } Else {
                        Write $$$ZENJSONVALUE(tValue,pFormat)
                    }
                }
                Quit:$$$ISERR(tSC)
                If tIncludeWhitespace Set tIndent="", $P(tIndent,tTab,pLevel+1)="" Write tLF_tIndent
                Write "]"
            }
            Quit
        }
        ElseIf (pObject.%Extends("%Stream.Object")) {
            Write """"
            #; Initialize stream read length, if needed
            If '$data(tStreamMaxReadLen) Set tStreamMaxReadLen = ($$$MaxLocalLength\2)
            Do pObject.Rewind()
            While 'pObject.AtEnd {
                Write $$$ZENJSONESCAPE(pObject.Read(tStreamMaxReadLen),pFormat)
            }
            Write """"
            Quit
        }
        If pFormat["o" || 'pLevel {
            Set tPropCount = ""
            If (tIncludeWhitespace && pLevel) Set tIndent="", $P(tIndent,tTab,pLevel+1)="" Write $S(pFormat["b":tLF_tIndent,1:" ")
            Write "{"
        } Else {
            Set tPropCount = 0
        }
        If pFormat["c" {
            // add class name to model
            Do nextProp
            Write $$$ZENJSONPAIR("_class",tClass,pFormat)
            // add id for persistent objects
            If (pObject.%IsA("%Library.Persistent")) {
                Do nextProp
                Set tID = pObject.%Id()
                Write $$$ZENJSONPAIR("_id",tID,pFormat)
            }
        }
        #; Special treatment for top-level array: output no matter what
        If pObject.%Extends("%Collection.AbstractArray") {
            #; write out (eligible) array elements/properties
            If pObject.%Extends("%Collection.AbstractArrayOfObj") {
                #; object elements
                Set tKey=""  For { Set tValue = pObject.GetNext(.tKey)  Quit:""=tKey
                    If $IsObject(tValue) {
                        If tValue.%Extends("%Stream.Object")||tValue.%Extends("%IO.I.Stream") {
                            Do tValue.Rewind()
                            If (pFormat["e" || tValue.Size()) {
                                Do nextProp
                                Write $$$ZENJSONPROP(tKey,pFormat)_":"""
                                #; Initialize stream read length, if needed
                                If '$data(tStreamMaxReadLen) Set tStreamMaxReadLen = ($$$MaxLocalLength\2)
                                #; Rewind non-%IO streams if needed
                                If tValue.AtEnd && tValue.%Extends("%Stream.Object") Do tValue.Rewind()
                                While 'tValue.AtEnd {
                                    Write $$$ZENJSONESCAPE(tValue.Read(tStreamMaxReadLen),pFormat)
                                }
                                Write """"
                            }
                        } ElseIf pFormat["o" || ..hasObjContent(tValue,.pVisited,pFormat) {
                            Do nextProp
                            Write $$$ZENJSONPROP(tKey,pFormat)_":"
                            Set tSC = ..%ObjectToJSON(tValue,.pVisited, pLevel+1,pFormat)
                            Quit:$$$ISERR(tSC)
                        }
                    } ElseIf pFormat["a" {
                        Do nextProp
                        Write $$$ZENJSONPROP(tKey,pFormat)_":null"
                    }
                } ; end tKey object array loop
            } Else {
                #; scalar array elements
                Set tKey=""  For { Set tValue = pObject.GetNext(.tKey)  Quit:""=tKey
                    If (pFormat["e") || (tValue'="") {
                        Do nextProp
                        Write $$$ZENJSONPAIR(tKey,tValue,pFormat)
                    }
                } ; end tKey scalar array loop
            }
            If tPropCount'=0 {
                #; either we wrote at least one property or we wrote an empty '{' due to "o" mode or level zero
                If tIncludeWhitespace Set tIndent="", $P(tIndent,tTab,pLevel+1)="" Write tLF_tIndent
                Write "}"
            }
            Quit
        }
        #; else: main object is not a collection
        #; loop over properties using class meta-data
        Do ..getOrderedProps(tClass,.tProps)
        Set tSeq="" For { Set tSeq=$O(tProps(tSeq),1,tPropName)  Quit:""=tSeq
            Set tPrivate = +$$$comMemberKeyGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPprivate)
            Continue:tPrivate||(tPropName["%")
            Set tType = $$$comMemberKeyGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPtype)
            Set tClsType = $$$getClassType(tType)
            Set tClientType = $$$comClassKeyGet(tType,$$$cCLASSclientdatatype)
            Set tCollection = $$$comMemberKeyGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPcollection)
            If (tClsType '= "datatype") {
                #; Check for the case where we have a property declared as a %ListOf**
                If ($classmethod(tType,"%IsA","%Collection.AbstractList")) {
                    Set tCollection = "list"
                    If ($classmethod(tType,"%IsA","%Collection.AbstractListOfDT")) {
                        #; Reset object information for %ListOfDataTypes
                        Set tClientType = "VARCHAR"
                        Set tDataType = ""
                    }
                }
            } Else {
                Set tDataType=$Case(tClientType, "BOOLEAN":"b", "INTEGER":"n","NUMERIC":"n","FLOAT":"n", "TIMESTAMP":"u", "DATE":"d", "TIME":"t", :"")
            }
            Set tMultiDim = 0
            If (tCollection="array") {
                Set tCardinality = $$$comMemberKeyGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPcardinality)
                Set tInverse = $$$comMemberKeyGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPinverse)
                If ((tCardinality'="")&&(tInverse'="")) {
                    // treat relationship as list
                    Set tCollection = "list"
                }
            } ElseIf (tCollection = "") {
                Set tMultiDim = +$$$comMemberKeyGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPmultidimensional)
            }
            Continue:tMultiDim
            Set tValue = $property(pObject,tPropName)
            #; If the value is "" or $c(0) and we are NOT including empty properties, skip if we are not a collection, object or stream
            If (((tValue = "") || (tValue = $c(0))) && (pFormat'["e") && (tCollection = "") && $Case(tClientType, "HANDLE": 0, "CHARACTERSTREAM": 0, "BINARYSTREAM": 0, :1)) {
                Continue
            }
            // Write the property if not inhibited
            If (tCollection="list") {
                // list collection
                If '$IsObject(tValue) {
                    Set tCount = 0
                } Else {
                    Set tList = tValue
                    Set tCount = tList.Count()
                }
                If (pFormat["l" || tCount) {
                    Do nextProp
                    if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                        Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":["
                    } else {
                        Write $$$ZENJSONPROP(tPropName,pFormat)_":["
                    }

                    For n = 1:1:tCount {
                        Set tValue = tList.GetAt(n)
                        Write:n>1 ","
                        If (tClientType = "HANDLE") {
                            #; object items
                            If $IsObject(tValue) {
                                Set tSC = ..%ObjectToJSON(tValue,.pVisited, pLevel+1, pFormat)
                                Quit:$$$ISERR(tSC)
                            } Else {
                                Write "null" ; not conditional because it has to hold the place in the list
                            }
                        } Else {
                            #; scalar list item ; converts $List to empty string!
                            Write $S((tDataType="b")&&(pFormat["e"):$S(tValue=1:"true",tValue=0:"false",1:"null")
                                , (tDataType="b"):$S(tValue:"true",1:"false")
                                , ((tDataType="n")||(pFormat["q"))&&$$$ZENJSISNUM(tValue):$$$ZENJSNUM(tValue)
                                , (tDataType="n")&&(tValue="")&&(pFormat["d"):"null"
                                , ($C(0)=tValue)||$ListValid(tValue):""""""
                                , 1:$$$ZENJSONSTR(tValue,pFormat))
                        }
                    }
                    Write "]"
                }
            }
            ElseIf (tCollection="array") {
                // array collection (object on client)
                If '$IsObject(tValue) {
                    Set tKey = ""
                } Else {
                    Set tArray = tValue
                    Set tKey = tArray.Next("")
                    If pFormat'["o" && (""'=tKey) {
                        #; look ahead to see if there is any content
                        Set tHasArrayContent=0, k=tKey  While (k '= "") { Set tValue = tArray.GetAt(k)
                            If (tClientType = "HANDLE") {
                                If $IsObject(tValue) {
                                    If ..hasObjContent(tValue,.pVisited,pFormat) Set tHasArrayContent=1  Quit
                                } ElseIf (pFormat["a") {
                                    Set tHasArrayContent=1  Quit
                                }
                            } Else {
                                If $S(tDataType="b":1
                                    , $C(0)=tValue||$ListValid(tValue):pFormat["e"
                                    //, "dtu"[tDataType:$S(pFormat["u":$$$ZENJSUSTR(..formatDateTime(tValue,tType,tDataType,pFormat)), 1:$$$ZENJSSTR(..formatDateTime(tValue,tType,tDataType,pFormat)))
                                    , 1:""'=tValue||(pFormat["e")) {
                                    Set tHasArrayContent=1  Quit
                                }
                            }
                            Set k = tArray.Next(k)
                        }
                    }
                }
                If (pFormat["o" || (""'=tKey && tHasArrayContent)) {
                    Do nextProp
                    if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                        Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_": {"
                    } else {
                        Write $$$ZENJSONPROP(tPropName,pFormat)_": {"
                    }

                    Set n = 0
                    While (tKey '= "") { Set tValue = tArray.GetAt(tKey)
                        If (tClientType = "HANDLE") {
                            #; object elements
                            If $IsObject(tValue) {
                                Set n = n+1
                                Write $S(n>1:",",1:"")_$$$ZENJSONPROP(tKey,pFormat)_":"
                                Set tSC = ..%ObjectToJSON(tValue,.pVisited, pLevel+1, pFormat)
                                Quit:$$$ISERR(tSC)
                            } ElseIf (pFormat["a") {
                                Set n = n+1
                                Write $S(n>1:",",1:"")_$$$ZENJSONPROP(tKey,pFormat)_":null"
                            }
                        } Else {
                            #; scalar array item ; converts $List to empty string!
                            Set tStr = $S((tDataType="b")&&(pFormat["e"):$S(tValue=1:"true",tValue=0:"false",1:"null")
                                , (tDataType="b"):$S(tValue:"true",1:"false")
                                , ((tDataType="n")||(pFormat["q"))&&$$$ZENJSISNUM(tValue):$$$ZENJSNUM(tValue)
                                , (tDataType="n")&&(tValue="")&&(pFormat["d"):"null"
                                , ($C(0)=tValue)||$ListValid(tValue):""""""
                                //, "dtu"[tDataType:$S(pFormat["u":$$$ZENJSUSTR(..formatDateTime(tValue,tType,tDataType,pFormat)), 1:$$$ZENJSSTR(..formatDateTime(tValue,tType,tDataType,pFormat)))
                                , 1:$$$ZENJSONSTR(tValue,pFormat))
                            If (pFormat["e") || (tStr'="""""") {
                                Set n = n+1
                                Write $S(n>1:",",1:"")_$$$ZENJSONPROP(tKey,pFormat)_":"_tStr
                            }
                        }
                        Set tKey = tArray.Next(tKey)
                    }
                    Write "}"
                }
            }
            ElseIf (tClientType = "HANDLE") {
                // object
                If $IsObject(tValue) {
                    If ..hasObjContent(tValue,.pVisited,pFormat) || (pFormat["o")  {
                        Do nextProp
                        if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                            Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":"
                        } else {
                            Write $$$ZENJSONPROP(tPropName,pFormat)_":"
                        }

                        Set tSC = ..%ObjectToJSON(tValue,.pVisited, pLevel+1, pFormat)
                        Quit:$$$ISERR(tSC)
                    }
                } ElseIf (pFormat["a") {
                    Do nextProp
                    if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                        Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":null"
                    } else {
                        Write $$$ZENJSONPROP(tPropName,pFormat)_":null"
                    }

                }
            }
            ElseIf (tClientType = "CHARACTERSTREAM") {
                If $IsObject(tValue) {
                    If tValue.Size || (pFormat["e") {
                        Do nextProp
                        if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                            Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":"""
                        } else {
                            Write $$$ZENJSONPROP(tPropName,pFormat)_":"""
                        }

                        If tValue.Size {
                            #; Initialize stream read length, if needed
                            If '$data(tStreamMaxReadLen) Set tStreamMaxReadLen = ($$$MaxLocalLength\2)
                            Do tValue.Rewind()
                            While 'tValue.AtEnd {
                                Write $$$ZENJSONESCAPE(tValue.Read(tStreamMaxReadLen),pFormat)
                            }
                        }
                        Write """"
                    }
                } ElseIf (pFormat["a") {
                    Do nextProp
                    if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                        Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":null"
                    } else {
                        Write $$$ZENJSONPROP(tPropName,pFormat)_":null"
                    }

                }
            }
            ElseIf (tClientType = "BINARYSTREAM") {
                Do nextProp
                if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                    Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":null"
                } else {
                    Write $$$ZENJSONPROP(tPropName,pFormat)_":null"
                }

            }
            Else {
                #; scalar item ; converts $List to empty string!
                Set tStr = $S((tDataType="b")&&(pFormat["e"):$S(tValue=1:"true",tValue=0:"false",1:"null")
                    , (tDataType="b"):$S(tValue:"true",1:"false")
                    , ((tDataType="n")||(pFormat["q"))&&$$$ZENJSISNUM(tValue):$$$ZENJSNUM(tValue)
                    , (tDataType="n")&&(tValue="")&&(pFormat["d"):"null"
                    , ($C(0)=tValue)||$ListValid(tValue):""""""
                    //, "dtu"[tDataType:$S(pFormat["u":$$$ZENJSUSTR(..formatDateTime(tValue,tType,tDataType,pFormat)), 1:$$$ZENJSSTR(..formatDateTime(tValue,tType,tDataType,pFormat)))
                    , 1:$$$ZENJSONSTR(tValue,pFormat))
                If (pFormat["e") || (tStr'="""""") {
                    Do nextProp
                    if ($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME") '= "") {
                        Write $$$ZENJSONPROP($$$comMemberArrayGet(tClass,$$$cCLASSproperty,tPropName,$$$cPROPparameter,"XMLNAME"),pFormat)_":"_tStr
                    } else {
                        Write $$$ZENJSONPROP(tPropName,pFormat)_":"_tStr
                    }

                }
            }
        } ; end properties loop
        Quit:$$$ISERR(tSC)
        If tPropCount'=0 {
            #; either we wrote at least one property or we wrote an empty '{' due to "o" mode or level zero
            If tIncludeWhitespace Set tIndent="", $P(tIndent,tTab,pLevel+1)="" Write tLF_tIndent
            Write "}"
        }
    }
    Catch ex {
        Set tSC = ex.AsStatus()
    }
    Quit tSC
nextProp
    If tPropCount=0 {
        If (tIncludeWhitespace && pLevel) Set tIndent="", $P(tIndent,tTab,pLevel+1)="" Write $S(pFormat["b":tLF_tIndent,1:" ")
        Write "{"
    } ElseIf tPropCount {
        Write ","
    } ; else tPropCount="" means we already did the starting '{' due to "o" mode
    Set tPropCount = tPropCount + 1
    If tIncludeWhitespace Set tIndent="", $P(tIndent,tTab,pLevel+2)="" Write tLF_tIndent
    Quit
}

And it works!

TEST>set x = ##class(test.msg.struct.TestXML).%New()
TEST>set x.statusId = "1111"
TEST>set x.service = "222"
TEST>do ##class(test.util.JsonProvider).%WriteJSONStreamFromObject(.obj1,.x,,,,"aelotuw")
TEST>w obj1.Read()
{
        "status_id":"1111",
        "service":"222"
}
TEST>

I didn't want to change system classes, so I thought to extend it and overrite what I need. For me is much clean this.

I had already thought about it, but we have a lot of properties with underscore, we would have to change everyone manually.

We can do that, but I don't like it.

Maybe changing something in the method ##class(%ZEN.Auxiliary.jsonProvider).%WriteJSONStreamFromObject() that if "XMLNAME" is defined, use that name instead property real name? But I don't know where to do that...

We are using 2016.2.1 (Build 803U).

This is the way we generate JSON:

TEST>set x = ##class(test.msg.struct.TestXML).%New()
 TEST>set x.statusId = "111"
 TEST>set x.service = "222"
 TEST>do ##class(Ens.Util.JSON).ObjectToJSONStream(x, .obj1, "aelotu")
 TEST>w obj1.Read()
{       "statusId":"111",       "service":"222"}
 

And this is the definition of the object:

Class test.msg.struct.TestXML Extends (%SerialObject,%XML.Adaptor)
{
Property statusId As %String(MAXLEN = "", XMLNAME = "status_id");
Property service As %String(MAXLEN = "");
}

Yes, we have a .Net Gateway configured, and we have imported the .Net dll through the Studio wizard.

We have activated gateway log, but it doesn't say anything.

From an Ensemble Bussiness Operation we call the .Net method. The code is this:

Class bo.GenerarWord Extends EnsLib.DotNetGateway.AbstractOperation
{

Parameter INVOCATION = "Queue";

Method generarDocumento(pRequest As msg.WordRequest, Output pResponse As msg.WordResponse) As %Status
{
        #dim sc as %status
        #dim gateway as %Net.Remote.Gateway
        
        set pResponse = ##class(msg.WordResponse).%New()
        
        set sc = ..GetConnection(.gateway)
        
        if $$$ISERR(sc){
            set pResponse.mensaje = "Error ("_sc_"):"_$System.Status.GetErrorText(sc)
            
        }else{
            #dim ce as cysnet.MiClase.entity.ControlError
            #dim we as cysnet.MiClase.entity.WordEntity
            #dim plantilla as %String
            #dim documento as %String
            
            set ce = ##class(cysnet.MiClase.entity.ControlError).%New(gateway)
            set we = ##class(cysnet.MiClase.entity.WordEntity).%New(gateway)
            
            set plantilla = "C:\InterSystems\Ensemble\mgr\DLLWORDENS2\dlls\PlantillaTuneada.doc"
            set documento = "C:\InterSystems\Ensemble\mgr\DLLWORDENS2\dlls\"
            
            //set we.setuTitulo = "TITULO_ENS"
            
            do dao.EscribirWord(ce,plantilla,documento,we,"PRUEBA_ENS")
            
            $$$LOGINFO(ce.getuDebbug())
        }
        
        set pResponse.mensaje = "OK"
        Quit $$$OK
}

XData MessageMap
{
<MapItems>
        <MapItem MessageType="msg.WordRequest"> 
            <Method>generarDocumento</Method>
        </MapItem>
</MapItems>
}

The .Net code is this:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using cysnet.MiClase.entity;
using System.IO;
using Microsoft.Office.Interop.Word;
 
namespace cysnet.MiClase
{
    public class MiClase
    {
        public String EscribirWord(ControlError ce, String fullPathPlantilla, String pathDocumento, WordEntity we, String numDocumento)
        {
 
            if (ce == null)
            {
                ce = new ControlError();
            }
            ce.Reset();
            ce.Debbug = fullPathPlantilla + " || " + pathDocumento + " || " + numDocumento + "  || ";
            ce.Debbug += " Iniciando método";
            String resultado = "";
            Application MSWord = new Application();
            Document documento;
 
            try
            {
                object oMissing = System.Reflection.Missing.Value;
                
                ce.Debbug += "RUTA DEL NUEVO DOCUMENTO:"+ pathDocumento + numDocumento +".docx";
 
                documento = MSWord.Documents.Add(ref oMissing, ref oMissing, ref oMissing, ref oMissing);
 
                ce.Debbug += " Abriendo plantilla Word";
                //Abrir Palntilla
 
                documento = MSWord.Documents.Open(fullPathPlantilla);
 
                ce.Debbug += " Escribiendo en marcadores";
                
                //Editar marcadores
                documento.Bookmarks["Titulo"].Range.Text = we.Titulo;
 
                ce.Debbug += " Guardando documento Word";
                //Guardar copia de la plantilla como documento
                documento.SaveAs(pathDocumento+numDocumento+".dot");
                
                ce.Debbug += " Cerrando documento Word";
                //Cerrar documento
                documento.Close();
                
                ce.Debbug += " Operación realizada con éxito";
            }
            catch (Exception e)
            {
                ce.MessageError = e.Message;
                ce.IsError = true;
            }
            finally
            {
                ce.Debbug += " Cerrando aplicación MsWord";
                //Cerrar la aplicación
                MSWord.Quit();
            }
 
            return resultado;
        }
    }
}

I have cleaned it a bit to be more legible. It has comments in spanish. I hope it doesn't matter.