Vorgehensweise: Erstellen eines Snapshots für eine Mergeveröffentlichung mit parametrisierten Filtern (RMO-Programmierung)

Zur Erstellung eines Snapshots für eine Mergeveröffentlichung mithilfe von parametrisierten Filtern müssen Sie zunächst einen Standardsnapshot (Schema) erstellen, der alle Abonnentenmetadaten für das Abonnement enthält. Dann generieren Sie den Teil des Snapshots, der die abonnentenspezifische Partition der veröffentlichten Daten enthält. Weitere Informationen finden Sie unter Vorgehensweise: Erstellen des Anfangssnapshots (RMO-Programmierung).

Sie können Replikationsverwaltungsobjekte (RMO) verwenden, um partitionierte Snapshots mit einem der folgenden Verfahren programmgesteuert zu generieren:

  • Anfordern der Snapshotgenerierung und -anwendung durch Abonnenten beim erstmaligen Synchronisieren

  • Vorabgenerieren von Snapshots für jede Partition

  • Manuelles Generieren eines Snapshots für jeden Abonnenten durch Ausführen des Snapshot-Agent

HinweisHinweis

Wenn das Filtern für einen Artikel nicht überlappende Partitionen ergibt, die für jedes Abonnement eindeutig sind (durch Angabe des Werts NonOverlappingSingleSubscription für PartitionOption beim Erstellen eines Mergeartikels), werden Metadaten immer dann bereinigt, wenn der Merge-Agent ausgeführt wird. Das bedeutet, dass der partitionierte Snapshot schneller abläuft. Bei dieser Methode sollten Sie zulassen, dass Abonnenten das Generieren von Snapshots anfordern. Weitere Informationen finden Sie unter "Verwenden der richtigen Filteroptionen" im Thema Parametrisierte Zeilenfilter.

SicherheitshinweisSicherheitshinweis

Benutzer sollten nach Möglichkeit dazu aufgefordert werden, Anmeldeinformationen zur Laufzeit einzugeben. Wenn Sie Anmeldeinformationen speichern müssen, verwenden Sie die Kryptografiedienste von Microsoft Windows .NET Framework.

So erstellen Sie eine Veröffentlichung, die es Abonnenten ermöglicht, die Generierung und Übermittlung von Snapshots zu initiieren

  1. Erstellen Sie eine Verbindung mit dem Verleger, indem Sie die ServerConnection-Klasse verwenden.

  2. Erstellen Sie eine Instanz der ReplicationDatabase-Klasse für die Veröffentlichungsdatenbank, legen Sie die ConnectionContext-Eigenschaft auf die Instanz von ServerConnection aus Schritt 1 fest, und rufen Sie die LoadProperties-Methode auf. Wenn LoadProperties den Wert false zurückgibt, vergewissern Sie sich, dass die Datenbank vorhanden ist.

  3. Wenn die EnabledMergePublishing-Eigenschaft false lautet, legen Sie sie auf true fest, und rufen Sie CommitPropertyChanges auf.

  4. Erstellen Sie eine Instanz der MergePublication-Klasse, und legen Sie die folgenden Eigenschaften für dieses Objekt fest:

    • Die ServerConnection aus Schritt 1 für ConnectionContext

    • Den Namen der veröffentlichten Datenbank für DatabaseName

    • Einen Namen für die Veröffentlichung für Name

    • Die maximale Anzahl an Aufträgen für dynamische Snapshots, die für MaxConcurrentDynamicSnapshots ausgeführt werden können. Da von Abonnenten initiierte Snapshotanforderungen jederzeit erfolgen können, begrenzt diese Eigenschaft die Anzahl der Snapshot-Agentaufträge, die gleichzeitig ausgeführt werden können, wenn mehrere Abonnenten ihren partitionierten Snapshot gleichzeitig anfordern. Wenn die maximale Anzahl an Aufträgen ausgeführt wird, werden weitere Anforderungen für partitionierte Snapshots in die Warteschlange eingefügt, bis einer der Aufträge abgeschlossen ist.

    • Verwenden Sie einen bitweisen logischen OR-Operator (| in Visual C# und Or in Visual Basic), um Attributes den Wert AllowSubscriberInitiatedSnapshot hinzuzufügen.

    • Die Felder Login und Password von SnapshotGenerationAgentProcessSecurity, um die Anmeldeinformationen für das Microsoft Windows-Konto bereitzustellen, unter dem der Snapshot-Agentauftrag ausgeführt wird.

      HinweisHinweis

      Wenn die Veröffentlichung von einem Mitglied der festen Serverrolle sysadmin erstellt wird, empfiehlt es sich, SnapshotGenerationAgentProcessSecurity festzulegen. Weitere Informationen finden Sie unter Sicherheitsmodell des Replikations-Agents.

  5. Rufen Sie die Create-Methode auf, um die Veröffentlichung zu erstellen.

    SicherheitshinweisSicherheitshinweis

     Beim Konfigurieren eines Verlegers mit einem Remoteverteiler werden die Werte, die für alle Eigenschaften einschließlich SnapshotGenerationAgentProcessSecurity bereitgestellt werden, als Nur-Text an den Verteiler gesendet. Sie sollten die Verbindung zwischen dem Verleger und dem zugehörigen Remoteverteiler verschlüsseln, bevor Sie die Create-Methode aufrufen. Weitere Informationen finden Sie unter Verschlüsseln von Verbindungen zu SQL Server.

  6. Verwenden Sie die MergeArticle-Eigenschaft, um der Veröffentlichung Artikel hinzuzufügen. Geben Sie die FilterClause-Eigenschaft für wenigstens einen Artikel an, der den parametrisierten Filter definiert. (Optional) Erstellen Sie MergeJoinFilter-Objekte, die Verknüpfungsfilter zwischen Artikeln definieren. Weitere Informationen finden Sie unter Vorgehensweise: Definieren eines Artikels (RMO-Programmierung).

  7. Wenn der Wert für SnapshotAgentExists auf false lautet, rufen Sie CreateSnapshotAgent auf, um den Agentauftrag für den Anfangssnapshot dieser Veröffentlichung zu erstellen.

  8. Rufen Sie die StartSnapshotGenerationAgentJob-Methode des in Schritt 4 erstellten MergePublication-Objekts auf. Dadurch wird der Agentauftrag gestartet, der den Anfangssnapshot generiert. Weitere Informationen darüber, wie ein Anfangssnapshot generiert und ein benutzerdefinierter Zeitplan für den Snapshot-Agent definiert wird, finden Sie unter Vorgehensweise: Erstellen des Anfangssnapshots (RMO-Programmierung).

  9. (Optional) Kontrollieren Sie, wann die SnapshotAvailable-Eigenschaft auf true lautet, um zu ermitteln, wann der Anfangssnapshot verwendet werden kann.

  10. Wenn der Merge-Agent eines Abonnenten die Verbindung erstmalig herstellt, wird automatisch ein partitionierter Snapshot generiert.

So erstellen Sie eine Veröffentlichung und generieren Snapshots vorab oder aktualisieren sie automatisch

  1. Verwenden Sie eine Instanz der MergePublication-Klasse, um eine Mergeveröffentlichung zu definieren. Weitere Informationen finden Sie unter Vorgehensweise: Erstellen einer Veröffentlichung (RMO-Programmierung).

  2. Verwenden Sie die MergeArticle-Eigenschaft, um der Veröffentlichung Artikel hinzuzufügen. Geben Sie die FilterClause-Eigenschaft für mindestens einen Artikel an, der den parametrisierten Filter definiert, und erstellen Sie beliebige MergeJoinFilter-Objekte, die Verknüpfungsfilter zwischen Artikeln definieren. Weitere Informationen finden Sie unter Vorgehensweise: Definieren eines Artikels (RMO-Programmierung).

  3. Wenn der Wert für SnapshotAgentExistsfalse lautet, rufen Sie CreateSnapshotAgent auf, um den Agentauftrag für den Snapshot dieser Veröffentlichung zu erstellen.

  4. Rufen Sie die StartSnapshotGenerationAgentJob-Methode des in Schritt 1 erstellten MergePublication-Objekts auf. Durch diese Methode wird der Agentauftrag gestartet, der den Anfangssnapshot generiert. Weitere Informationen darüber, wie ein Anfangssnapshot generiert und ein benutzerdefinierter Zeitplan für den Snapshot-Agent definiert wird, finden Sie unter Vorgehensweise: Erstellen des Anfangssnapshots (RMO-Programmierung).

  5. Kontrollieren Sie, wann die SnapshotAvailable-Eigenschaft true lautet, um zu ermitteln, wann der Anfangssnapshot verwendet werden kann.

  6. Erstellen Sie eine Instanz der MergePartition-Klasse, und legen Sie die Kriterien für den parametrisierten Filter des Abonnenten fest, indem Sie eine der folgenden Eigenschaften oder beide verwenden:

  7. Erstellen Sie eine Instanz der MergeDynamicSnapshotJob-Klasse, und legen Sie dieselbe Eigenschaft wie in Schritt 6 fest.

  8. Verwenden Sie die ReplicationAgentSchedule-Klasse, um einen Zeitplan für die Generierung des gefilterten Snapshots für die Abonnentenpartition zu definieren.

  9. Rufen Sie mithilfe der Instanz von MergePublication aus Schritt 1 AddMergePartition auf. Übergeben Sie das MergePartition-Objekt aus Schritt 6.

  10. Rufen Sie mithilfe der Instanz von MergePublication aus Schritt 1 die AddMergeDynamicSnapshotJob-Methode auf. Übergeben Sie das MergeDynamicSnapshotJob-Objekt aus Schritt 7 und das ReplicationAgentSchedule-Objekt aus Schritt 8.

  11. Rufen Sie EnumMergeDynamicSnapshotJobs auf, und suchen Sie im zurückgegebenen Array nach dem MergeDynamicSnapshotJob-Objekt für den neu hinzugefügten Auftrag für den partitionierten Snapshot.

  12. Rufen Sie die Name-Eigenschaft für den Auftrag ab.

  13. Erstellen Sie eine Verbindung zum Verteiler, indem Sie die ServerConnection-Klasse verwenden.

  14. Erstellen Sie eine Instanz der Server-Klasse für SQL Server Management Objects (SMO), indem Sie das ServerConnection-Objekt aus Schritt 13 übergeben.

  15. Erstellen Sie eine Instanz der Job-Klasse, indem Sie die JobServer-Eigenschaft des Server-Objekts aus Schritt 14 und den Auftragnamen aus Schritt 12 übergeben.

  16. Rufen Sie die Start-Methode auf, um den Auftrag für den partitionierten Snapshot zu starten.

  17. Wiederholen Sie die Schritte 6 bis 16 für jeden Abonnenten.

So erstellen Sie eine Veröffentlichung und für jede Partition manuell Snapshots

  1. Verwenden Sie eine Instanz der MergePublication-Klasse, um eine Mergeveröffentlichung zu definieren. Weitere Informationen finden Sie unter Vorgehensweise: Erstellen einer Veröffentlichung (RMO-Programmierung).

  2. Verwenden Sie die MergeArticle-Eigenschaft, um der Veröffentlichung Artikel hinzuzufügen. Geben Sie die FilterClause-Eigenschaft für mindestens einen Artikel an, der den parametrisierten Filter definiert, und erstellen Sie beliebige MergeJoinFilter-Objekte, die Verknüpfungsfilter zwischen Artikeln definieren. Weitere Informationen finden Sie unter Vorgehensweise: Definieren eines Artikels (RMO-Programmierung).

  3. Generieren Sie den Anfangssnapshot. Weitere Informationen finden Sie unter Vorgehensweise: Erstellen des Anfangssnapshots (RMO-Programmierung).

  4. Erstellen Sie eine Instanz der SnapshotGenerationAgent-Klasse, und legen Sie die folgenden erforderlichen Eigenschaften fest:

  5. Legen Sie den Wert Merge für ReplicationType fest.

  6. Legen Sie eine oder mehrere der folgenden Eigenschaften fest, um die Partitionierungsparameter zu definieren:

  7. Rufen Sie die GenerateSnapshot-Methode auf.

  8. Wiederholen Sie die Schritte 4 - 7 für jeden Abonnenten.

Beispiel

In diesem Beispiel wird eine Mergeveröffentlichung erstellt, die es Abonnenten ermöglicht, die Snapshotgenerierung anzufordern.

         // Set the Publisher, publication database, and publication names.
            string publisherName = publisherInstance;
            string publicationName = "AdvWorksSalesOrdersMerge";
            string publicationDbName = "AdventureWorks2008R2";

            ReplicationDatabase publicationDb;
            MergePublication publication;

            // Create a connection to the Publisher.
            ServerConnection conn = new ServerConnection(publisherName);

            try
            {
                // Connect to the Publisher.
                conn.Connect();

                // Enable the database for merge publication.               
                publicationDb = new ReplicationDatabase(publicationDbName, conn);
                if (publicationDb.LoadProperties())
                {
                    if (!publicationDb.EnabledMergePublishing)
                    {
                        publicationDb.EnabledMergePublishing = true;
                    }
                }
                else
                {
                    // Do something here if the database does not exist. 
                    throw new ApplicationException(String.Format(
                        "The {0} database does not exist on {1}.",
                        publicationDb, publisherName));
                }

                // Set the required properties for the merge publication.
                publication = new MergePublication();
                publication.ConnectionContext = conn;
                publication.Name = publicationName;
                publication.DatabaseName = publicationDbName;

                // Enable precomputed partitions.
                publication.PartitionGroupsOption = PartitionGroupsOption.True;

                // Specify the Windows account under which the Snapshot Agent job runs.
                // This account will be used for the local connection to the 
                // Distributor and all agent connections that use Windows Authentication.
                publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin;
                publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword;

                // Explicitly set the security mode for the Publisher connection
                // Windows Authentication (the default).
                publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = true;

                // Enable Subscribers to request snapshot generation and filtering.
                publication.Attributes |= PublicationAttributes.AllowSubscriberInitiatedSnapshot;
                publication.Attributes |= PublicationAttributes.DynamicFilters;

                // Enable pull and push subscriptions.
                publication.Attributes |= PublicationAttributes.AllowPull;
                publication.Attributes |= PublicationAttributes.AllowPush;

                if (!publication.IsExistingObject)
                {
                    // Create the merge publication.
                    publication.Create();
                    
                    // Create a Snapshot Agent job for the publication.
                    publication.CreateSnapshotAgent();
                }
                else
                {
                    throw new ApplicationException(String.Format(
                        "The {0} publication already exists.", publicationName));
                }
            }

            catch (Exception ex)
            {
                // Implement custom application error handling here.
                throw new ApplicationException(String.Format(
                    "The publication {0} could not be created.", publicationName), ex);
            }
            finally
            {
                conn.Disconnect();
            }
' Set the Publisher, publication database, and publication names.
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2008R2"

Dim publicationDb As ReplicationDatabase
Dim publication As MergePublication

' Create a connection to the Publisher.
Dim conn As ServerConnection = New ServerConnection(publisherName)

Try
    ' Connect to the Publisher.
    conn.Connect()

    ' Enable the database for merge publication.                
    publicationDb = New ReplicationDatabase(publicationDbName, conn)
    If publicationDb.LoadProperties() Then
        If Not publicationDb.EnabledMergePublishing Then
            publicationDb.EnabledMergePublishing = True
        End If
    Else
        ' Do something here if the database does not exist. 
        Throw New ApplicationException(String.Format( _
         "The {0} database does not exist on {1}.", _
         publicationDb, publisherName))
    End If

    ' Set the required properties for the merge publication.
    publication = New MergePublication()
    publication.ConnectionContext = conn
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName

    ' Enable precomputed partitions.
    publication.PartitionGroupsOption = PartitionGroupsOption.True

    ' Specify the Windows account under which the Snapshot Agent job runs.
    ' This account will be used for the local connection to the 
    ' Distributor and all agent connections that use Windows Authentication.
    publication.SnapshotGenerationAgentProcessSecurity.Login = winLogin
    publication.SnapshotGenerationAgentProcessSecurity.Password = winPassword

    ' Explicitly set the security mode for the Publisher connection
    ' Windows Authentication (the default).
    publication.SnapshotGenerationAgentPublisherSecurity.WindowsAuthentication = True

    ' Enable Subscribers to request snapshot generation and filtering.
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowSubscriberInitiatedSnapshot
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.DynamicFilters

    ' Enable pull and push subscriptions
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowPull
    publication.Attributes = publication.Attributes Or _
        PublicationAttributes.AllowPush

    If Not publication.IsExistingObject Then
        ' Create the merge publication.
        publication.Create()

        ' Create a Snapshot Agent job for the publication.
        publication.CreateSnapshotAgent()
    Else
        Throw New ApplicationException(String.Format( _
            "The {0} publication already exists.", publicationName))
    End If
Catch ex As Exception
    ' Implement custom application error handling here.
    Throw New ApplicationException(String.Format( _
        "The publication {0} could not be created.", publicationName), ex)
Finally
    conn.Disconnect()
End Try

In diesem Beispiel werden die Abonnentenpartition und der gefilterte Snapshot für eine Mergeveröffentlichung mit parametrisierten Zeilenfiltern manuell erstellt.

           // Define the server, database, and publication names
            string publisherName = publisherInstance;
            string publicationName = "AdvWorksSalesOrdersMerge";
            string publicationDbName = "AdventureWorks2008R2";
            string distributorName = publisherInstance;

            MergePublication publication;
            MergePartition partition;
            MergeDynamicSnapshotJob snapshotAgentJob;
            ReplicationAgentSchedule schedule;
            
            // Create a connection to the Publisher.
            ServerConnection publisherConn = new ServerConnection(publisherName);

            // Create a connection to the Distributor to start the Snapshot Agent.
            ServerConnection distributorConn = new ServerConnection(distributorName);

            try
            {
                // Connect to the Publisher.
                publisherConn.Connect();

                // Set the required properties for the publication.
                publication = new MergePublication();
                publication.ConnectionContext = publisherConn;
                publication.Name = publicationName;
                publication.DatabaseName = publicationDbName;


                // If we can't get the properties for this merge publication, 
                // then throw an application exception.
                if (publication.LoadProperties() || publication.SnapshotAvailable)
                {
                    // Set a weekly schedule for the filtered data snapshot.
                    schedule = new ReplicationAgentSchedule();
                    schedule.FrequencyType = ScheduleFrequencyType.Weekly;
                    schedule.FrequencyRecurrenceFactor = 1;
                    schedule.FrequencyInterval = Convert.ToInt32(0x001);

                    // Set the value of Hostname that defines the data partition. 
                    partition = new MergePartition();
                    partition.DynamicFilterHostName = hostname;
                    snapshotAgentJob = new MergeDynamicSnapshotJob();
                    snapshotAgentJob.DynamicFilterHostName = hostname;

                    // Create the partition for the publication with the defined schedule.
                    publication.AddMergePartition(partition);
                    publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule);
                }
                else
                {
                    throw new ApplicationException(String.Format(
                        "Settings could not be retrieved for the publication, " +
                        " or the initial snapshot has not been generated. " +
                        "Ensure that the publication {0} exists on {1} and " +
                        "that the Snapshot Agent has run successfully.",
                        publicationName, publisherName));
                }
            }
            catch (Exception ex)
            {
                // Do error handling here.
                throw new ApplicationException(string.Format(
                    "The partition for '{0}' in the {1} publication could not be created.",
                    hostname, publicationName), ex);
            }
            finally
            {
                publisherConn.Disconnect();
                if (distributorConn.IsOpen) distributorConn.Disconnect();
            }
' Define the server, database, and publication names
Dim publisherName As String = publisherInstance
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2008R2"
Dim distributorName As String = publisherInstance

Dim publication As MergePublication
Dim partition As MergePartition
Dim snapshotAgentJob As MergeDynamicSnapshotJob
Dim schedule As ReplicationAgentSchedule

' Create a connection to the Publisher.
Dim publisherConn As ServerConnection = New ServerConnection(publisherName)

' Create a connection to the Distributor to start the Snapshot Agent.
Dim distributorConn As ServerConnection = New ServerConnection(distributorName)

Try
    ' Connect to the Publisher.
    publisherConn.Connect()

    ' Set the required properties for the publication.
    publication = New MergePublication()
    publication.ConnectionContext = publisherConn
    publication.Name = publicationName
    publication.DatabaseName = publicationDbName


    ' If we can't get the properties for this merge publication, 
    ' then throw an application exception.
    If (publication.LoadProperties() Or publication.SnapshotAvailable) Then
        ' Set a weekly schedule for the filtered data snapshot.
        schedule = New ReplicationAgentSchedule()
        schedule.FrequencyType = ScheduleFrequencyType.Weekly
        schedule.FrequencyRecurrenceFactor = 1
        schedule.FrequencyInterval = Convert.ToInt32("0x001", 16)

        ' Set the value of Hostname that defines the data partition. 
        partition = New MergePartition()
        partition.DynamicFilterHostName = hostname
        snapshotAgentJob = New MergeDynamicSnapshotJob()
        snapshotAgentJob.DynamicFilterHostName = hostname

        ' Create the partition for the publication with the defined schedule.
        publication.AddMergePartition(partition)
        publication.AddMergeDynamicSnapshotJob(snapshotAgentJob, schedule)
    Else
        Throw New ApplicationException(String.Format( _
         "Settings could not be retrieved for the publication, " + _
         " or the initial snapshot has not been generated. " + _
         "Ensure that the publication {0} exists on {1} and " + _
         "that the Snapshot Agent has run successfully.", _
         publicationName, publisherName))
    End If
Catch ex As Exception
    ' Do error handling here.
    Throw New ApplicationException(String.Format( _
     "The partition for '{0}' in the {1} publication could not be created.", _
     hostname, publicationName), ex)
Finally
    publisherConn.Disconnect()
    If distributorConn.IsOpen Then
        distributorConn.Disconnect()
    End If
End Try

In diesem Beispiel wird der Snapshot-Agent manuell gestartet, um die gefilterten Snapshotdaten für den Abonnenten einer Mergeveröffentlichung mit parametrisierten Zeilenfiltern zu generieren.

         // Set the Publisher, publication database, and publication names.
            string publicationName = "AdvWorksSalesOrdersMerge";
            string publicationDbName = "AdventureWorks2008R2";
            string publisherName = publisherInstance;
            string distributorName = publisherInstance;

            SnapshotGenerationAgent agent;

            try
            {
                // Set the required properties for Snapshot Agent.
                agent = new SnapshotGenerationAgent();
                agent.Distributor = distributorName;
                agent.DistributorSecurityMode = SecurityMode.Integrated;
                agent.Publisher = publisherName;
                agent.PublisherSecurityMode = SecurityMode.Integrated;
                agent.Publication = publicationName;
                agent.PublisherDatabase = publicationDbName;
                agent.ReplicationType = ReplicationType.Merge;

                // Specify the partition information to generate a 
                // filtered snapshot based on Hostname.
                agent.DynamicFilterHostName = hostname;

                // Start the agent synchronously.
                agent.GenerateSnapshot();
            }
            catch (Exception ex)
            {
                // Implement custom application error handling here.
                throw new ApplicationException(String.Format(
                    "A snapshot could not be generated for the {0} publication."
                    , publicationName), ex);
            }
' Set the Publisher, publication database, and publication names.
Dim publicationName As String = "AdvWorksSalesOrdersMerge"
Dim publicationDbName As String = "AdventureWorks2008R2"
Dim publisherName As String = publisherInstance
Dim distributorName As String = publisherInstance

Dim agent As SnapshotGenerationAgent

Try
    ' Set the required properties for Snapshot Agent.
    agent = New SnapshotGenerationAgent()
    agent.Distributor = distributorName
    agent.DistributorSecurityMode = SecurityMode.Integrated
    agent.Publisher = publisherName
    agent.PublisherSecurityMode = SecurityMode.Integrated
    agent.Publication = publicationName
    agent.PublisherDatabase = publicationDbName
    agent.ReplicationType = ReplicationType.Merge

    ' Specify the partition information to generate a 
    ' filtered snapshot based on Hostname.
    agent.DynamicFilterHostName = hostname

    ' Start the agent synchronously.
    agent.GenerateSnapshot()
Catch ex As Exception
    ' Implement custom application error handling here.
    Throw New ApplicationException(String.Format( _
     "A snapshot could not be generated for the {0} publication." _
     , publicationName), ex)
End Try