none
un problème dont je n'ai pas la solution sur l'interface word RRS feed

  • Question

  • Bonjour,

    J'ai deux documents à lire: je les ouvre et je les ferme comme expliquée dans le Thread de Word

    et lord de la deuxième ouverture la plupart du temps je plante sur l'instruction

    objParagraphs = objDocument->Paragraphs;

    qui donne dans ce cas le message suivant: un exception non gérée du type System.Runtime.Interopservice.COMException s'est produite: le serveur RPC n'est pas disponible. Le code HRESULT = 0x800706BA

    J'ai essayé plusieurs approches mais j'en reviens à constater que une fois que le document est ouvert, il faut initialiser objParagraphs en le plaçant sur le document ouvert. Ou est l'erreur?


    Jean Noël Martin

    mercredi 5 décembre 2012 08:24

Réponses

  • J'ai suivi votre conseil : voila la methode:

            erc CWManager::CloseDocument()
            {
                Object^ oNull = System::Reflection::Missing::Value;
                Object^ oFalse = false;
                Object^ oTrue = true;
                objDocuments->Close( oNull, oNull, oNull);
                objApplication->Quit(oNull, oNull, oNull);
                Marshal.FinalReleaseComObject(objApplication);
                return(0);
            }

    et je vous donne le résultat de la compilation

    1>  WordManager.cpp
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(237): warning C4800: 'BOOL' : valeur forcée à la valeur booléenne 'true' ou 'false' (avertissement sur les performances)
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(300): error C2385: accès ambigu de 'Quit'
    1>          peut être le 'Quit' en base 'Microsoft::Office::Interop::Word::_Application'
    1>          ou peut être le 'Quit' en base 'Microsoft::Office::Interop::Word::ApplicationEvents4_Event'
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(300): error C3861: 'Quit' : identificateur introuvable
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C2143: erreur de syntaxe : absence de ';' avant '.'
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C2143: erreur de syntaxe : absence de ';' avant '.'

    par contre la méthode ci-dessous est correcte et il semble qu'elle résolve tous les problèmes connus

                    erc CWManager::CloseDocument( Word::Application^ objApplication, Word::Document^ objDocument, Word::Documents^ objDocuments)
    		{
    			Object^ oNull = System::Reflection::Missing::Value;
    			Object^ oFalse = false;
    			Object^ oTrue = true;
    			objDocuments->Close( oNull, oNull, oNull);
    			//objApplication->Quit(oNull, oNull, oNull);
                            Marshal::FinalReleaseComObject(objApplication);
    			return(0);
    		}


    Jean Noël Martin



    • Modifié JeanNoel53 mardi 11 décembre 2012 15:50
    • Marqué comme réponse JeanNoel53 mardi 11 décembre 2012 15:50
    mardi 11 décembre 2012 14:51

Toutes les réponses

  • ReBonjour

    Avant d’ouvrir la deuxième fois le fichier, vérifier si le processus du Word n’est pas encore active dans la mémoire (dans le Manager des taches de Windows.)

    Aussi vérifiez si c’est votre cas :

    http://support.microsoft.com/kb/935677

    Cordialement,


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    jeudi 6 décembre 2012 08:51
  • Mon système est déjà à jour pour ce point, Je crois que il faut rajouter une tempo pour laisser au système le temps de fermer ses ressources. Je vais essayer et je reviens vers vous

    Jean Noël Martin

    jeudi 6 décembre 2012 16:07
  • Je met un point d'arrêt dans l’arrêt de word.

    J'ai une autre anormale sur l'arrêt de Word.

    WinWord reste actif même après l'arrêt de Word par son interface.

    je l’arrête par le gestionnaire de tâches de Windows.

    Ça ne peut pas aller dans un produit professionnel.

    Je suppose que ma procédure d'arrêt décrite ici est incomplète. Pouvez vous m'aider?

    Jean Noël Martin

    lundi 10 décembre 2012 10:53
  • Bonjour

    La solution c’est de faire grand attention avec tout objet initialisé.

    Vous devez bien détruire tous ces objets.

    Aussi, à la fin du traitement ajoutez 
    yourWordAppObject.Quit();

    System.Runtime.InteropServices.Marshal.FinalReleaseComObject(yourWordAppObject);

    Plus de détails vous avez ici

    http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.marshal.finalreleasecomobject.aspx?cs-save-lang=1&cs-lang=cpp#code-snippet-1

     

    Cordialement, 


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    lundi 10 décembre 2012 11:02
  • J'ai du mal à interpréter votre conseil:

    J'ai essayé deux solutions qui sont toutes refusée par le compilateur:

    			objDocuments->Quit();
    			FinalReleaseComObject( objDocuments);

    et j'ai aussi essayé ça:

    erc CWManager::CloseDocument()
    		{
    			Object^ oNull = System::Reflection::Missing::Value;
    			Object^ oFalse = false;
    			Object^ oTrue = true;
    			System.Runtime.InteropServices.Marshal.FinalReleaseComObject(yourWordAppObject);
    			objDocuments->Close( oNull, oNull, oNull);
    			// FinalReleaseComObject( Object^ o)
    			yourWordAppObject.Quit();
    			//FinalReleaseComObject( objDocuments);
    			return(0);
    		}


    Jean Noël Martin


    • Modifié JeanNoel53 lundi 10 décembre 2012 14:47
    lundi 10 décembre 2012 14:43
  • Si on garde les noms des variables décrites dans votre poste "Les points clefs d'un lecteur de Word"

    Vous avez :

    objApplication->Quit();

    FinalReleaseComObject(objApplication);

    Avez-vous bien declaree

     using namespace  System::Runtime::InteropServices

    Aurel


    Aurel BERA, Microsoft
    Microsoft propose ce service gratuitement, dans le but d'aider les utilisateurs et d'élargir les connaissances générales liées aux produits et technologies Microsoft. Ce contenu est fourni "tel quel" et il n'implique aucune responsabilité de la part de Microsoft.

    lundi 10 décembre 2012 14:54
  • Je donne tout le code de la classe avec les modifications que vous suggérez et Je met le diagnostique du compilateur:

    namespace SpecificationLoader
    {
        using namespace System;
    	using namespace System::ComponentModel;
    	using namespace System::Collections;
    	using namespace System::Windows::Forms;
    	using namespace System::Data;
    	using namespace System::Drawing;
    	using namespace System::Threading;
    	using namespace System::IO;
    	using namespace System::Runtime::InteropServices;
    	namespace Word = Microsoft::Office::Interop::Word;
    	
    	bool bonDocumentOpen;
    	
    	
    		CWManager::CWManager()
    		{
    		}
    
    		CWManager::~CWManager()
    		{
    		}
    
    		void CWManager::OnDocumentOpen(void)
    		{
    			bonDocumentOpen = true;
    		}
    
    		erc CWManager::GetNbWords()
    		{
    			return( ulNbWord);
    		}
    		
    		erc CWManager::StartWordApi()
    		{
    			// Convenient values declared as ColeVariants.
    			//COleVariant covTrue((short)TRUE), covFalse((short)FALSE), covOptional((long)DISP_E_PARAMNOTFOUND, VT_ERROR);
    			// Get the IDispatch pointer and attach it to the objWord object.
    			// objApplication->CreateDispatch("Word.Application");
    			//Word::ApplicationEvents2_DocumentOpenEventHandler^ objWord;
    			//SpecificationLoader::CWManager::OnDocumentOpen* ptrWord;
    			bonDocumentOpen = false;
    			//ptrWord = &SpecificationLoader::CWManager::OnDocumentOpen;
    			//objWord += gcnew Word::ApplicationEvents2_DocumentOpenEventHandler( this, &SpecificationLoader::CWManager::OnDocumentOpen);
    			return(0);
    		}
    		
    		erc CWManager::StopWordApi()
    		{
    			return( 0);
    		}
    	
    		erc CWManager::OpenWordDocument(std::wstring wsFullPathName)
    		{
    			bool m_bDocumentIsOpen;
    			erc ErrorCode = INIT_NO_ERROR;
    			int m_lNumberOfWords;
    			enum OpenDocumentErrors
    			{
    				CANT_OPEN_DOCUMENT = 1,
    				DOC_IS_NULL,
    			};
    		
    			try
    			{
    				Word::Documents^ objDocuments = objApplication->Documents;
    				// public: Document^ Open( &Object^ FileName, &Object^ ConfirmConversions, &Object^ ReadOnly, &Object^ AddToRecentFiles, &Object^ PasswordDocument, &Object^ PasswordTemplate, &Object^ Revert, &Object^ WritePasswordDocument, &Object^ WritePasswordTemplate, &Object^ Format, &Object^ Encoding, &Object^ Visible, &Object^ OpenAndRepair, &Object^ DocumentDirection, &Object^ NoEncodingDialog, &Object^ XMLTransform);
    				// 1                        &Object^ FileName
    			    // 2                                         &Object^ ConfirmConversions
    			    // 3                                                  &Object^ ReadOnly
    			    // 4                                                      &Object^ AddToRecentFiles
    				// 5                                                             &Object^ PasswordDocument
    			    // 6                                                                      &Object^ PasswordTemplate
    			    // 7                                                                               &Object^ Revert
    			    // 8                                                                                        &Object^ WritePasswordDocument
    			    // 9                                                                                                 &Object^ WritePasswordTemplate
    			    // 10                                                                                                          &Object^ Format
    			    // 11                                                                                                               &Object^ Encoding
    				// 12                                                                                                                           &Object^ Visible
    			    // 13                                                                                                                                 &Object^ OpenAndRepair
    			    // 14                                                                                                                                          &Object^ DocumentDirection
    			    // 15                                                                                                                                                   &Object^ NoEncodingDialog
    				// 16                                                                                                                                                            &Object^ XMLTransform
    				//objDocument = objDocument->Open( &wsFullPathName, false, true, false, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, nullptr, true, nullptr, nullptr, nullptr, nullptr);
    				bonDocumentOpen = true;
    				Object^ oFalse = false;
    				Object^ oTrue = true;
    				Object^ oNull = System::Reflection::Missing::Value;
    				ulNbWord = 0;
    				if( wsFullPathName.size() != 0)
    				{
    					Object^ oNomDocument = gcnew String( wsFullPathName.c_str());
    					while( bonDocumentOpen != true);
    					objDocument = objDocuments->Open( oNomDocument, oFalse, oTrue, oFalse, oNull, oNull, oNull,   oNull,   oNull,   oNull,   oNull,   oTrue, oNull,   oNull,   oNull,   oNull);
    					objDocument->Activate();
    					Word::Words^ objWords = objDocument->Words;
    					
    					m_lNumberOfWords = objWords->Count;
    					ulNbWord = m_lNumberOfWords;
    				}
    				else
    					ErrorCode = objStrConv.CreateReturnCode( TYPE_ERROR, MSG_CANT_OPEN_DOCUMENT,MODULE_ID_WORD_READER, MODULE_ID_WORD_READER, OPEN_DOCUMENT, DOC_IS_NULL);
    				if (ErrorCode == INIT_NO_ERROR)
    				{
    					m_bDocumentIsOpen = true;
    				}
    				return ( ulNbWord);
    			}
    			catch(...)
    			{
    				return( -1);
    			}
    		}
    				
    		erc CWManager::StartDocAnalysis( System::ComponentModel::BackgroundWorker^  backgroundWorker1, long ulNbWord, bool bNewDoc)
    		{				
    			CBloc* pBloc;
    			size_t iSize;
    			
    			Word::Paragraphs^ objParagraphs;
    			nParagraph = 0;
    			objParagraphs = objDocument->Paragraphs;
    			erc ulTotalNbWords = 0;
    			// il faut swapper les fichiers de backup
    			bool bStatus = CopyFile( (LPCTSTR)sLogFile.c_str(), (LPCTSTR)sSavedLogFile.c_str(), false);
    			int iStatus = remove( sLogFile.c_str());
    			for each( Word::Paragraph^ objParagraph in objParagraphs)
    			{
    				System::String^ wsText = objParagraph->default->default;
    				// Récupérer les informations de Layout
    				// Word::Paragraph::Format::ParagraphFormat^ Format = objParagraph->Format->ParagraphFormat;
    				Object^ Style = objParagraph->Style;
    				const wchar_t* chars = (const wchar_t*)(Marshal::StringToHGlobalUni( wsText)).ToPointer();
    				pBloc = new CBloc;
    				pBloc->wsBlocText.append( chars);
    				Marshal::FreeHGlobal(IntPtr((void*)chars));
    					
    				//pour chaque mot du paragraph on enregistre le Layout dans la list Elements avec le mot correspondant.
    				// CSchedulerGlobal::AnalyseBlocText(CBloc* pBloc)
    				// appeler SchedulerGlobal pour traiter le paragraph.
    				iSize = pBloc->wsBlocText.size();
    				if( iSize > 2)
    					ulTotalNbWords = objSchedulerGlobal.AnalyseBlocText( pBloc, ulTotalNbWords, bNewDoc);
    				// il faut appeler le backgroundWorker1_ProgressChanged( System::Object^ sender, ProgressChangedEventArgs^ e)
    				erc ProgressPercentage = 100 * ulTotalNbWords / ulNbWord;
    				// e->ProgressPercentage = ProgressPercentage;
    				// void MainMenue::backgroundWorker1_ProgressChanged( System::Object^ sender, ProgressChangedEventArgs^ e)
    				// backgroundWorker1->RunWorkerAsync( numberToCompute );
    				// worker->ReportProgress( percentComplete ); 
    				// backgroundWorker1->ReportProgress( ProgressPercentage);
    			}
    			CloseDocument();
    			return( 0);
    		}
    		
    		
    		erc CWManager::CloseDocument()
    		{
    			Object^ oNull = System::Reflection::Missing::Value;
    			Object^ oFalse = false;
    			Object^ oTrue = true;
    			//Services.Marshal.FinalReleaseComObject(yourWordAppObject);
    			objDocuments->Close( oNull, oNull, oNull);
    			objApplication->Quit();
    			// FinalReleaseComObject( Object^ o)
    			//yourWordAppObject.Quit();
    			FinalReleaseComObject( objDocuments);
    			return(0);
    		}
    		
    }

    et le diagnostic du compilateur

    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C2385: accès ambigu de 'Quit'
    1>          peut être le 'Quit' en base 'Microsoft::Office::Interop::Word::_Application'
    1>          ou peut être le 'Quit' en base 'Microsoft::Office::Interop::Word::ApplicationEvents4_Event'
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C2660: 'Microsoft::Office::Interop::Word::_Application::Quit' : la fonction ne prend pas 0 arguments
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C3861: 'Quit' : identificateur introuvable
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(304): error C3861: 'FinalReleaseComObject' : identificateur introuvable


    Jean Noël Martin

    lundi 10 décembre 2012 18:09
  • J'ai suivi votre conseil : voila la methode:

            erc CWManager::CloseDocument()
            {
                Object^ oNull = System::Reflection::Missing::Value;
                Object^ oFalse = false;
                Object^ oTrue = true;
                objDocuments->Close( oNull, oNull, oNull);
                objApplication->Quit(oNull, oNull, oNull);
                Marshal.FinalReleaseComObject(objApplication);
                return(0);
            }

    et je vous donne le résultat de la compilation

    1>  WordManager.cpp
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(237): warning C4800: 'BOOL' : valeur forcée à la valeur booléenne 'true' ou 'false' (avertissement sur les performances)
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(300): error C2385: accès ambigu de 'Quit'
    1>          peut être le 'Quit' en base 'Microsoft::Office::Interop::Word::_Application'
    1>          ou peut être le 'Quit' en base 'Microsoft::Office::Interop::Word::ApplicationEvents4_Event'
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(300): error C3861: 'Quit' : identificateur introuvable
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C2143: erreur de syntaxe : absence de ';' avant '.'
    1>..\..\..\..\Linguistic\WordReader\src\WordManager.cpp(301): error C2143: erreur de syntaxe : absence de ';' avant '.'

    par contre la méthode ci-dessous est correcte et il semble qu'elle résolve tous les problèmes connus

                    erc CWManager::CloseDocument( Word::Application^ objApplication, Word::Document^ objDocument, Word::Documents^ objDocuments)
    		{
    			Object^ oNull = System::Reflection::Missing::Value;
    			Object^ oFalse = false;
    			Object^ oTrue = true;
    			objDocuments->Close( oNull, oNull, oNull);
    			//objApplication->Quit(oNull, oNull, oNull);
                            Marshal::FinalReleaseComObject(objApplication);
    			return(0);
    		}


    Jean Noël Martin



    • Modifié JeanNoel53 mardi 11 décembre 2012 15:50
    • Marqué comme réponse JeanNoel53 mardi 11 décembre 2012 15:50
    mardi 11 décembre 2012 14:51