Fehler: Der Cancel-Parameter für Office-Ereignisse wird in Visual Studio .NET 2003 ignoriert.

SPRACHE AUSWÄHLEN SPRACHE AUSWÄHLEN
Artikel-ID: 830519 - Produkte anzeigen, auf die sich dieser Artikel bezieht
Dieser Artikel wurde archiviert. Er wird im vorliegenden Zustand bereitgestellt und nicht mehr aktualisiert.
Alles erweitern | Alles schließen

Auf dieser Seite

Zusammenfassung

Bei der Arbeit mit Microsoft Visual Studio .NET 2003 möglicherweise Probleme auftreten, wenn Sie den Cancel -Parameter in eine COM-Ereignis verwenden, das von Microsoft Word, Microsoft Excel oder Microsoft Outlook ausgelöst wird. Obwohl der Code das COM-Ereignis empfängt und des Codes kann den Parameter entsprechend den COM-Ereignis nicht abgebrochen. Dieses Problem tritt auf, wenn Sie COM-Interop von einem verwalteten Client (z. B. Microsoft Visual c# oder Microsoft Visual Basic .NET) verwenden und Sie auch das Microsoft .NET Framework Version 1.1 verwenden.

Ursache

.NET Framework 1.1 wurde Sicherheitsänderungen um Typsicherheit zu verbessern, bei der Interaktion mit einer COM-Komponente eingeführt. .NET Framework 1.1 verbessert Typsicherheit, indem mithilfe der Marshalling-Informationen in der Bibliothek Typ der Komponente. Beim Automatisieren von Word, Excel oder Outlook von einem verwalteten Client verwendet die COM-Interop-Assembly (IA) oder die primäre Interop-Assembly (PIA) für Microsoft Office XP die Typ-Informationen, die in den Microsoft Office-Typbibliotheken zum Behandeln von Ereignissen gespeichert ist. Vorhandene Versionen von Word geben Bibliotheken, die Excel-Typbibliotheken und das Outlook Typ Bibliotheken Endnotenzeichen der Cancel -Parameter als [in] -Parameter. Der Cancel -Parameter wird als [in] -Parameter markiert, sodass die common Language Runtime diese Einschränkung erzwingt und verhindert, dass alle Änderungen von verwaltetem Code an den Aufrufer zurückgegeben wird. Daher kann das Ereignis nicht aus einer verwalteten Code IA (oder PIA) abgebrochen werden.

Lösung

Dieser Bug wurde in Microsoft Office 2003 behoben.

Abhilfe

Wenn Sie eine frühere Version von Word, eine frühere Version von Excel oder eine frühere Version von Outlook verwenden, müssen Sie Ihre eigenen Verbindungspunktempfänger in verwaltetem Code herstellen. Ein benutzerdefinierter Handler kann vermeiden, den Typ-Bibliothek Abhängigkeit und der erzwungen Typ Schutz, die in der Regel gelten. Daher kann das Argument an den Aufrufer übergeben werden.

Microsoft bietet Programmierbeispiele für Abbildung nur ohne Gewährleistung oder konkludent. Dies umfasst, ist jedoch nicht beschränkt auf konkludenten Garantien der Handelsüblichkeit oder Eignung für einen bestimmten Zweck. Dieser Artikel setzt voraus, dass Sie mit der Programmiersprache, die Programmierungsbeispiele ist und mit den Tools, die zum Erstellen und Debuggen von Prozeduren verwendet werden vertraut sind. Microsoft Support-Technikern helfen Erläuterung die Funktionalität einer bestimmten Prozedur, Sie werden ändert jedoch nicht diese Beispiele bieten Funktionen hinzugefügt oder Verfahren, um Ihren Anforderungen entsprechend zu erstellen.

Generieren einer Hilfsklasse

Um direkt Ereignisse von Visual C#-Waschbecken, müssen Sie eigene Definition Dispinterface erstellen und Sie müssen auch eine Hilfsklasse zum Implementieren der Ereigniscode erstellen. Die Dispinterface-Definition muss übereinstimmen, den global eindeutigen Bezeichner (GUID) und die Dispatch-IDs (DISPIDs) für die Ereignissenke, die von der Office-Objekt erwartet wird, die Sie für Ereignisse Auffangen möchten. Um herauszufinden, was diese Werte sind, können Sie eine der folgenden Methoden verwenden:
  • Sie können den OLE-COM-Objektkatalog verwenden, die in Visual Studio .NET 2003 Professional Edition enthalten ist
  • Sie können das Platform SDK verwenden. Weitere Informationen zu Plattform-SDK die folgenden Microsoft-Website:

    http://www.microsoft.com/msdownload/platformsdk/sdkupdate
Nachdem Sie die GUID und die DISPIDs kennen, können Sie Ihre eigene Definition der Definition der Disp-Schnittstelle in Visual Basic .NET oder Visual C#-erstellen.

Dieser Artikel bietet Sie zwei Beispiele demonstrieren, wie Sie benutzerdefinierte Verbindungen zeigen, um dieses Problem zu umgehen. Das erste Beispiel veranschaulicht die Auffangen der Ereignisse des Application -Objekts für Word 2000 und das DocumentBeforeClose -Ereignis abbrechen, so dass der Benutzer das Dokument schließen kann nicht. Im zweite Beispiel Channelsenken das ItemSend -Ereignis für Outlook 2002, so dass Sie den Vorgang senden in Ihrer Anwendung abbrechen können.

Beispiel 1: Abbrechen DocumentBeforeClose -Ereignis

  1. Starten Sie Visual Studio .NET 2003. Starten Sie ein neues Projekt. SELECT c# als Projekt. Wählen Sie Windows Application als die Vorlage. Nennen Sie das Projekt MyWordEventTest , und klicken Sie dann auf OK .

    Standardmäßig wird jetzt Form1 erstellt.
  2. Klicken Sie im Menü Projekt auf Hinzufügen Verweis . Wählen Sie im Dialogfeld Microsoft Word 9.0-Objektbibliothek auf die Registerkarte COM, und klicken Sie auf auswählen , um einen Verweis hinzufügen und dann auf OK , um das Dialogfeld zu schließen.

    Eine benutzerdefinierte IA wird automatisch für Sie generiert.
  3. Klicken Sie im Menü Projekt auf Hinzufügen einer Klasse . Wählen Sie Code-Datei , und benennen Sie die Klasse Word9EventHelper.cs . Klicken Sie auf OK , um die Datei zu generieren.
  4. Fügen Sie den folgenden Code im Codefenster für Word9EventHelper.cs:
    using System;
    using System.Runtime.InteropServices;
    using Word; // The default name for a custom Word IA.
    // If you use Office XP and you have the PIAs
    // referenced in your project, you must change the previous line to read:
    // using Word = Microsoft.Office.Interop.Word;
    
    namespace WordAppEvents9
    {
    	[InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
    	GuidAttribute("000209FE-0000-0000-C000-000000000046")]
    	public interface DWordApplicationEvents9
    	{
    		[DispId(0x00000001)] void Startup();
    		[DispId(0x00000002)] void Quit();
    		[DispId(0x00000003)] void DocumentChange();
    		[DispId(0x00000004)] void DocumentOpen(Word.Document doc);
    		[DispId(0x00000006)] void DocumentBeforeClose(Word.Document doc, ref bool Cancel);	
    		[DispId(0x00000007)] void DocumentBeforePrint(Word.Document doc, ref bool Cancel);
    		[DispId(0x00000008)] void DocumentBeforeSave(Word.Document doc, ref bool SaveAsUI, ref bool Cancel);
    		[DispId(0x00000009)] void NewDocument(Word.Document doc);
    		[DispId(0x0000000a)] void WindowActivate(Word.Document doc, Word.Window wn);
    		[DispId(0x0000000b)] void WindowDeactivate(Word.Document doc, Word.Window wn);
    		[DispId(0x0000000c)] void WindowSelectionChange(Word.Selection sel);
    		[DispId(0x0000000d)] void WindowBeforeRightClick(Word.Selection sel, ref bool Cancel);
    		[DispId(0x0000000e)] void WindowBeforeDoubleClick(Word.Selection sel, ref bool Cancel);
    	}
    
    
    	public class WordAppEventHelper : DWordApplicationEvents9, IDisposable
    	{
    		public WordAppEventHelper()
    		{
    			m_oConnectionPoint = null;
    			m_Cookie = 0;
    		}
    
    		public void Startup()
    		{System.Diagnostics.Debug.WriteLine("Startup");}
    
    		public void Quit()
    		{System.Diagnostics.Debug.WriteLine("Quit");}
    
    		public void DocumentChange()
    		{System.Diagnostics.Debug.WriteLine("DocumentChange");}
    
    		public void DocumentOpen(Word.Document doc)
    		{System.Diagnostics.Debug.WriteLine("DocumentOpen");}
    
    		public void DocumentBeforeClose(Word.Document doc, ref bool Cancel)
    		{
    			System.Diagnostics.Debug.WriteLine("DocumentBeforeClose");
    			Cancel = true; // Cancel the close!
    		}
    
    		public void DocumentBeforePrint(Word.Document doc, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("DocumentBeforePrint");}
    
    		public void DocumentBeforeSave(Word.Document doc, ref bool SaveAsUI, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("DocumentBeforeSave");}
    
    		public void NewDocument(Word.Document doc)
    		{System.Diagnostics.Debug.WriteLine("NewDocument");}
    
    		public void WindowActivate(Word.Document doc, Word.Window wn)
    		{System.Diagnostics.Debug.WriteLine("WindowActivate");}
    
    		public void WindowDeactivate(Word.Document doc, Word.Window wn)
    		{System.Diagnostics.Debug.WriteLine("WindowDeactivate");}
    
    		public void WindowSelectionChange(Word.Selection sel)
    		{System.Diagnostics.Debug.WriteLine("WindowSelectionChange");}
    
    		public void WindowBeforeRightClick(Word.Selection sel, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("WindowBeforeRightClick");}
    
    		public void WindowBeforeDoubleClick(Word.Selection sel, ref bool Cancel)
    		{System.Diagnostics.Debug.WriteLine("WindowBeforeDoubleClick");}
    
    		private UCOMIConnectionPoint m_oConnectionPoint;
    		private int m_Cookie;
    
    		public void SetupConnection(Word.Application app)
    		{
    			if (m_Cookie != 0) return;
    
    			// GUID of the DIID_ApplicationEvents dispinterface.
    			Guid guid = new Guid("{000209FE-0000-0000-C000-000000000046}");
    
    			// QI for IConnectionPointContainer.
    			UCOMIConnectionPointContainer oConnPointContainer = (UCOMIConnectionPointContainer)app;
    
    			// Find the connection point and then advise.
    			oConnPointContainer.FindConnectionPoint(ref guid, out m_oConnectionPoint);
    			m_oConnectionPoint.Advise(this, out m_Cookie);
    		}
    
    		public void RemoveConnection()
    		{
    			if (m_Cookie != 0)
    			{
    				m_oConnectionPoint.Unadvise(m_Cookie);
    				m_oConnectionPoint = null;
    				m_Cookie = 0;
    			}
    		}
    
    		public void Dispose(){RemoveConnection();}
    	}
    }
  5. Wechseln Sie wieder zu Form1 hinzu, und fügen Sie eine Befehlsschaltfläche. Doppelklicken Sie auf die Befehlsschaltfläche, um das Fenster Code für "Form1.cs" angezeigt. Oder klicken Sie im Menü Ansicht auf Code , um das Fenster Code für "Form1.cs" angezeigt. Den folgenden Code-Handler der Schaltfläche für das Dokument Klicken Sie auf event:
    Word.Document doc;
    Object missing = System.Reflection.Missing.Value;
    
    // Create a new instance of Word and then set up the event handler.
    m_oApp = new Word.ApplicationClass();
    m_oAppEvents = new WordAppEvents9.WordAppEventHelper();
    m_oAppEvents.SetupConnection(m_oApp);
    
    // Make Word visible and then display a new document to test close.
    m_oApp.Visible = true;
    doc = m_oApp.Documents.Add(ref missing, ref missing, ref missing, ref missing);
    doc.UserControl = true;
    doc.Content.Text = "Try to close the document";
    
    // You only have to do this one time in this sample.
    button1.Enabled = false;
    
  6. Fügen Sie der Form1 -Klasse vor-Handler der Schaltfläche den folgenden Code:
    Word.Application m_oApp;
    WordAppEvents9.WordAppEventHelper m_oAppEvents;
    
  7. Klicken Sie im Menü Erstellen auf Erstellen Projektmappen des Projekts vornehmen. Klicken Sie auf Debuggen , und klicken Sie auf Start , um die Anwendung auszuführen.

    Wenn die Anwendung gestartet wird, können Sie auf die Befehlsschaltfläche klicken, und dann Word angezeigt. Sie können nicht das Word Fenster schließen, bis Sie die Anwendung schließen.

    Ähnlichen Code können zum Behandeln von Ereignissen für Excel.

Beispiel 2: Abbrechen ItemSend -Ereignis

  1. Starten Sie Visual Studio .NET 2003. Starten Sie ein neues Projekt. SELECT c# als Projekt. Wählen Sie Windows Application als die Vorlage. Nennen Sie das Projekt MyOutlookEventTest , und klicken Sie dann auf OK .

    Standardmäßig wird jetzt Form1 erstellt.
  2. Klicken Sie im Menü Projekt auf Hinzufügen Verweis . Wählen Sie im Dialogfeld Microsoft Outlook 10.0-Objektbibliothek auf die Registerkarte COM, und klicken Sie auf auswählen , um einen Verweis hinzufügen und dann auf OK , um das Dialogfeld zu schließen.

    Eine benutzerdefinierte IA wird automatisch für Sie generiert.
  3. Klicken Sie im Menü Projekt auf Hinzufügen einer Klasse . Wählen Sie Code-Datei , und benennen Sie die Klasse Outlook10EventHelper.cs . Klicken Sie auf OK , um die Datei zu generieren.
  4. Fügen Sie in das Codefenster den folgenden Code für Outlook10EventHelper.cs:
    using System;
    using System.Runtime.InteropServices;
    //using Outlook; // The default name for a custom Word IA.
    // If you use Office XP and you have the PIAs
    // referenced in your project, you must change the previous line to read:
    using Outlook = Microsoft.Office.Interop.Outlook;
    using System.Windows.Forms;
    
    namespace OutlookAppEvents10
    {
    	[InterfaceType(ComInterfaceType.InterfaceIsIDispatch),
    	GuidAttribute("0006300E-0000-0000-C000-000000000046")]
    	public interface DOutlookApplicationEvents_10
    	{
    		void ItemSend(object Item, ref bool Cancel);
    		void NewMail();
    		void Reminder(object Item);
    		void OptionsPagesAdd(Outlook.PropertyPages Pages);
    		void Startup();
    		void Quit();
    		void AdvancedSearchComplete(Outlook.Search SearchObject);
    		void AdvancedSearchStopped(Outlook.Search SearchObject);
    		void MAPILogonComplete();
    	}
    
    	public class OutlookAppEventHelper : IDisposable
    	{
    		public OutlookAppEventHelper()
    		{
    			m_oConnectionPoint = null;
    			m_Cookie = 0;
    		}
    
    		private UCOMIConnectionPoint m_oConnectionPoint;
    		private int m_Cookie;
    
    		public void SetupConnection(Outlook.Application app)
    		{
    			if (m_Cookie != 0) return;
    			// GUID of the DIID_ApplicationEvents dispinterface.
    			Guid guid = new Guid("{0006300E-0000-0000-C000-000000000046}");
    
    			// QI for IConnectionPointContainer.
    			UCOMIConnectionPointContainer oConnectionPointContainer = (UCOMIConnectionPointContainer)app;
    
    			// Find the connection point and then advise.
    			oConnectionPointContainer.FindConnectionPoint(ref guid, out m_oConnectionPoint);
    			m_oConnectionPoint.Advise(this, out m_Cookie);
    		}
    
    		public void RemoveConnection()
    		{
    			if (m_Cookie != 0)
    			{
    				m_oConnectionPoint.Unadvise(m_Cookie);
    				m_oConnectionPoint = null;
    				m_Cookie = 0;
    			}
    		}
    
    		#region IDisposable Members
    
    		public void Dispose()
    		{
    			RemoveConnection();
    		}
    
    		#endregion
    
    		//#region DOutlookApplicationEvents_10 Members
    
    		[DispId(0x0000F002)]
    		public void ItemSend(object Item, ref bool Cancel)
    		{
    			DialogResult result;
    			result = MessageBox.Show("Do you want to cancel the ItemSend event?","",MessageBoxButtons.YesNo);
    			if(result == DialogResult.Yes)
    			{
    				System.Diagnostics.Debug.WriteLine("Cancelling Message");
    				Cancel = true;	
    			}
    			else
    			{
    				System.Diagnostics.Debug.WriteLine("Passing Message");
    				Cancel = false;
    			}
    		}
    
    		[DispId(0x0000F003)]
    		public void NewMail()
    		{
    			MessageBox.Show("NewMail");
    		}
    
    		[DispId(0x0000F004)]
    		public void Reminder(object Item)
    		{
    			MessageBox.Show("Reminder");
    		}
    
    		[DispId(0x0000F005)]
    		public void OptionsPagesAdd(Microsoft.Office.Interop.Outlook.PropertyPages Pages)
    		{
    			MessageBox.Show("OptionsPagesAdd");
    		}
    
    		[DispId(0x0000F006)]
    		public void Startup()
    		{
    			MessageBox.Show("Startup");
    		}
    
    		[DispId(0x0000F007)]
    		public void Quit()
    		{
    			MessageBox.Show("Quit");
    		}
    
    		[DispId(0x0000FA6A)]
    		public void AdvancedSearchComplete(Microsoft.Office.Interop.Outlook.Search SearchObject)
    		{
    			MessageBox.Show("AdvancedSearchComplete");
    		}
    
    		[DispId(0x0000FA6B)]
    		public void AdvancedSearchStopped(Microsoft.Office.Interop.Outlook.Search SearchObject)
    		{
    			MessageBox.Show("AdvancedSearchStopped");
    		}
    
    		[DispId(0x0000FA90)]
    		public void MAPILogonComplete()
    		{
    			MessageBox.Show("MAPILogonComplete");
    		}
    		//#endregion
    	}
    }
    Note You need to place the [DispId(#)] attribute on the methods. Andernfalls kann nicht das Ereignis abgebrochen werden.
  5. Wechseln Sie wieder zu Form1 hinzu, und fügen Sie eine Befehlsschaltfläche. Doppelklicken Sie auf die Befehlsschaltfläche, um das Fenster Code für "Form1.cs" angezeigt. Oder klicken Sie im Menü Ansicht auf Code , um das Fenster Code für "Form1.cs" angezeigt. Fügen Sie den folgenden Code hinzu Schaltfläche Handler für das Element Klicken Sie auf event:
    Outlook.MailItem item;
    
    if (m_oApp == null)
    {
    	// Create a new instance of Outlook and then set up the event handler.
    	m_oApp = new Outlook.ApplicationClass();
    	m_oAppEvents = new OutlookAppEvents10.OutlookAppEventHelper();
    	m_oAppEvents.SetupConnection(m_oApp);
    } 
    
    // Make Outlook visible and then display a new message to test send.
    item = (Outlook.MailItem)m_oApp.CreateItem(Outlook.OlItemType.olMailItem);
    item.Subject = "The Subject!";
    item.Body = "Try sending the message.";
    item.Display(m_oApp);
  6. Fügen Sie der Form1 -Klasse vor-Handler der Schaltfläche den folgenden Code:
    Outlook.Application m_oApp;
    OutlookAppEvents10.OutlookAppEventHelper m_oAppEvents;
    
  7. Klicken Sie im Menü Erstellen auf Erstellen Projektmappen des Projekts vornehmen. Klicken Sie auf Debuggen , und klicken Sie auf Start , um die Anwendung auszuführen.

    Wenn die Anwendung gestartet wird, können Sie auf die Befehlsschaltfläche klicken, und anschließend Outlook angezeigt. Ein neue e-Mail-Entwurf wird automatisch erstellt. Geben Sie einen Empfänger in der Zeile an , und klicken Sie Senden . Sie erhalten eine Popup-Dialogfeld Sie gefragt werden, wenn das ItemSend-Ereignis abgebrochen werden soll. Klicken Sie auf Ja, um ihn abzubrechen.

    Ähnlichen Code können zum Behandeln von Ereignissen für Excel.

Status

Microsoft hat bestätigt, dass dies ein Problem in den Microsoft-Produkten ist, die im Abschnitt "Gilt für" dieses Artikels aufgeführt sind.

Informationsquellen

Weitere Informationen zum Automatisieren von Office von Visual Studio .NET finden Sie im folgenden Artikel der Microsoft Knowledge Base:
311452Entwickeln von Microsoft Office-Lösungen mit Visual Studio .NET
317109Office-Anwendung wird nicht nach der Automatisierung von Visual Studio .NET Client beendet.

Eigenschaften

Artikel-ID: 830519 - Geändert am: Donnerstag, 27. Februar 2014 - Version: 3.5
Die Informationen in diesem Artikel beziehen sich auf:
  • Microsoft Excel 2002 Standard Edition
  • Microsoft Word 2002 Standard Edition
  • Microsoft Outlook 2002 Standard Edition
  • Microsoft Excel 2000 Standard Edition
  • Microsoft Word 2000 Standard Edition
  • Microsoft Outlook 2000
  • Microsoft .NET Framework 1.1
  • Microsoft Visual Studio .NET 2003 Professional Edition
  • Microsoft Visual Studio .NET 2003 Enterprise Architect
  • Microsoft Visual Studio .NET 2003 Academic Edition
Keywords: 
kbnosurvey kbarchive kbmt kbnofix kbbug KB830519 KbMtde
Maschinell übersetzter Artikel
Wichtig: Dieser Artikel wurde maschinell und nicht von einem Menschen übersetzt. Die Microsoft Knowledge Base ist sehr umfangreich und ihre Inhalte werden ständig ergänzt beziehungsweise überarbeitet. Um Ihnen dennoch alle Inhalte auf Deutsch anbieten zu können, werden viele Artikel nicht von Menschen, sondern von Übersetzungsprogrammen übersetzt, die kontinuierlich optimiert werden. Doch noch sind maschinell übersetzte Texte in der Regel nicht perfekt, insbesondere hinsichtlich Grammatik und des Einsatzes von Fremdwörtern sowie Fachbegriffen. Microsoft übernimmt keine Gewähr für die sprachliche Qualität oder die technische Richtigkeit der Übersetzungen und ist nicht für Probleme haftbar, die direkt oder indirekt durch Übersetzungsfehler oder die Verwendung der übersetzten Inhalte durch Kunden entstehen könnten.
Den englischen Originalartikel können Sie über folgenden Link abrufen: 830519
Microsoft stellt Ihnen die in der Knowledge Base angebotenen Artikel und Informationen als Service-Leistung zur Verfügung. Microsoft übernimmt keinerlei Gewährleistung dafür, dass die angebotenen Artikel und Informationen auch in Ihrer Einsatzumgebung die erwünschten Ergebnisse erzielen. Die Entscheidung darüber, ob und in welcher Form Sie die angebotenen Artikel und Informationen nutzen, liegt daher allein bei Ihnen. Mit Ausnahme der gesetzlichen Haftung für Vorsatz ist jede Haftung von Microsoft im Zusammenhang mit Ihrer Nutzung dieser Artikel oder Informationen ausgeschlossen.

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com