Evitando chamadas de processo cruzado ao fazer automação de palavras via vb.net
-
28-09-2019 - |
Pergunta
A versão curtaEu tenho um add word add em vb.net e vsto que expõe um objeto compatível com word.comaddins.object, para que a funcionalidade add possa ser chamada de externa ao word, sem acessos à própria palavra sendo processada.
A técnica funcionou no VB6, mas com o VB.NET, ainda funciona, mas é muito mais lento que o mesmo código que executa diretamente do Addin por meio de um painel de tarefas, como se as chamadas fossem todos processos cruzados quando não deveriam ser. x
A versão longaEsse add é essencialmente toneladas de processamento em documentos do Word. O Addin pode ser executado de duas maneiras.
- De dentro do Word, usando um TaskPane
- Externamente, através de um conjunto de classes expostas ao COM (porque tenho que fornecer acesso à funcionalidade aos aplicativos do cliente VB6.
Mas aqui está o problema. Qualquer pessoa que já tenha feito a automação de palavras saiba que o código que executa perfeitamente aceravelmente inproc com o Word (neste caso a instância do add que a própria palavra carrega), geralmente será executada inaceitavelmente lentamente fora do processo (ou processo cruzado).
Este aplicativo não é diferente.
Há eras, fiz uso de um truque útil para contornar esse problema.
- Crie uma palavra addin como de costume
- Exponha um objeto por meio da propriedade Word.Addin.Object que permitirá que o código externo acesse seu addin.
- No seu projeto externo, em vez de manipular a palavra diretamente, use a coleção Application.comaddins, encontre seu add, recupere a propriedade Comaddin.Object exposta e, em seguida, chame um método nesse objeto que faz o trabalho.
Obviamente, o chamado para o seu objeto Comaddin.Object ainda será um processo cruzado, mas, uma vez que a execução estivesse no add que esteja em processo com o Word, seu add agora pode executar todas as manipulações de objeto que deseja e é rápido porque elas ' todas as chamadas em processo nesse ponto.
Isso funcionou nos dias VB6 com.
Mas, juntei este addin VstO vsto e exponho meu objeto Addin através da função RequestComaddinautomations Service do objeto Connect do Vsto
Eu posso fazer chamadas para o meu add externamente e todas elas funcionam exatamente como eu esperaria que elas, exceto que são todas +lentas +, muito parecidas com as chamadas no Word ainda estão sendo realizadas processos cruzados, mesmo que o código que faça essas chamadas para o Word faz parte da DLL add que foi carregada em processo por palavra!
E lento como em um fator de cerca de 10 a 1; O que leva 3 segundos para ser executado quando executado diretamente do Addin através do painel de tarefas, leva ~ 30 segundos para executar quando chamados do código externo através do objeto Comaddin.Object.
Suponho que estou encontrando algum tipo de problema com o .NET AppDomains ou algo assim e o que + realmente + + Cross Proc chama no .NET, mas não encontrei nada até agora, isso sugeriria sobre esse tipo de coisa.
Meu próximo passo, exceto algumas dicas místicas, será codificar uma repro, o que pode ser complicado por causa do número de cisalhamento de elementos em jogo.
Alguma ideia?
Solução 2
Infelizmente, a técnica de gancho de eventos que Thorben menciona não funcionaria para minha situação específica.
Então, estou fechando essa pergunta com a solução alternativa que mencionei nos comentários e vou repetir aqui ...
Bem, não é uma solução perfeita, mas eu encontrei a solução + A +. Envolveu um cronômetro, por isso é definitivamente subótimo essencialmente, quando o add é carregado por palavra (ou seja, durante o evento de inicialização), inicialize um cronômetro (um cronômetro Winforms, não um cronômetro de encadeamento) e defina seu intervalo para 500. Quando externo O código se conecta ao addin através da propriedade Comaddin.Object e faz uma chamada no addin, defina um sinalizador variável, que está sendo pesquisado pelo timer. Quando o timer o vê definido, ele redefine o sinalizador e executa a ação.
Não é a solução limpa que eu teria preferido, mas é bastante fácil de implementar, moderadamente fácil de entender após o fato, e definitivamente evita a desaceleração das chamadas do XProcess Com no Word.
Outras dicas
Fiz as mesmas observações com o meu vstow word adicionar. O que eu gostaria de adicionar aqui: quando você adiciona seu procedimento como manipulador de cliques a um botão:
`this.testbutton.Click += new Office._CommandBarbuttonevents_ClickeventHandler (YourProcedure);
e implemente seu procedimento caro em "YourProcedure", você pode ligar para o tópico da interface do word usando
this.testbutton.execute ();
Esta também não é uma solução elegante, mas talvez seja útil se você tiver botões prontos em um CommandBar.