SharePointCommunity
Die deutschsprachige Community für SharePoint, Microsoft 365, Teams, Yammer und mit Azure

Sponsored by

Willkommen im Forum Archiv.
Einträge sind hier nicht mehr möglich, aber der Bestand von 12 Jahren SharePoint-Wissen ist hier recherchierbar.




Workflow manuell starten

Unbeantwortet Dieser Beitrag hat 25 Antworten

Ohne Rang
37 Beiträge
Chris 22 erstellt 8 Okt. 2010 09:56
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 Hi all,

ich habe in VS einen State Machine Workflow erstellt, den ich nun manuell starten muss, jedoch klappt das nicht. Der Workflow an sich funktioniert solange er standardmäßig verwendet wird. Zum manuellen Starten verwende ich folgenden Code:

 

public void StartWorkflow(SPWeb spWeb, SPSite spSite, SPListItem item)

{ // Initialisierungen...

 

workflowTemplate = spWeb.WorkflowTemplates.GetTemplateByName(workflowTemplateName, new CultureInfo(1033));

SPSecurity.RunWithElevatedPrivileges(delegate()

{

using (SPSite spSiteE = new SPSite(siteGuid ))

{

using (SPWeb spWebE = spSiteE.OpenWeb())

{

spWebE.AllowUnsafeUpdates = true;

 

try

{

wfAssoc = assocExists(workflowAssocName, myList);

 

if (wfAssoc == null)

{

// Add workflow association to my list

workflowAssociation = SPWorkflowAssociation.CreateListAssociation(

workflowTemplate, workflowAssocName, taskList, historyList);

myList.AddWorkflowAssociation(workflowAssociation);

}

 

//start Workflow manually

data = "<Data></Data>";

spSiteE.WorkflowManager.StartWorkflow(item, wfAssoc, data, true);

 

myList.Update();

spWebE.Update();

spWebE.AllowUnsafeUpdates = false;

}

catch (Exception e)

{...

}

Der Workflow bleibt nach dem Start in der StateInitalization des ersten Zustandes stecken, also ganz am Anfang. Beim Debuggen habe ich festgestellt dass der Fehler in der System-Klasse ApplicationBrowserCapabilitiesFactory geworfen wird. Ich habe keinerlei Anhaltspunkte was ich falsch mache. Fehlt die Verwendung der WFRuntime? Es scheint so als ob Informationen über den Ablauf fehlen...

Danke im Voraus!

Viele Güße

Alle Antworten

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 8 Okt. 2010 10:06
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Du fügst den Workflow zur Liste hinzu, versuchst ihn zu starten und rufst erst dann myList.Update() auf. Dreh das mal um.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 8 Okt. 2010 11:41
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 Das hilft nicht und auch die SPWorkflowAssociation löschen und neu setzen behebt nicht den Fehler. Wie gesagt, in der StateInitalization werden alle Aktivitäten ausgeführt (Code-Aktivitäten). Im nächsten Schritt (gleicher Zustand) folgt eine EventDriven, diese wird aber nicht mehr erreicht.

Der WF wird übrigens in einem EventReceiver gestartet.

 

Ich hatte schon vermutet, dass es vielleicht an den WorkflowAssociation liegt. Diese sind immer null, werden dann von mir auf "<Data></Data>"; gesetzt. (Dummy Daten)

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 8 Okt. 2010 12:12
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Das ganze Konstrukt klingt etwas konfus, sorry.

Warum startest Du einen Workflow aus einem EventReceiver? Dann kann der Workflow doch gleich automatisch starten. Man kann ihn auch einfach bei Neuanlage starten und auf einen bestimmten Zustand warten lassen, den man dann aus dem EventReceiver heraus herstellt.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 8 Okt. 2010 12:16
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Sorry, gemeint war dass die  AssociationData = null sind. Könnte das eine Fehlerquelle sein?

Die Startreihenfolge hat was mit der Reihenfolge der durchzuführenden Aktionen zu tun. Der WF greift auf Elemente zu die Vom EventR. erstellt werden.

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 8 Okt. 2010 12:28
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Chris 22"]gemeint war dass die  AssociationData = null sind. Könnte das eine Fehlerquelle sein?[/quote]

Nein, außer Dein Workflowcode ist zwingend darauf angewiesen.

Tut mir leid, aber dann habe ich keine Idee, was da schiefläuft :-(

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 8 Okt. 2010 15:54
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Ok, nur um auszuschließen, dass der Fehler am Veröffentlichen liegt:

Eigentlich werden doch beim Debuggen (F5) alle relevaten Dateien des WF an die richtigen Stellen kopiert, so dass hier keine manuellen Eingriffe erfolgen müssen!?

 - .dll in den GAC

- workflow.xml und feature.xml in das entsprechende Verzeichnis in /FEATURES

Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 8 Okt. 2010 16:13
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Außerdem werden die WF Eigenschaften teils in VS Workflow gesetzt, teils in meinem Code. Ich gehe davon aus das ist kein Problem und die benötigten Eigenschaften wie Anzeigename, zugeodnete Listen, Startzustände, Zielsite werden durch meinen Code ergänzt oder überschrieben... !?

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 8 Okt. 2010 16:37
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Grundsätzlich sollte da kein Unterschied bestehen, aber wer außer Dir weiß schon, was Du da alles programmiert hast ;-)

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 11 Okt. 2010 11:06
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 

Hi Andi,

erstmal vielen Dank für die Unterstützung bei der Fehlereingrenzung.

Einen Schritt weiter bin ich schon. Der Fehler tritt auf sobald ich eine zweite Klasse in die Workflowklasse einbinde. Unter http://www.sharepointassist.com/2009/12/01/serialization-issue-with-windows-workflow-foundation-and-sharepoint-workflow/ gibt es einen Lösungsvorschlag.

Nun habe ich den problematischen Code in eine separate Klasse ausgelagert, welche mit [Serializable] vermerkt ist und und alle Klassenvariablen auf public gesetzt. Ebenso bei einer weiteren Klasse, welche von der genannten abhängig ist.

Anscheinend funktioniert die Serialisierung nicht ganz. Trotz der Änderungen tritt in den LOGs die gleiche Fehlermeldung auf:

 

Unexpected WinWF Internal Error, terminating workflow Id# adace3c1-39e6-438d-be65-1eb01259357d

Unexpected System.Workflow.Runtime.Hosting.PersistenceException: Type 'Microsoft.SharePoint.SPSite' in Assembly 'Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' is not marked as serializable. ---> System.Runtime.Serialization.SerializationException: Type 'Microsoft.SharePoint.SPSite' in Assembly 'Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c' is not marked as serializable. at System.Runtime.Serialization.FormatterServices.InternalGetSerializableMembers(RuntimeType type) at System.Runtime.Serialization.FormatterServices.GetSerializableMembers(Type type, StreamingContext context) at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.InitMemberInfo() at System.Runtime.Serialization.Formatters...

 

Unexpected ....Binary.WriteObjectInfo.InitSerialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) at System.Runtime.Serialization.Formatters.Binary.WriteObjectInfo.Serialize(Object obj, ISurrogateSelector surrogateSelector, StreamingContext context, SerObjectInfoInit serObjectInfoInit, IFormatterConverter converter, ObjectWriter objectWriter) at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Write(WriteObjectInfo objectInfo, NameInfo memberNameInfo, NameInfo typeNameInfo) at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object graph, Header[] inHeaders, __BinaryWriter serWriter, Boolean fCheck) at System.Runtime.Serialization.Fo...

Unexpected ...rmatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph, Header[] headers, Boolean fCheck) at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream serializationStream, Object graph) at System.Workflow.ComponentModel.Activity.Save(Stream stream, IFormatter formatter) at System.Workflow.ComponentModel.Activity.Save(Stream stream) at System.Workflow.Runtime.Hosting.WorkflowPersistenceService.GetDefaultSerializedForm(Activity activity) at Microsoft.SharePoint.Workflow.SPWinOePersistenceService.SaveWorkflowInstanceState(Activity instanceState, Boolean unlock) at System.Workflow.Runtime.WorkflowExecutor.Persist(Activity dynamicActivity, Boolean unlock, Boolean needsCompensation) --- End of inner exception stack tra...

 

Unexpected ...ce --- at System.Workflow.Runtime.WorkflowExecutor.Persist(Activity dynamicActivity, Boolean unlock, Boolean needsCompensation) at System.Workflow.Runtime.WorkflowExecutor.ProtectedPersist(Boolean unlock)

 

 

 

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 11 Okt. 2010 11:10
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Chris 22"]Nun habe ich den problematischen Code in eine separate Klasse ausgelagert, welche mit [Serializable] vermerkt ist und und alle Klassenvariablen auf public gesetzt[/quote]

Ganz so einfach geht das nicht. Alle derartigen Variablen müssen selbst von einem serialisierbaren Typ sein. Du hast mindestens eine Variable vom Typ SPSite, bei der das nicht so ist.

EDIT: wenn Du unbedingt eine SPSite persistieren mußt, dann nur die ID (= GUID = serialisierbar). Daraus kannst Du dann die Site später wiederherstellen.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 11 Okt. 2010 11:39
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 

Die zu serialisierenden Klassen besitzen nicht serialisierbare Variablen, das stimmt. Hatte mit dieser Problematik noch keinen Kontakt. Im Moment soll bei mir die komplette Klasse serialisiert werden.

Ich habe deine Antwort nicht ganz verstanden. Gemeint war, dass in der einzubindenden Klasse Variablen separat serialisiert werden müssen?

 

Meine Klassen:

 

public sealed partial class Workflow1 : StateMachineWorkflowActivity

{

public WFMembers wfm = null;

 

private void initCreateLib_ExecuteCode(object sender, EventArgs e)

{

wfm = new WFMembers(workflowProperties.Site, workflowProperties.Web,

workflowProperties.ListId, workflowProperties.ItemId);

 

wfm.initCreateLibrary();

}

}

 

[Serializable]

public class WFMembers

{

public SPSite _WFCurrentSite = null;

public SPWeb _WFCurrentWeb = null;

public SPList _WFListAufgaben = null;

public string _WFPageName = string.Empty;

public SPListItem _WFListItem = null;

 

public ProjectLibraries plib = null;

 

...

}

 

[Serializable]

public class ProjectLibraries

{

public void createLibrary(SPSite spSite, SPWeb spWeb, string phase, string listName)

{

string ctPhase1 = "...";

string ctPhase2 = "...";

string ctPhase3 = "...";

 

SPList lib1 = null;

SPList lib2 = null;

SPList lib3 = null;

 

//usw.

}

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 11 Okt. 2010 12:10
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Wenn eine Klasse mit [Serializable] markiert wird, dann müssen alle public-Felder serialisierbar sein. Das sind i.d.R. nur die Standardtypen wie int und string, aber nicht SPSite, SPWeb usw.

Wenn Du solche Daten in einer serialisierbaren Klasse zwischenspeichern möchtest, dann mußt Du auf z.B. deren IDs zurückgriefen.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
929 Beiträge
Thomas Östreich Als Antwort am 11 Okt. 2010 13:10
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Andi Fandrich"]

Wenn eine Klasse mit [Serializable] markiert wird, dann müssen alle public-Felder serialisierbar sein. Das sind i.d.R. nur die Standardtypen wie int und string, aber nicht SPSite, SPWeb usw.

[/quote]

Nicht ganz korrekt ;)  (Ist nicht XmlSerialization da dort auch kein Serializable benötigt wird) private, protected zählen auch dazu es sei den diese habe das NonSerializedAttribute. http://msdn.microsoft.com/de-de/library/system.serializableattribute(VS.80).aspx

Sonst aber so wie Andi sagt einfach nur die ID's zum serializieren speichern.

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 11 Okt. 2010 13:53
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Danke für die Korrektur - selbst ich tippe manchmal einfach nur schnell was runter :-)

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 12 Okt. 2010 09:50
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 

Dank der guten Tips konnte ich nun alles so umbauen, dass nur noch ID's verwendet werden. Die Serialisierung habe ich in einer Konsolenanwendung getestet und sie funktioniert, in dem Workflow jedoch nicht. Hier bekomme ich einen "Access to the path 'C:\\... is denied." - Fehler bei der Zeile:

Stream stream = File.Open("data.xml", FileMode.Create);

Gibt es hierfür eine einfache und elegante Lösung?

Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 12 Okt. 2010 09:53
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Dank der guten Tips konnte ich nun alles so umbauen, dass nur noch ID's verwendet werden. Die Serialisierung habe ich in einer Konsolenanwendung getestet und sie funktioniert, in dem Workflow jedoch nicht. Hier bekomme ich einen "Access to the path 'C:\\... is denied." - Fehler bei der Zeile:

Stream stream = File.Open("data.xml", FileMode.Create);

Gibt es hierfür eine einfache und elegante Lösung?

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 12 Okt. 2010 10:31
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Auf das Dateisystem hast Du keinen Zugriff. Es bringt auch nichts wenn man an eine Farm mit mehr als einem Server denkt - auf welchem Server liegt jetzt die Datei?

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 12 Okt. 2010 14:22
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 

Ich arbeite in einer Testumgebung. SharePoint ist hier einfach auf einem Windows Server 2003 Betriebssystem installiert. Du meinst die "data.xml"? Sie kann nicht erzeugt werden, sollte aber auf dem Windows Server Betriebssystem liegen, es wäre aber erstmal egal wo ist abgelegt wird.

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 12 Okt. 2010 14:25
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Wie gesagt, an das Dateisystem kommst Du nicht ran. Du wirst Dir einen anderen Speicherort suchen müssen. SharePoint bietet genügend Möglichkeiten.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 12 Okt. 2010 16:52
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Bin halt echt noch ganz am Anfang mit SharePoint... Sorry, meinst du jetzt in eine Liste oder in eine Datenbank?    

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 12 Okt. 2010 17:02
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

[quote user="Chris 22"]Bin halt echt noch ganz am Anfang mit SharePoint...[/quote]

Kein Problem, das waren wir alle mal :-)

[quote user="Chris 22"]meinst du jetzt in eine Liste oder in eine Datenbank?[/quote]

Im Prinzip kannst Du Dir das aussuchen. Was eben am Besten paßt. Man kann etwas in (versteckten) Listen speichern. Oder in einer XML-Datei und die wiederum in einer Bibliothek. Oder in den Properties des Web-Objekts (SPWeb.Properties). Oder in den Properties eines Ordners (SPFolder.Properties). Oder in einer eigenen Datenbank. Oder... Nur eben nicht im Dateisystem.

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 15 Okt. 2010 16:08
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 

Die Serialisierung ist wohl nicht gerade meine Stärke. :) Nach mehreren Ausprobieren habe ich leider immer noch keine funktionierende Lösung gefunden.

 

  • Die Datei in einer SharePoint Bibliothek abgelegt über MemoryStream()/StreamWriter(stream) funktioniert.

  • Das Einlesen funktioniert nicht über einen SharePoint-Pfad, folgende Fehlermeldung wird geworfen: ''URI formats are not supported.''

 

Code zum Einlesen:

string docpath = @"http://server/Page/Library/Test.xml";

string string = null;

using (StreamReader streamReader = new StreamReader(File.Open(docpath, FileMode.Open)))

{

       string = streamReader.ReadToEnd();

} ...


 

Offenbar ergibt sich hier die Lösung über HTTPContext:

using (StreamReader streamReader = new StreamReader (File.Open (

HttpContext.Current.Server.MapPath (@"~_ Layouts \ theXSL.xslt "), FileMode.Open)))

 

Gibt es hierfür eine Alternative, d.h. eine Lösung ohne HTTPContext? (HTTPContext in meinem WF nicht vorhanden)

Danke im Voraus!

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 15 Okt. 2010 16:26
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Gehe einfach über das SharePoint-Objektmodell:

SPWeb web = SPContext.Current.Web;
SPFile file = web.GetFile("/library/filename.ext");

An den Inhalt kommst Du jetzt ganz einfach über die Methoden von SPFile (OpenBinary*).

Viele Grüße
Andi
af @ evocom de
Blog
Ohne Rang
37 Beiträge
Chris 22 Als Antwort am 18 Okt. 2010 10:31
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

 

Erstmal einen herzlichen Dank für den zuverlässigen Service! :)

Das ganze funktioniert soweit in einer Konsolenapplication. Ich hatte mich doch für den XmlSerializer entschieden. Den XML-Code verwende ich als String in einem SPFile-Objekt, welches gelesen und überschrieben wird. Die Datei wird dabei in SharePoint abgelegt.

Nun muss ich das ganze in den Workflow einbauen. Leider sind das jetzt wieder einige Instanzen die in dem WF liegen müssen (XmlSerializer, SPSite, SPWeb, Stream-Instanzen). Muss hier irgendetwas beachtet werden oder kann ich Funktionen sowie genannte Instanzen wie gewohnt verwenden.?

Hoffe, mich erwartet jetzt nicht noch so eine Überraschung, welche mich ein paar Tage kostet...

Ohne Rang
19231 Beiträge
Andi Fandrich Als Antwort am 18 Okt. 2010 12:10
SchlechtSchlechtIn OrdnungIn OrdnungDurchschnittDurchschnittGutGutSehr gutSehr gut

Außer den üblichen Regeln gibt es da nichts besonderes zu beachten (alles wieder sauber aufräumen Stream.Close() etc.).

Viele Grüße
Andi
af @ evocom de
Blog