Microsoft.Synchronization code crashing in Unity but works in Visual C# - c#

So i modified a sample code from here https://code.msdn.microsoft.com/windowsdesktop/File-Synchronization-516e3ad7 a little to fit my needs. This is a console application that takes in 2 arguments, first is the source, second is destination. It's a one way sync source to destination folders.
// <copyright file="SyncMain.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// <summary>Sample code for using the MSF File Sync Provider</summary>
using System;
using System.IO;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
public class FileSyncProviderSample
{
public static void Main(string[] args)
{
if (args.Length < 2 ||
string.IsNullOrEmpty(args[0]) || string.IsNullOrEmpty(args[1]) ||
!Directory.Exists(args[0]) || !Directory.Exists(args[1]))
{
Console.WriteLine(
"Usage: FileSyncSample [valid directory path 1] [valid directory path 2]");
return;
}
string replica1RootPath = args[0];
string replica2RootPath = args[1];
try
{
// Set options for the sync operation
FileSyncOptions options =
FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles |
FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk"); // Exclude all *.lnk files
// Explicitly detect changes on both replicas upfront, to avoid two change
// detection passes for the two-way sync
DetectChangesOnFileSystemReplica(
replica1RootPath, filter, options);
DetectChangesOnFileSystemReplica(
replica2RootPath, filter, options);
// Sync in both directions
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, null, options);
//SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, null, options);
}
catch (Exception e)
{
Console.WriteLine("\nException from File Sync Provider:\n" + e.ToString());
}
}
public static void DetectChangesOnFileSystemReplica(
string replicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider provider = null;
try
{
provider = new FileSyncProvider(replicaRootPath, filter, options);
provider.DetectChanges();
}
finally
{
// Release resources
if (provider != null)
provider.Dispose();
}
}
public static void SyncFileSystemReplicasOneWay(
string sourceReplicaRootPath, string destinationReplicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider destinationProvider = null;
try
{
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
destinationProvider.AppliedChange +=
new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload; // Sync source to destination
Console.WriteLine("Synchronizing changes to replica: " +
destinationProvider.RootDirectoryPath);
agent.Synchronize();
}
finally
{
// Release resources
if (sourceProvider != null) sourceProvider.Dispose();
if (destinationProvider != null) destinationProvider.Dispose();
}
}
public static void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
switch(args.ChangeType)
{
case ChangeType.Create:
Console.WriteLine("-- Applied CREATE for file " + args.NewFilePath);
break;
case ChangeType.Delete:
Console.WriteLine("-- Applied DELETE for file " + args.OldFilePath);
break;
case ChangeType.Update:
Console.WriteLine("-- Applied OVERWRITE for file " + args.OldFilePath);
break;
case ChangeType.Rename:
Console.WriteLine("-- Applied RENAME for file " + args.OldFilePath +
" as " + args.NewFilePath);
break;
}
}
public static void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
Console.WriteLine("-- Skipped applying " + args.ChangeType.ToString().ToUpper()
+ " for " + (!string.IsNullOrEmpty(args.CurrentFilePath) ?
args.CurrentFilePath : args.NewFilePath) + " due to error");
if (args.Exception != null)
Console.WriteLine(" [" + args.Exception.Message + "]");
}
}
It works just as expected, but when i modified the code and uses it in Unity, it crashes in editor playmode and does nothing when running the build. The crash seems to originate from agent.Synchronize();
Script in Unity
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Microsoft.Synchronization;
using Microsoft.Synchronization.Files;
using System;
using System.IO;
public class FileSyncTest : MonoBehaviour
{
[SerializeField] private string replica1RootPath;
[SerializeField] private string replica2RootPath;
[SerializeField] private KeyCode activateSyncKey = KeyCode.Keypad5;
private void Update()
{
if (Input.GetKeyDown(activateSyncKey))
{
if (Directory.Exists(replica1RootPath) || Directory.Exists(replica2RootPath))
{
try
{
// Set options for the sync operation
FileSyncOptions options =
FileSyncOptions.ExplicitDetectChanges |
FileSyncOptions.RecycleDeletedFiles |
FileSyncOptions.RecyclePreviousFileOnUpdates |
FileSyncOptions.RecycleConflictLoserFiles;
FileSyncScopeFilter filter = new FileSyncScopeFilter();
filter.FileNameExcludes.Add("*.lnk"); // Exclude all *.lnk files
// Explicitly detect changes on both replicas upfront, to avoid two change
// detection passes for the two-way sync
DetectChangesOnFileSystemReplica(
replica1RootPath, filter, options);
DetectChangesOnFileSystemReplica(
replica2RootPath, filter, options);
// Sync in both directions
SyncFileSystemReplicasOneWay(replica1RootPath, replica2RootPath, null, options);
//SyncFileSystemReplicasOneWay(replica2RootPath, replica1RootPath, null, options);
}
catch (Exception e)
{
Debug.Log("\nException from File Sync Provider:\n" + e.ToString());
}
}
else
{
Debug.Log("One of the dir doesn't exist");
}
}
}
public void DetectChangesOnFileSystemReplica(
string replicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider provider = null;
try
{
provider = new FileSyncProvider(replicaRootPath, filter, options);
provider.DetectChanges();
}
finally
{
// Release resources
if (provider != null)
provider.Dispose();
}
}
private void SyncFileSystemReplicasOneWay(
string sourceReplicaRootPath, string destinationReplicaRootPath,
FileSyncScopeFilter filter, FileSyncOptions options)
{
FileSyncProvider sourceProvider = null;
FileSyncProvider destinationProvider = null;
try
{
sourceProvider = new FileSyncProvider(
sourceReplicaRootPath, filter, options);
destinationProvider = new FileSyncProvider(
destinationReplicaRootPath, filter, options);
destinationProvider.AppliedChange +=
new EventHandler<AppliedChangeEventArgs>(OnAppliedChange);
destinationProvider.SkippedChange +=
new EventHandler<SkippedChangeEventArgs>(OnSkippedChange);
SyncOrchestrator agent = new SyncOrchestrator();
agent.LocalProvider = sourceProvider;
agent.RemoteProvider = destinationProvider;
agent.Direction = SyncDirectionOrder.Upload; // Sync source to destination
Debug.Log("Synchronizing changes to replica: " +
destinationProvider.RootDirectoryPath);
agent.Synchronize();
}
finally
{
// Release resources
if (sourceProvider != null) sourceProvider.Dispose();
if (destinationProvider != null) destinationProvider.Dispose();
}
}
private void OnAppliedChange(object sender, AppliedChangeEventArgs args)
{
switch (args.ChangeType)
{
case ChangeType.Create:
Debug.Log("-- Applied CREATE for file " + args.NewFilePath);
break;
case ChangeType.Delete:
Debug.Log("-- Applied DELETE for file " + args.OldFilePath);
break;
case ChangeType.Update:
Debug.Log("-- Applied OVERWRITE for file " + args.OldFilePath);
break;
case ChangeType.Rename:
Debug.Log("-- Applied RENAME for file " + args.OldFilePath +
" as " + args.NewFilePath);
break;
}
}
private void OnSkippedChange(object sender, SkippedChangeEventArgs args)
{
Debug.Log("-- Skipped applying " + args.ChangeType.ToString().ToUpper()
+ " for " + (!string.IsNullOrEmpty(args.CurrentFilePath) ?
args.CurrentFilePath : args.NewFilePath) + " due to error");
if (args.Exception != null)
Debug.Log(" [" + args.Exception.Message + "]");
}
}
I have copied the required DLLs into the project folders, below are the DLLs i copied.
FeedSync.21.dll
FileSyncProvider21.dll
MetaStore21.dll
Microsoft.Synchronization.dll
Microsoft.Synchronization.Files.dll
Microsoft.Synchronization.MetadataStorage.dll
Microsoft.Synchronization.SimpleProviders.dll
Msfdb.dll
Msfdbqp.dll
Msfdbse.dll
-SimpleProviders21.dll
-Synchronization21.dll
Editor.log
- https://pastebin.com/3MnNFY4z
Any help will be appreciated!

Related

Multithreaded Selenium Bot does not work correctly

I wrote a bot in C#, I used Selenium.
Problem: When I start more threads at same time, the bot does the work in the first window. All of the e-mail addresses are being added to the "E-mail" textbox in the same window instead of one e-mail address per window.
But it should look like:
Start function: DivisionStart()
private void DivisionStart() {
foreach(var account in BotConfig.AccountList) {
while (CurrentBotThreads >= BotConfig.MaxLoginsAtSameTime) {
Thread.Sleep(1000);
}
StartedBotThreads++;
CurrentBotThreads++;
int startIndex = (StartedBotThreads * BotConfig.AdsPerAccount + 1) - BotConfig.AdsPerAccount - 1;
int stopIndex = BotConfig.AdsPerAccount * CurrentBotThreads;
if (stopIndex > BotConfig.ProductList.Count) {
stopIndex = BotConfig.ProductList.Count;
}
Debug.Print("Thread: " + StartedBotThreads);
var adList = GetAdListBy(startIndex, stopIndex);
foreach(var ad in adList) {
Debug.Print("Für thread: " + StartedBotThreads + " | Anzeige: " + ad.AdTitle);
}
Debug.Print("Parallel");
var ebayBotThread = new Thread(() => {
var botOptions = new IBotOptionsModel() {
CaptchaSolverApiKey = CaptchaSolverApiKey,
ReCaptchaSiteKey = "6LcZlE0UAAAAAFQKM6e6WA2XynMyr6WFd5z1l1Nr",
StartPageUrl = "https://www.ebay-kleinanzeigen.de/m-einloggen.html?targetUrl=/",
EbayLoginEmail = account.AccountEmail,
EbayLoginPassword = account.AccountPassword,
Ads = adList,
};
var ebayBot = new EbayBot(this, botOptions);
ebayBot.Start(StartedBotThreads);
Thread.Sleep(5000);
});
ebayBotThread.Start();
}
}
The class with function which will be executed in each thread:
using OpenQA.Selenium;
using Selenium.WebDriver.UndetectedChromeDriver;
using System.Diagnostics;
using TwoCaptcha.Captcha;
using System.Drawing;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chrome.ChromeDriverExtensions;
namespace EbayBot
{
class EbayBot
{
public Selenium.Extensions.SlDriver Driver;
private WebDriverHelper DriverHelper;
private Bot Sender;
private bool CaptchaSolved = false;
public IBotOptionsModel Options;
public EbayBot(Bot sender, IBotOptionsModel options)
{
Sender = sender;
Options = options;
}
public void Start(int threadIndex)
{
var chromeOptions = new ChromeOptions();
/*if (Sender.BotConfig.EnableProxy)
{
chromeOptions.AddHttpProxy(
Options.Proxy.IpAddress,
Options.Proxy.Port,
Options.Proxy.Username,
Options.Proxy.Password
);
}*/
Driver = UndetectedChromeDriver.Instance(null, chromeOptions);
DriverHelper = new WebDriverHelper(Driver);
string status = "";
Debug.Print("Bot-Thread: " + threadIndex);
Driver.Url = Options.StartPageUrl + Options.EbayLoginEmail;
PressAcceptCookiesButton();
Login();
if (!CaptchaSolved) return;
Driver.Wait(3);
if (LoginError() || !IsLoggedIn())
{
status = "Login für '" + Options.EbayLoginEmail + "' fehlgeschlagen!";
Debug.Print(status);
Sender.ProcessStatus = new IStatusModel(status, Color.Red);
return;
}
else
{
status = "Login für '" + Options.EbayLoginEmail + "' war erfolgreich!";
Debug.Print(status);
Sender.ProcessStatus = new IStatusModel(status, Color.Green);
}
Driver.Wait(5);
BeginFillFormular();
}
private bool CookiesAccepted()
{
try
{
var btnAcceptCookies = Driver.FindElement(By.Id(Config.PageElements["id_banner"]));
return btnAcceptCookies == null;
}
catch (Exception)
{
return true;
}
}
private void PressAcceptCookiesButton()
{
DriverHelper.WaitForElement(Config.PageElements["id_banner"], "", 10);
if (CookiesAccepted()) return;
var btnAcceptCookies = Driver.FindElement(By.Id(Config.PageElements["id_banner"]));
btnAcceptCookies.Click();
}
private bool IsLoggedIn()
{
Debug.Print("Check if logged in already");
try
{
var userEmail = Driver.FindElement(By.Id("user-email")).Text;
return userEmail.ToLower().Contains(Options.EbayLoginEmail);
}
catch (Exception)
{
return false;
}
}
private bool LoginError()
{
try
{
var loginErrorH1 = Driver.FindElements(By.TagName("h1"));
return loginErrorH1[0].Text.Contains("ungültig");
}
catch (Exception)
{
return false;
}
}
private void Login()
{
if (IsLoggedIn()) return;
string status = "Anmelden bei " + Options.EbayLoginEmail + "...";
Debug.Print(status);
Sender.ProcessStatus = Sender.ProcessStatus = new IStatusModel(status, Color.DimGray);
Driver.Wait(5);
var fieldEmail = Driver.FindElement(By.Id(Config.PageElements["id_login_email"]));
var fieldPassword = Driver.FindElement(By.Id(Config.PageElements["id_login_password"]));
var btnLoginSubmit = Driver.FindElement(By.Id(Config.PageElements["id_login_button"]));
fieldEmail.SendKeys(Options.EbayLoginEmail);
Driver.Wait(4);
fieldPassword.SendKeys(Options.EbayLoginPassword);
SolveCaptcha();
if (!CaptchaSolved)
{
return;
}
Debug.Print("Clicking login button");
btnLoginSubmit.Click();
}
public void BeginFillFormular()
{
Debug.Print("Formular setup, Inserate: " + Options.Ads.Count);
foreach (var adData in Options.Ads)
{
Debug.Print("Setting up formular for " + adData.AdTitle);
var adFormular = new AdFormular(Driver, adData, Options);
adFormular._EbayBot = this;
adFormular.CreateAd(Sender);
// 10 seconds
Debug.Print("Nächstes Insert für " + adData.AdTitle);
}
}
public string GetSolvedCaptchaAnswer(string captchaUrl = "")
{
string code = string.Empty;
var solver = new TwoCaptcha.TwoCaptcha(Options.CaptchaSolverApiKey);
var captcha = new ReCaptcha();
captcha.SetSiteKey(Options.ReCaptchaSiteKey);
captcha.SetUrl(captchaUrl == "" ? Options.StartPageUrl : captchaUrl);
try
{
solver.Solve(captcha).Wait();
code = captcha.Code;
}
catch (AggregateException e)
{
Sender.ProcessStatus = new IStatusModel("Captcha Api-Fehler: " + e.InnerExceptions.First().Message, Color.Red);
Driver.Wait(10);
}
return code;
}
public void SolveCaptcha(string captchaUrl = "")
{
Debug.Print("Solving captcha...");
var solvedCaptchaAnswer = GetSolvedCaptchaAnswer(captchaUrl);
if (solvedCaptchaAnswer == string.Empty)
{
Debug.Print("Captcha konnte nicht gelöst werden");
Sender.ProcessStatus = new IStatusModel("Captcha konnte nicht gelöst werden", Color.Red);
CaptchaSolved = false;
Driver.Wait(10);
return;
}
CaptchaSolved = true;
Debug.Print("Captcha answer: " + solvedCaptchaAnswer);
Driver.ExecuteScript("document.getElementById('g-recaptcha-response').innerHTML = '" + solvedCaptchaAnswer + "'");
Debug.Print("Captcha solved!");
Driver.Wait(2);
}
}
}
If I remove the Thread.Sleep(5000); in the DivisionStart function it will work, but I need it I actually want to wait for a found proxy but I simulated it with Thread.Sleep
How can I solve my problem?
Thanks for any answer!
I fixed it.
I used UndetectedChromeDriver wich does not use different ports.
I use another Undetected driver now.
Thank you all

Extent reports 4.0.3 - capture screenshot not working - c#, specflow

I am trying to add screenshot capture to extent report. I am able to capture screenshot using selenium webdriver but attaching screenshot to extent report is not working.
Code in [AfterStep] hook will actually generate step for failure in report. I have not included the code for pass step.
step.AddScreenCaptureFromPath(screenshotPath)
code runs successfully but the cannot find the attachment in report.
This is Hooks code trying to generate report for BDD feature.
//Global Variable for Extend report
private static ExtentTest featureName;
private static ExtentTest scenario;
private static ExtentTest step;
private static ExtentReports extent;
//Initialize extent reports
[BeforeTestRun]
public static void InitializeReport()
{
//initialize extent report before test starts
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
var htmlReporter = new ExtentHtmlReporter(assemblyFolder + "\\Reports\\ExtentReport.html");
htmlReporter.Config.Theme = AventStack.ExtentReports.Reporter.Configuration.Theme.Dark;
//Attach report to reporter
extent = new ExtentReports();
extent.AttachReporter(htmlReporter);
}
//generate feature name dynamically
[BeforeFeature]
public static void BeforeFeature()
{
//Create dynamic feature name
featureName = extent.CreateTest<Feature>(FeatureContext.Current.FeatureInfo.Title);
}
//generate scenario name dynamically
[BeforeScenario]
public void Initialize()
{
//Create dynamic scenario name
scenario = featureName.CreateNode<Scenario>(ScenarioContext.Current.ScenarioInfo.Title);
}
//get the screenshot upon failure
[AfterStep]
public void InsertReportingSteps()
{
var stepType = ScenarioStepContext.Current.StepInfo.StepDefinitionType.ToString();
PropertyInfo pInfo = typeof(ScenarioContext).GetProperty("ScenarioExecutionStatus", BindingFlags.Instance | BindingFlags.Public);
MethodInfo getter = pInfo.GetGetMethod(nonPublic: true);
object TestResult = getter.Invoke(ScenarioContext.Current, null);
if (ScenarioContext.Current.TestError != null)
{
if (stepType == "Given"){
step = scenario.CreateNode<Given>(stepType + " " + ScenarioStepContext.Current.StepInfo.Text).Fail(ScenarioContext.Current.TestError.Message);
}
else if (stepType == "When"){
step = scenario.CreateNode<When>(stepType + " " + ScenarioStepContext.Current.StepInfo.Text).Fail(ScenarioContext.Current.TestError.Message);
}
else if (stepType == "Then"){
step = scenario.CreateNode<Then>(stepType + " " + ScenarioStepContext.Current.StepInfo.Text).Fail(ScenarioContext.Current.TestError.Message);
}
string screenshotPath = CaptureScreenshot.Capture(driver);
//Capture screenshot not attaching screenshot to extent reports
step.AddScreenCaptureFromPath(screenshotPath);
}
}
//flush extent reports
[AfterTestRun]
public static void TearDownReport()
{
//Flush report once test completes
extent.Flush();
}
class CaptureScreenshot
{
public static string Capture(IWebDriver driver)
{
ITakesScreenshot ts = (ITakesScreenshot)driver;
Screenshot screenshot = ts.GetScreenshot();
string screenShotName = "screenShotName_" + Calendar.getCurrentDate();
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string finalpth = assemblyFolder + "\\Reports\\Screenshots\\";
string screenshotDir = finalpth + screenShotName + ".png";
string localpath = new Uri(screenshotDir).LocalPath;
screenshot.SaveAsFile(localpath);
return localpath;
}
}
I was able to resolve the issue by using MediaEntityBuilder
https://extentreports.com/docs/versions/4/java/
MediaModelProvider mediaModel =
MediaEntityBuilder.createScreenCaptureFromPath("screenshot.png").build();
test.fail("details", mediaModel);
// or:
test.fail("details",
MediaEntityBuilder.createScreenCaptureFromPath("screenshot.png").build());
You'll need to include the screenshot in your step
step = scenario.CreateNode<Then>(stepType + " " + ScenarioStepContext.Current.StepInfo.Text).Fail(ScenarioContext.Current.TestError.Message,MediaEntityBuilder.CreateScreenCaptureFromPath(screenshotPath).Build());

Cortana Background task crashes on mobile but works perfectly on desktop

Been looking at this for the past few days now and I'm no closer to a solution. The code below is based on the CortanaVoiceCommand sample at https://github.com/Microsoft/Windows-universal-samples/tree/master/Samples/CortanaVoiceCommand and the code works perfectly on desktop but the background task is crashing on mobile each time.
In OnTaskCanceled the BackgroundTaskCancellationReason always reports as SystemPolicy but I'm no closer to finding a solution.
Appreciate any help anyone can suggest.
using System;
using System.Collections;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using Windows.ApplicationModel.AppService;
using Windows.ApplicationModel.Background;
using Windows.ApplicationModel.VoiceCommands;
namespace TramTimesVoice
{
public sealed class VoiceCommandService : IBackgroundTask
{
private BackgroundTaskDeferral backgroundTaskDeferral;
private IEnumerable services;
private Service service;
private Stop stop;
private VoiceCommandServiceConnection voiceCommandServiceConnection;
public async void Run(IBackgroundTaskInstance taskInstance)
{
backgroundTaskDeferral = taskInstance.GetDeferral();
taskInstance.Canceled += OnTaskCanceled;
AppServiceTriggerDetails triggerDetails = taskInstance.TriggerDetails as AppServiceTriggerDetails;
if (triggerDetails != null && triggerDetails.Name == "VoiceCommandService")
{
try
{
voiceCommandServiceConnection = VoiceCommandServiceConnection.FromAppServiceTriggerDetails(triggerDetails);
voiceCommandServiceConnection.VoiceCommandCompleted += OnVoiceCommandCompleted;
VoiceCommand voiceCommand = await voiceCommandServiceConnection.GetVoiceCommandAsync();
if (voiceCommand.CommandName == "getServices")
{
await SendCompletionMessageForServices(voiceCommand.Properties["stop"][0]);
}
else
{
LaunchAppInForeground();
}
}
catch (Exception ex)
{
throw new Exception("Handling Voice Command Failed: " + ex.ToString());
}
}
}
private async void LaunchAppInForeground()
{
VoiceCommandUserMessage userMessage = new VoiceCommandUserMessage();
userMessage.SpokenMessage = "Launching Tram Times";
VoiceCommandResponse response = VoiceCommandResponse.CreateResponse(userMessage);
response.AppLaunchArgument = "";
await voiceCommandServiceConnection.RequestAppLaunchAsync(response);
}
private void OnTaskCanceled(IBackgroundTaskInstance sender, BackgroundTaskCancellationReason reason)
{
if (backgroundTaskDeferral != null)
{
backgroundTaskDeferral.Complete();
}
}
private void OnVoiceCommandCompleted(VoiceCommandServiceConnection sender, VoiceCommandCompletedEventArgs args)
{
if (backgroundTaskDeferral != null)
{
backgroundTaskDeferral.Complete();
}
}
private async Task SendCompletionMessageForServices(String input)
{
await ShowProgressScreen("Working On It");
IEnumerable stops = new Stops().Get();
foreach (Stop item in stops)
{
if (input == item.Voice)
{
stop = new Stop()
{
Code = item.Code,
Name = item.Name,
Latitude = item.Latitude,
Longitude = item.Longitude,
ApiCodes = item.ApiCodes,
City = item.City,
Lines = item.Lines,
Voice = item.Voice
};
break;
}
}
if (stop.City == "Blackpool")
{
services = await new Blackpool().Get(stop.ApiCodes);
}
else if (stop.City == "Edinburgh")
{
services = await new Edinburgh().Get(stop.ApiCodes);
}
else if (stop.City == "London")
{
services = await new London().Get(stop.ApiCodes);
}
else if (stop.City == "Manchester")
{
services = await new Manchester().Get(stop.ApiCodes);
}
else if (stop.City == "Midland")
{
services = await new Midland().Get(stop.ApiCodes);
}
else if (stop.City == "Nottingham")
{
services = await new Nottingham().Get(stop.ApiCodes);
}
else if (stop.City == "Sheffield")
{
services = await new Sheffield().Get(stop.ApiCodes);
}
ObservableCollection<Service> data = new ObservableCollection<Service>();
foreach (Service item in services)
{
if (item.DestinationScheduled != null)
{
service = new Service()
{
Destination = item.Destination,
DestinationRealtime = item.DestinationRealtime,
DestinationRealtimeFull = item.DestinationRealtimeFull,
DestinationScheduled = item.DestinationScheduled,
DestinationScheduledFull = item.DestinationScheduledFull
};
data.Add(service);
}
else
{
service = new Service()
{
Destination = item.Destination,
DestinationRealtime = item.DestinationRealtime,
DestinationRealtimeFull = item.DestinationRealtimeFull,
DestinationScheduled = item.DestinationRealtime,
DestinationScheduledFull = item.DestinationRealtimeFull
};
data.Add(service);
}
}
data = new ObservableCollection<Service>(data.OrderBy(service => service.DestinationScheduledFull).ThenBy(service => service.Destination));
VoiceCommandUserMessage userMessage = new VoiceCommandUserMessage();
userMessage.DisplayMessage = "I Found These Services";
userMessage.SpokenMessage = "I found these services from " + stop.Voice + ". ";
Collection<VoiceCommandContentTile> tiles = new Collection<VoiceCommandContentTile>();
VoiceCommandContentTile tile = new VoiceCommandContentTile();
tile.AppLaunchArgument = stop.Name;
tile.ContentTileType = VoiceCommandContentTileType.TitleWithText;
tile.Title = stop.Name;
if (data.Count > 0)
{
if (data[0].DestinationRealtime != null)
{
tile.TextLine1 = data[0].DestinationRealtime + " " + data[0].Destination;
userMessage.SpokenMessage += data[0].DestinationRealtime + " to " + data[0].Destination + ". ";
}
else
{
tile.TextLine1 = data[0].DestinationScheduled + " " + data[0].Destination;
userMessage.SpokenMessage += data[0].DestinationScheduled + " to " + data[0].Destination + ". ";
}
}
if (data.Count > 1)
{
if (data[1].DestinationRealtime != null)
{
tile.TextLine2 = data[1].DestinationRealtime + " " + data[1].Destination;
userMessage.SpokenMessage += data[1].DestinationRealtime + " to " + data[1].Destination + ". ";
}
else
{
tile.TextLine2 = data[1].DestinationScheduled + " " + data[1].Destination;
userMessage.SpokenMessage += data[1].DestinationScheduled + " to " + data[1].Destination + ". ";
}
}
if (data.Count > 2)
{
if (data[2].DestinationRealtime != null)
{
tile.TextLine3 = data[2].DestinationRealtime + " " + data[2].Destination;
userMessage.SpokenMessage += data[2].DestinationRealtime + " to " + data[2].Destination + ". ";
}
else
{
tile.TextLine3 = data[2].DestinationScheduled + " " + data[2].Destination;
userMessage.SpokenMessage += data[2].DestinationScheduled + " to " + data[2].Destination + ". ";
}
}
tiles.Add(tile);
VoiceCommandResponse response = VoiceCommandResponse.CreateResponse(userMessage, tiles);
response.AppLaunchArgument = "";
await voiceCommandServiceConnection.ReportSuccessAsync(response);
}
private async Task ShowProgressScreen(String message)
{
var userProgressMessage = new VoiceCommandUserMessage();
userProgressMessage.DisplayMessage = message;
userProgressMessage.SpokenMessage = message;
VoiceCommandResponse response = VoiceCommandResponse.CreateResponse(userProgressMessage);
await voiceCommandServiceConnection.ReportProgressAsync(response);
}
}
}

how to use application/x-rtp binding with gstreamer-sharp?

I am wondering how/if it's possible to use the follwing gstreamer bindings using gstreamer-sharp/C# for Windows?
udpsrc port=1234 ! application/x-rtp, payload=127 ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink
I am not sure how to do the "application/x-rtp, payload=127" part and I think that's all I am missing, but I am not 100% sure about this. The videosink I am trying to use is dshowvideosink.
Here is relavent parts of my code so far. The variable videoDisplay is just a WinForms Panel control on my form.
internal enum videosinktype { glimagesink, d3dvideosink, dshowvideosink, directdrawsink}
static Element mVideoConv, mUdpcSrc, mDemux, mAvDecH264, mAVSink;
static Gst.App.AppSink mAppSink;
static System.Threading.Thread mMainGlibThread;
static GLib.MainLoop mMainLoop; // GLib's Main Loop
private const videosinktype mCfgVideosinkType = videosinktype.dshowvideosink;
private ulong mHandle;
private Gst.Video.VideoSink mGlImageSink;
private Gst.Pipeline mCurrentPipeline = null;
private void InitGStreamerPipeline()
{
//Assign Handle to prevent Cross-Threading Access
mHandle = (ulong)videoDisplay.Handle;
//Init Gstreamer
Gst.Application.Init();
GtkSharp.GstreamerSharp.ObjectManager.Initialize();
mMainLoop = new GLib.MainLoop();
mMainGlibThread = new System.Threading.Thread(mMainLoop.Run);
mMainGlibThread.Start();
#region BuildPipeline
switch (mCfgVideosinkType)
{
case videosinktype.glimagesink:
mGlImageSink = (Gst.Video.VideoSink)Gst.ElementFactory.Make("glimagesink", "glimagesink");
break;
case videosinktype.d3dvideosink:
mGlImageSink = (Gst.Video.VideoSink)Gst.ElementFactory.Make("d3dvideosink", "d3dvideosink");
//mGlImageSink = (Gst.Video.VideoSink)Gst.ElementFactory.Make("dshowvideosink", "dshowvideosink");
break;
case videosinktype.dshowvideosink:
mGlImageSink = (Gst.Video.VideoSink)Gst.ElementFactory.Make("dshowvideosink", "dshowvideosink");
break;
case videosinktype.directdrawsink:
mGlImageSink = (Gst.Video.VideoSink)Gst.ElementFactory.Make("directdrawsink", "directdrawsink");
break;
default:
break;
}
//what's the gstreamer-sharp equivalent of:
//application/x-rtp, payload=127
//??
mUdpcSrc = ElementFactory.Make("udpsrc", "sink0");
mUdpcSrc["port"] = 1234;
mDemux = ElementFactory.Make("rtph264depay", "depay0");
mAvDecH264 = ElementFactory.Make("avdec_h264", "avdech2640");
mVideoConv = ElementFactory.Make("videoconvert", "vidconvert0");
mAVSink = ElementFactory.Make("autovideosink", "video_sink");
mCurrentPipeline = new Gst.Pipeline("pipeline");
mCurrentPipeline.Add(mUdpcSrc, mDemux, mAvDecH264, mVideoConv, mAVSink);
if (!mVideoTestSource.Link(mVideoSink))
if (mUdpcSrc.Link(mVideoSink))
{
System.Diagnostics.Debug.WriteLine("Elements could not be linked");
}
#endregion
//subscribe to bus & bussync msgs
Bus bus = mCurrentPipeline.Bus;
bus.AddSignalWatch();
bus.Message += HandleMessage;
Bus bus = mCurrentPipeline.Bus;
bus.EnableSyncMessageEmission();
bus.SyncMessage += new SyncMessageHandler(bus_SyncMessage);
//play the stream
var setStateRet = mCurrentPipeline.SetState(State.Null);
System.Diagnostics.Debug.WriteLine("SetStateNULL returned: " + setStateRet.ToString());
setStateRet = mCurrentPipeline.SetState(State.Ready);
System.Diagnostics.Debug.WriteLine("SetStateReady returned: " + setStateRet.ToString());
setStateRet = mCurrentPipeline.SetState(Gst.State.Playing);
}
/// <summary>
///
/// </summary>
/// <remarks>
/// Indeed the application needs to set its Window identifier at the right time to avoid internal Window creation
/// from the video sink element. To solve this issue a GstMessage is posted on the bus to inform the application
/// that it should set the Window identifier immediately.
///
/// API: http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gst-plugins-base-libs/html/gst-plugins-base-libs-gstvideooverlay.html
/// </remarks>
/// <param name="o"></param>
/// <param name="args"></param>
private void bus_SyncMessage(object o, SyncMessageArgs args)
{
//Convenience function to check if the given message is a "prepare-window-handle" message from a GstVideoOverlay.
System.Diagnostics.Debug.WriteLine("bus_SyncMessage: " + args.Message.Type.ToString());
if (Gst.Video.Global.IsVideoOverlayPrepareWindowHandleMessage(args.Message))
{
Element src = (Gst.Element)args.Message.Src;
#if DEBUG
System.Diagnostics.Debug.WriteLine("Message'prepare-window-handle' received by: " + src.Name + " " + src.ToString());
#endif
if (src != null && (src is Gst.Video.VideoSink | src is Gst.Bin))
{
// Try to set Aspect Ratio
try
{
src["force-aspect-ratio"] = true;
}
catch (PropertyNotFoundException) { }
// Try to set Overlay
try
{
Gst.Video.VideoOverlayAdapter overlay_ = new Gst.Video.VideoOverlayAdapter(src.Handle);
overlay_.WindowHandle = mHandle;
overlay_.HandleEvents(true);
}
catch (Exception ex) { System.Diagnostics.Debug.WriteLine("Exception thrown: " + ex.Message); }
}
}
}
private void HandleMessage (object o, MessageArgs args)
{
var msg = args.Message;
//System.Diagnostics.Debug.WriteLine("HandleMessage received msg of type: {0}", msg.Type);
switch (msg.Type)
{
case MessageType.Error:
//
GLib.GException err;
string debug;
System.Diagnostics.Debug.WriteLine("Error received: " + msg.ToString());
//msg.ParseError (out err, out debug);
//if(debug == null) { debug = "none"; }
//System.Diagnostics.Debug.WriteLine ("Error received from element {0}: {1}", msg.Src, err.Message);
//System.Diagnostics.Debug.WriteLine ("Debugging information: "+ debug);
break;
case MessageType.StreamStatus:
Gst.StreamStatusType status;
Element theOwner;
msg.ParseStreamStatus(out status, out theOwner);
System.Diagnostics.Debug.WriteLine("Case SteamingStatus: status is: " + status + " ; Ownder is: " + theOwner.Name);
break;
case MessageType.StateChanged:
//System.Diagnostics.Debug.WriteLine("Case StateChanged: " + args.Message.ToString());
State oldState, newState, pendingState;
msg.ParseStateChanged(out oldState, out newState, out pendingState);
if (newState == State.Paused)
args.RetVal = false;
System.Diagnostics.Debug.WriteLine("Pipeline state changed from {0} to {1}: ; Pending: {2}", Element.StateGetName(oldState), Element.StateGetName(newState), Element.StateGetName(pendingState));
break;
case MessageType.Element:
System.Diagnostics.Debug.WriteLine("Element message: {0}", args.Message.ToString());
break;
default:
System.Diagnostics.Debug.WriteLine("HandleMessage received msg of type: {0}", msg.Type);
break;
}
args.RetVal = true;
}
application/x-rtp, payload=127 is just the GstCaps for the udpsrc element. You can listen on the pad-added signal and add the caps once a pad is created.
new Caps("application/x-rtp, payload=(int)127");

ProcessEvent not called in TFS plugin

Recently i have decided to create a plugin for the TFS for tracking work item changes based on ISubscriber interface.
So the workflow would be the following:
1) Work item state changes
2) Plugin catches the WorkItemChangedEvent
3) Send an email to the person specified in the Requester
As the base for my project, i used the following project from CodePlex - The Mail Alert
After i adopted it to my needs and saved compiled binaries in %TFS-DIR%\Microsoft Team Foundation Server 14.0\Application Tier\Web Services\bin\Plugins the TFS restarted the tier and... that's it. On work item change the ProcessEvent method is not called, but it should be.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Common;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Framework.Server;
using Microsoft.TeamFoundation.VersionControl.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Client;
using Microsoft.TeamFoundation.WorkItemTracking.Server;
using System.Diagnostics;
using System.Xml.Linq;
using System.Xml;
using System.DirectoryServices;
using System.Net.Mail;
using System.Xml.Xsl;
using System.Configuration;
using System.Reflection;
namespace MailAlert
{
public class WorkItemChangedEventHandler : ISubscriber
{
static string serverPath = "";
static string ExternalURL = "";
static string MailAddressFrom = "";
static string SMTPHost = "";
static string Password = "";
static int Port = 25;
static int index = 0;
static string projectCollectionFolder;
static Uri projectCollectionUri;
static WorkItemStore wiStore;
static WorkItem wItem;
static WorkItemChangedEvent workItemChangedEvent;
static string teamProjectPath = "";
static VersionControlServer versionControlServer;
static TfsTeamProjectCollection projectCollection;
static Dictionary<IdentityDescriptor, TeamFoundationIdentity> m_identities = new Dictionary<IdentityDescriptor, TeamFoundationIdentity>(IdentityDescriptorComparer.Instance);
public Type[] SubscribedTypes()
{
return new Type[1] { typeof(WorkItemChangedEvent) };
}
public WorkItemChangedEventHandler()
{
TeamFoundationApplicationCore.Log("WorkItemChangedEvent Started", index++, EventLogEntryType.Information);
}
public EventNotificationStatus ProcessEvent(TeamFoundationRequestContext requestContext, NotificationType notificationType,
object notificationEventArgs, out int statusCode, out string statusMessage, out ExceptionPropertyCollection properties)
{
TeamFoundationApplicationCore.Log("WorkItemChangedEventHandler: ProcessEvent entered", index++, EventLogEntryType.Information);
statusCode = 0;
properties = null;
statusMessage = String.Empty;
GetTfsServerName();
projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(TfsTeamProjectCollection.GetFullyQualifiedUriForName(serverPath));
try
{
if (notificationType == NotificationType.Notification && notificationEventArgs is WorkItemChangedEvent)
{
workItemChangedEvent = notificationEventArgs as WorkItemChangedEvent;
TeamFoundationApplicationCore.Log("WorkItemChangedEventHandler: WorkItem " + workItemChangedEvent.WorkItemTitle + " was modified", index++, EventLogEntryType.Information);
TeamFoundationApplicationCore.Log("WorkItemChangedEventHandler: serverPath - " + serverPath, index++, EventLogEntryType.Information);
projectCollectionFolder = requestContext.ServiceHost.VirtualDirectory.ToString();
projectCollectionUri = new Uri(serverPath + projectCollectionFolder);
projectCollection = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(projectCollectionUri);
wiStore = projectCollection.GetService<WorkItemStore>();
versionControlServer = projectCollection.GetService<VersionControlServer>();
TeamFoundationApplicationCore.Log("WorkItemChangedEventHandler: Before process workitem", index++, EventLogEntryType.Information);
ProcessWorkItem();
TeamFoundationApplicationCore.Log("WorkItemChangedEventHandler: After process workitem", index++, EventLogEntryType.Information);
}
}
catch (Exception ex)
{
TeamFoundationApplicationCore.Log("WorkItemChangedEventHandler: FUCKING EXCEPTION! =>\n" + ex.Message, index++, EventLogEntryType.Error);
}
return EventNotificationStatus.ActionPermitted;
}
private static void GetTfsServerName()
{
try
{
string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load(assemblyFolder + #"\Settings.xml");
// Declare the xpath for finding objects inside the XML file
XmlNodeList XmlDocNodes = XmlDoc.SelectNodes("/configuration/tfssettings");
XmlNodeList XmlDocExt = XmlDoc.SelectNodes("/configuration/Externaltfssettings");
// Define a new List, to store the objects we pull out of the XML
serverPath = XmlDocNodes[0].InnerText;
ExternalURL = XmlDocExt[0].InnerText;
XmlNodeList XmlDocNodes2 = XmlDoc.SelectNodes("/configuration/appSettings");
foreach (XmlNode mailNode in XmlDocNodes2)
{
foreach (XmlNode varElement in mailNode.ChildNodes)
{
switch (varElement.Attributes["key"].Value)
{
case "MailAddressFrom":
MailAddressFrom = varElement.Attributes["value"].Value;
break;
case "SMTPHost":
SMTPHost = varElement.Attributes["value"].Value;
break;
case "Password":
Password = varElement.Attributes["value"].Value;
break;
case "Port":
Port = Convert.ToInt32(varElement.Attributes["value"].Value);
break;
}
}
}
}
catch (Exception ex)
{
EventLog.WriteEntry("WorkItemChangedEventHandler", ex.Message);
}
}
public string Name
{
get { return "WorkItemChangedEventHandler"; }
}
public SubscriberPriority Priority
{
get { return SubscriberPriority.High; }
}
private static void ProcessWorkItem()
{
var teamProjects = versionControlServer.GetAllTeamProjects(false);
for (int i = 0; i < teamProjects.Length; i++)
{
string teamProjectName = teamProjects[i].Name;
var teamProject = teamProjects[i];
Project teamProjectWI = wiStore.Projects[i];
teamProjectPath = projectCollectionUri + teamProject.Name;
if (workItemChangedEvent.PortfolioProject == teamProjectName)
{
//get the workitem by ID ( CoreFields.IntegerFields[0] == ID ?!)
//check if any of String changed fields
foreach(StringField sf in workItemChangedEvent.ChangedFields.StringFields)
{
//is the State field
if (sf.Name.Equals("State"))
{
//then notify Reuqester
wItem = wiStore.GetWorkItem(workItemChangedEvent.CoreFields.IntegerFields[0].NewValue);
string CollGuid = projectCollection.InstanceId.ToString();
string Requester = wItem.Fields["Requester"].Value.ToString();
string WorkItemId = wItem.Id.ToString();
string mail = GetEmailAddress(Requester);
SendMail(CollGuid, WorkItemId, mail);
}
}
}
}
}
private static string GetEmailAddress(string userDisplayName)
{
DirectorySearcher ds = new DirectorySearcher();
ds.PropertiesToLoad.Add("mail");
ds.Filter = String.Format("(&(displayName={0})(objectCategory=person)((objectClass=user)))", userDisplayName);
SearchResultCollection results = ds.FindAll();
if (results.Count == 0)
{
return string.Empty;
}
ResultPropertyValueCollection values = results[0].Properties["mail"];
if (values.Count == 0)
{
return string.Empty;
}
return values[0].ToString();
}
private static void SendMail(string collID,string workItemId,string tomailAddrees)
{
MailMessage objeto_mail = new MailMessage();
SmtpClient client = new SmtpClient();
client.Port = Port;
client.Host = SMTPHost;
client.Timeout = 200000;
client.DeliveryMethod = SmtpDeliveryMethod.Network;
client.UseDefaultCredentials = true;
client.EnableSsl = true;
client.Credentials = new System.Net.NetworkCredential(MailAddressFrom, Password);
objeto_mail.From = new MailAddress(MailAddressFrom);
objeto_mail.To.Add(new MailAddress(tomailAddrees));
//objeto_mail.CC.Add(new MailAddress("nagarajb#hotmail.com"));
objeto_mail.Subject = "Work Item Changed:"+workItemId;
string mailbody = serverPath+"/tfs/web/wi.aspx?pcguid=" + collID + "&id=" + workItemId;
string mailbody2 = "";
if (ExternalURL.Length > 0)
{
mailbody2 = ExternalURL + "/tfs/web/wi.aspx?pcguid=" + collID + "&id=" + workItemId;
}
string tables = "<table border=1><tr><td>Work Item ID</td><td>" + wItem.Id.ToString() + "</td></tr><tr><td>Title</td><td>" + wItem.Title + "</td></tr><tr><td>State</td><td>" + wItem.State + "</td></tr><tr><td>Assigned To</td><td>" + wItem.Fields["Assigned to"].Value.ToString() + "</td></tr><tr><td>Internal URL</td><td>" + mailbody + "</td></tr><tr><td>External URL</td><td>" + mailbody2 + "</td></tr></table>";
objeto_mail.IsBodyHtml = true;
objeto_mail.Body = "<i>Hi " + wItem.Fields["Requester"].Value.ToString() + ","+"</i></br></br></br>" + tables + " </br></br> Best regards; </br></br>Configuration Management Team</br></br></br>";
client.Send(objeto_mail);
EventLog.WriteEntry("WorkItemChangedEventHandler", "Email Sent");
}
}
}
No errors or exceptions are thrown in the Event Log either. Tracing TFS (trace=true property in web.config) also was of no help.
Maybe someone could help or shed light on this mysterious case?
UPDATE:
Thanks for a reply Giulio Vian!
Here how it goes:
1) I haven't seen the dependencies broken, plus the constructor WorkItemChangedEventHandler is successfully called. That is seen in the Windows Event Log - WorkItemChangedEvent Started message is written.
2) I am not sure how to register the event handler.... i'll look that up
3) I am not sure how this works. I thought just copy-pasting dlls in the appropriate folder will do the trick, and there is no need for an account for the plugin. Mind giving a bit more info on this?
4) yes. Web.config in the main Web config in Application Tier\Web Services
5) Yes. Using an account with Administer rights. if i set a break point in the constructor, it is reached. Any other place in the code is not reached.
Many things can be wrong.
If any dependency is broken, you should see an error in the Event log
If you do not register the "WorkItemChangedEventHandler" event source, no message is written
Can the user account running the plugin access TFS?
How did you enabled the tracing (you pasted a bunch of code, but no configuration)?
Have you attached the debugger to the TFS process and set a breakpoint (do not this on a production TFS)?
We have collected similar suggestions in the documentation for our plugin at
https://github.com/tfsaggregator/tfsaggregator/wiki.

Categories