.NET

1 out, 2012

Controles ActiveX de Word/Excel em ASP.NET

Publicidade

Neste artigo, vamos criar um controle ActiveX para o Word/Excel e ele será usado em um aplicativo ASP.NET.

Download do código fonte – 1,93 MB

O que é um controle ActiveX

ActiveX é um componente de software do Microsoft Windows. Se você tem o Internet Explorer o ActiveX já está instalado em seu computador. Os controles ActiveX são pequenos programas, chamados às vezes de add-ons, que são usados na Internet. Eles podem melhorar a sua experiência de navegação.

Você pode decidir se deseja ou não fazer o download de controles ActiveX de acordo com a sua necessidade. Alguns sites exigem que você instale os controles ActiveX para visualizar ou executar determinadas tarefas, mas isso pode conter potenciais riscos. Os cibercriminosos podem desenvolver seus próprios controles ActiveX e podem danificar os computadores se os usuários visitarem páginas que contêm software ActiveX maliciosos.

Quando você visitar um site que usa um controle ActiveX, o Internet Explorer vai perguntar se deseja instalar o controle ActiveX. Então, você pode escolher instalar o controle ActiveX ou aprender sobre os riscos. Clique em Don´t run se você não confia no site.

Etapas para criar um controle ActiveX

Criar uma Blank Solution no Visual Studio

1- Abra o Visual Studio -> menu File -> New Project -> Other Project Types -> Visual Studio Solutions —> Blank Solution

2 – Escreva Blank Solution “OtherControlSol” e selecione solution location–> -> clique em OK.

Criar um controle C# do Windows no Visual Studio

1 – Clique com o botão direito do mouse em Solution Explorer —> New Project -> Visual C # Windows Control Library nome do projeto “ControlWordExcel”.

2 – Depois de adicionar um projeto de biblioteca de Controle do Windows, clique com o botão direito sobre o controle —> renomeie o controle “ControlWordExcel”.

3 – Abra AssemblyInfo.cs e configure [assembly: ComVisible (true)].

4 – Clique com o botão direito do mouse na  pasta referências —> clique em Add References … e selecione as seguintes referências: Microsoft.Office.Core em (aba COM), Microsoft.Office.Interop.Excel e Microsoft.Office.Interop.Word em (aba .NET), todas referências versão 12.0.0.0, o Microsoft Office 12.0 Object Library (aba COM).

5 – Clique com o botão direito do mouse sobre ControWordExcel Project —> selecione Proprerties —> clique na aba Signing.

6 – Defina a largura do controle para width:998, height:573 a partir de propriedade do controle.

7 – Abra uma caixa de diálogo para adicionar arquivos na caixa de ferramentas de controle.

8 – Selecionar Sign the assembly –> selecione New -> caixa de diálogo irá aparecer -> Digite a senha —> clique em OK.

9 – Menu Visual Studio Tools —> Criar Guid —> Opção 4 (Formato Registry), clique em Copiar -> ControlWordExcel.cs Abertos. Adicionar ProgId, ClassInterface, Guid, e ComVisible.

[ProgId("ControlWord.ControlWordExcel")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[Guid("98BAE912-0171-4c9c-A4EC-FD5969E92D08")]
[ComVisible(true)]

10 – Escreva o código para chamar o user32.dll funções API FindWindow, SetParent e SetWindowPos.

#region "API Calling"

/// <summary>
/// Retrieves a handle to the top-level window whose
/// class name and window name match the specified strings.
/// </summary>
/// <param name="strclassName">calss name</param>
/// <param name="strWindowName">window class name</param>
/// <returns>If the function succeeds, the return value is a handle to the window
/// that has the specified class name and window name.</returns>

[DllImport("user32.dll")]
public static extern int FindWindow(string strclassName, string strWindowName);

/// <summary>
/// Changes the parent window of the specified child window.
/// </summary>
/// <param name="hWndChild">A handle to the child window</param>
/// <param name="hWndNewParent">A handle to the new parent window. If this parameter
/// is NULL, the desktop window becomes the new parent window.</param>
/// <returns>If the function succeeds, the return value
/// is a handle to the previous parent window</returns>

[DllImport("user32.dll")]
static extern int SetParent(int hWndChild, int hWndNewParent);

/// <summary>
/// Changes the size, position, and Z order of a child, pop-up, or top-level window. 
/// These windows are ordered according to their appearance on the screen. 
/// The topmost window receives the highest rank and is the first window in the Z order
/// </summary>
/// <param name="hWnd">A handle to the window</param>
/// <param name="hWndInsertAfter">A handle to the window
/// to precede the positioned window in the Z order.</param>
/// <param name="X">position of the left side of the window</param>
/// <param name="Y">position of the top of the window</param>
/// <param name="cx">width of the window</param>
/// <param name="cy">height of the window</param>
/// <param name="uFlags">
/// window sizing and positioning flags.
/// SWP_DRAWFRAME(0x20):Draws a frame (defined in the window's class description) around the window
/// SWP_NOMOVE(0x2):Retains the current position (ignores X and Y parameters)
/// SWP_NOZORDER(0x4):Retains the current Z order (ignores the hWndInsertAfter parameter).
/// </param>
/// <returns>If the function succeeds, the return value is nonzero</returns>

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
static extern bool SetWindowPos(int hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, uint uFlags);

#endregion

11 – Use o namespace System.Runtime.InteropServices. Crie documento e aplicação de objetos do Word Microsoft.Office.Interop.Word.Document e Microsoft.Office.Interop.Word.ApplicationClass. Em seguida, objeto para o MS Excel e aplicação para Excel Workbook: Microsoft.Office.Interop.Excel.Workbook e Microsoft.Office.Interop.Excel.ApplicationClass.

//object for word
public Microsoft.Office.Interop.Word.Document wDocument;
public static Microsoft.Office.Interop.Word.ApplicationClass acWord = null;
//object for excel
public Microsoft.Office.Interop.Excel.Workbook eWorkBook;
public static Microsoft.Office.Interop.Excel.ApplicationClass acExcel = null;

public static int iWindow = 0; // Window Handle
public static string sFileName = null; // Word or Excel File name

12 – Agora escreva o código para abrir o Word ou o Excel no controle. OpenDocument leva dois parâmetros sMyFileName e sAppType do tipo string. De acordo com o tipo passado, o objeto de classe do aplicativo é criado. Então, chame a função FindWindow, que tem dois parâmetros: nome de classe e nome de janela. Para o MS-Word, utilize o nome de classe Opusapp, e o MS-Excel utiliza o nome de classe XLMAIN. O próximo parâmetro é null para nome da janela.

FindWindow retorna um valor diferente de zero em caso de êxito, passa esse valor na função SetParent. Em seguida, chame a função Open para Word ou Excel de acordo com sAppType, cujo valor é W ou E. Depois, transmita todos os valores ausentes criando object oMissing = System.Reflection.Missing.Value;. Open para MS-Word, que pega valor por ref, mas no MS-Excel a função Open não é exigida a passar ref. Para ver MS-Word, use a propriedade Visible=true e chame a função Activate() do objeto Microsoft.Office.Interop.Word.ApplicationClass. O mesmo para o objeto Microsoft.Office.Interop.Excel.ApplicationClass, use a propriedade Visible=true e UserControl=true. Finalmente, chame SetWindowPos para definir a aplicação Word ou Excel no controle em local adequado.

/// <summary>
/// Open selected word or excel file.
/// </summary>
/// <param name="sMyFileName">word or excel file name</param>
/// <param name="sAppType">W for Word, E for Excel</param>
public void OpenDocument(string sMyFileName,string sAppType)
{
    sFileName = sMyFileName;

    //object for word
    if (acWord == null && sAppType=="W")
        { acWord = new Microsoft.Office.Interop.Word.ApplicationClass(); }
    //object for excel
    if (acExcel == null && sAppType == "E")
        { acExcel = new Microsoft.Office.Interop.Excel.ApplicationClass(); }

    if (wDocument != null) { try { CloseAndSave(sAppType); } catch { } }

    if (eWorkBook != null) { try { CloseAndSave(sAppType); } catch { } }
    // "Opusapp" for ms word.
    if (iWindow == 0 && sAppType == "W") { iWindow = FindWindow("Opusapp", null); }
    // "XLMAIN" for ms excel.
    if (iWindow == 0 && sAppType == "E") { iWindow = FindWindow("XLMAIN",null); }

    if (iWindow != 0)
    {
        //call SetParent function.
        SetParent(iWindow, this.Handle.ToInt32());

        object oFileName = sFileName;
        object oReadOnly = false;
        object oIsVisible = true;
        object oMissing = System.Reflection.Missing.Value;

        try
        {
            if (iWindow == 0) { throw new Exception(); }
            //object for word
            if (sAppType == "W")
            {
                if (acWord.Documents == null && sAppType == "W") { throw new Exception(); }

                if (acWord != null && acWord.Documents != null && sAppType == "W")
                { wDocument = acWord.Documents.Open(ref oFileName, ref oMissing, 
                    ref oReadOnly, ref oMissing, ref oMissing, ref oMissing, 
                    ref oMissing, ref oMissing, ref oMissing, ref oMissing, 
                    ref oMissing, ref oIsVisible, ref oMissing, ref oMissing, 
                    ref oMissing, ref oMissing); }

                if (wDocument == null && sAppType == "W") { throw new Exception(); }
            }
            //object for excel
            if (sAppType == "E")
            {
                if (acExcel.Workbooks == null && sAppType == "E") { throw new Exception(); }

                if (acExcel != null && acExcel.Workbooks != null && sAppType == "E")
                { eWorkBook = acExcel.Workbooks.Open(sFileName, oMissing,
                    oReadOnly, oMissing, oMissing, oMissing, oMissing, 
                    oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing, oMissing); }

                if (eWorkBook == null && sAppType == "E") { throw new Exception(); }
            }
        }
        catch { }
        try
        {
            //object for word
            if (sAppType == "W")
            {
                acWord.Visible = true;
                acWord.Activate();                        
            }
            //object for excel
            if (sAppType == "E")
            {
                acExcel.Visible = true;
                acExcel.UserControl = true;
            }
            // call SetWindowPos
            SetWindowPos(iWindow, this.Handle.ToInt32(), 0, 0, this.Bounds.Width, 
                         this.Bounds.Height, (0x4 | 0x2 | 0x20));

            OnResize(new EventArgs());

        }
        catch { MessageBox.Show("Error..."); }
        this.Parent.Focus();
    }
}

13 – Escreva função para fechar salvando o aplicativo do Word ou Excel com segurança. Para isso, a função CloseAndSave leva um parâmetro sAppType do tipo string. De acordo com esse parâmetro, nós chamamos a função Save(), Close(), e Quit(). Finalmente, atribua um valor null para o objeto e passe também o valor zero para o objeto iWindow do tipo int.

/// <summary>
/// Close and Save File.
/// </summary>
/// <param name="sAppType">W for Word, E for Excel</param>
public void CloseAndSave(string sAppType)
{
    try
    {
        object oMissing = false;
        if (sAppType == "W")
        {
            wDocument.Save();
            wDocument.Close(ref oMissing, ref oMissing, ref oMissing);
            acWord.Quit(ref oMissing, ref oMissing, ref oMissing);
            acWord = null;
        }
        if (sAppType == "E")
        {
            eWorkBook.Save();
            eWorkBook.Close(oMissing, oMissing, oMissing);
            acExcel.Quit();
            acExcel = null;
        }
        iWindow = 0;
    }
    catch (Exception ex)
    { }
}

14 – Agora, escreva o código para a caixa de diálogo para abrir o arquivo. Para isso, crie a função BrowseFileDialog(), que leva um parâmetro sAppType do tipo string. De acordo com o tipo, defina um filtro para a caixa de diálogo para abrir o arquivo, obtenha o nome do arquivo, e chame OpenDocument().

/// <summary>
/// call file open dialog to open file.
/// </summary>
/// <param name="sAppType">W for Word, E for Excel</param>
/// <returns>return selected file name with location.</returns>
public string BrowseFileDialog(string sAppType)
{
    string sFName; string sFilterExtension = "";
    openFileDialog1.Multiselect = false;
    openFileDialog1.FileName = "";
    //object for word
    if (sAppType == "W") { sFilterExtension = "MS-Word Files (*.docx,*.doc,*.dot) |*.docx;*.doc;*.dot;"; }
    //object for excel
    if (sAppType == "E") { sFilterExtension = "MS-Excel Files (*.xlsx,*.xls,*.xot) |*.xlsx;*.xls;*.xot;"; }
    openFileDialog1.Filter = sFilterExtension;
    if (openFileDialog1.ShowDialog() == DialogResult.OK)
    {
        sFName = openFileDialog1.FileName;
    }
    else return "";

    try
    { this.CloseAndSave(sAppType); }
    catch { }
    finally
    {
        //object for word
        if (sAppType == "W")
        {
            this.wDocument = null;
            acWord = null;
        }
        //object for excel
        if (sAppType == "E")
        {
            this.eWorkBook = null;
            acExcel = null;
        }
        iWindow = 0;
    }
    try
    {
        //open file word or excel.
        this.OpenDocument(sFName, sAppType);
    }
    catch (Exception ex) { String err = ex.Message; }
    return sFName;
}

15 – Finalmente, salve e crie o projeto e visualize o arquivo. dll na pasta Release ou Debug. O próximo passo é registrar  assembly com codebase.

Controle de registro (Regasm.exe)

A ferramenta Assembly Registration lê os metadados em um assembly e adiciona as entradas necessárias para o registro, que permite que clientes COM criem classes. NET Framework de forma transparente. Crie uma entrada Codebase no registro, use as opções /codebase. A entrada codebase especifica o caminho do arquivo para um assembly que não está instalado no cache de assembly global. Para cancelar o registro, use a opção /u.

Crie um novo site

Abra default.aspx e escreva código para visualizar o controle.

 

Crie novo arquivo JavaScript

Para lidar com funções JavaScript relacionadas ao controle. crie um novo arquivo jscontrol.js na raiz local.

Por fim, construa código e execute o site.

Crie um certificado digital

A ferramenta “Criação de certificado” gera certificados X.509 somente para fins de teste. Ela cria um par de chaves, pública e privada, para as assinaturas digitais e as armazena em um arquivo certificado. Essa ferramenta também associa o par de chaves com o nome de um editor especificado e cria um certificado X.509 que vincula um nome especificado de usuário para a parte pública desse par de chaves.

  • -r cria um certificado autoassinado, -sv especifica a chave privada do assunto do arquivo .pvk. O arquivo é criado caso não exista nenhum.
  • -n especifica o nome do certificado do assunto. Esse nome deve estar em conformidade com o padrão X.500. O método mais simples é especificar o nome entre aspas, precedido por CN=; por exemplo, “CN=myName“.
  • -b especifica o início do período de validade. Padrões para a data criação do certificado (dd/mm/aaaa).
  • -e especifica o final do período de validade da data (dd/mm/aaaa). Padrões para 12/31/2039 11:59:59 GMT.

Abra o prompt de comando do VS e escreva o comando makecert para criar um certificado digital, insira uma senha para ele, e pressione OK.

O próximo passo pedirá novamente a mesma senha. Pressione ok.

Vá para o prompt de comando do Visual Studio, e você vai encontrar três arquivos: .cer, .pfx e .pvk.

Assinando um certificado digital

Sign Tool é uma ferramenta de linha de comando que assina digitalmente os arquivos, verifica as assinaturas ou marca o tempo em arquivos. signwizard inicia o assistente de assinatura. Somente um arquivo pode ser especificado para o argumento de nome de arquivo da linha de comando.

Para assinar um certificado digital para todos os arquivos .dll, .msi, e .cab, repita o mesmo processo para todos eles. Abra o prompt de comando do VS e escreva o comando signtool.exe signwizard. Pressione enter. Um assistente vai aparecer, aí é só seguir os passos abaixo.

Observação

Primeiro assine o arquivo assembly .dll. Em seguida, o arquivo de instalação .msi. Por último, assine o arquivo cabinet.

Clique em Next e abra a localização de .dll, .msi, e .cab; em seguida, selecione Custom e clique de novo em Next.

Vá até a localização do prompt de comando do Visual Studio e selecione o arquivo .pvk.

Em seguida, digite a mesma chave, e depois, OK.

Use o algoritmo padrão e clique em “Next”.

Insira a mesma senha, pressione OK, clique em Finish e a caixa de mensagem aparecerá para completar, com sucesso, o processo de assinatura.

Criar um projeto de instalação do Windows C#

1 – Clique com o botão direito do mouse em Solution Explorer —> New project, Setup project, name “SetupWordExcel”.

2 – Adicione arquivos -> selecione ControlWordExcel.dll a partir do control build location.

3 – Configure a propriedade Register para vsdraCOM de ControlWordExcel.dll; a propriedade vsdraCOM, o item será registrado como um objeto COM.

4 – Construa o projeto e encontre a saída na pasta bin (Debug ou Release).

5 – Repita o processo do assistente signtool para assinar o arquivo SetupWordExcel.msi.

Criar um arquivo CAB

Para um arquivo cabinet, use cabarc.exe. Estamos criando um arquivo cabinet para o controle ActiveX, precisamos do arquivo .inf também.

1 – Crie um arquivo .inf chamado “ControlWordExcel.inf” e escreva o código nele.

2 – Precisamos de fazer um merge nos arquivos SetupWordExcel.msi e ControlWordExcel.inf no arquivo de gabinete para o controle ActiveX.

3 – Baixe o arquivo CABARC.EXE clicando no link de download.

4 – Cole SetupWordExcel.msi e ControlWordExcel.inf no CABARC.EXE ou como seu path de localização.

5 – Por fim, abra a localização da pasta de ControlWordExcel.cab e repita o processo do assistente Signtool para assinar o arquivo ControlWordExcel.cab.

Publicar ou implementar site no IIS

  1. No Visual Studio, cole o arquivo .cab em seu projeto web na raiz local.
  2. Clique com o botão direito do mouse no projeto web e publique o seu site.
  3. Instale o IIS no seu computador.
  4. Publique o código colado na pasta no “C:\Inetpub\wwwroot”. Defina a página padrão do site, digite sua URL localhost no navegador IE (como: http://127.0.0.1/, http://localhost/ ou IP do seu computador http://xxx.xxx.xx.xx/).

Configuração do controle ActiveX

Open IE–>Tools menu–>Internet Options–>Security tab–>Custom Level.

Se você encontrar quaisquer problemas em visualizar o controle, adicione a URL na sua zona de sites confiáveis na guia Segurança e desmarque a opção de formulário http server verification (https:), então Add e Close.

Instalação do certificado digital

Publique seu aplicativo web no IIS e execute-o em localhost. Após a execução, o controle será exibido no navegador. Autorize permissão e instale o certificado, clique no editor desconhecido, em seguida, clique em Ver certificado e em Instalar certificado.


Clique em Next e, em seguida, selecione a opção como “per view”, selecione a opção “Trusted Root Certification Authorities”, depois clique em OK.

Clique em Next com as opções padrão, então uma caixa de mensagem irá aparecer, clique em Sim e, finalmente, a mensagem de sucesso vai aparecer, então clique em OK.

Visualizar o certificado digital instalado

Abra o navegador IE, então o menu Ferramentas -> Opções da Internet —> aba Conteúdo -> clique no botão Certificados e, em seguida selecione a aba ” Trusted Root Certification Authorities “, role os certificados e selecione o nosso certificado, clique duas vezes e depois Exibir certificado.

Visualizar controle instalado em gerenciar add-ons

Abra o navegador IE, então o menu Ferramentas -> Opções da Internet —> guia de programa -> clique em Gerenciar add-ons —> selecione todos os add-ons na caixa dropdown; em seguida, veja o nosso controle e dê um duplo clique para ver mais informações.

Desinstalar o controle ActiveX

 

Conclusão

Nós abordamos os seguintes tópicos: como chamar o aplicativo web Word/Excel em ASP.NET web, como criar um controle ActiveX, como registrar um controle, como criar uma configuração de controle para COM, como criar um arquivo .cab, como criar um certificado digital, como assinar um controle, como publicar um controle, como instalar um certificado digital, como definir as configurações de controle ActiveX do IE, ver certificado e gerenciar complementos.

***

Texto original disponível em http://www.codeproject.com/Articles/404688/Word-Excel-ActiveX-Controls-in-ASP-NET