How do I use the Bing Search API in Windows Phone? - c#

I'm trying to use the Bing Search API to find images as backgrounds to the tiles inside of my app. I've included the BingSearchContainer.cs in my Project but I can't make it work with the sample code provided here.
Any guidelines for how to use the Bing Search API inside of my Windows Phone 8 app would be appriciated!
Thanks for any answer.

I expect that you already have a AccountKey so I wont tell you have to get one.
Implementation
First of all, add the BingSearchContainer.cs to your project
Implement the sample C# code found in the Bing API Quick Start & Code
Thereafter, right-click References and choose Manage NuGet Packages... and search for, and install, Microsoft.Data.Services.Client.WindowsP.
Modify the sample code so that it work with Windows Phone:
using Bing;
using System;
using System.Data.Services.Client;
using System.Linq;
using System.Net;
namespace StackOverflow.Samples.BingSearch
{
public class Finder
{
public void FindImageUrlsFor(string searchQuery)
{
// Create a Bing container.
string rootUri = "https://api.datamarket.azure.com/Bing/Search";
var bingContainer = new Bing.BingSearchContainer(new Uri(rootUri));
bingContainer.UseDefaultCredentials = false;
// Replace this value with your account key.
var accountKey = "YourAccountKey";
// Configure bingContainer to use your credentials.
bingContainer.Credentials = new NetworkCredential(accountKey, accountKey);
// Build the query.
var imageQuery = bingContainer.Image(query, null, null, null, null, null, null);
imageQuery.BeginExecute(_onImageQueryComplete, imageQuery);
}
// Handle the query callback.
private void _onImageQueryComplete(IAsyncResult imageResults)
{
// Get the original query from the imageResults.
DataServiceQuery<Bing.ImageResult> query =
imageResults.AsyncState as DataServiceQuery<Bing.ImageResult>;
var resultList = new List<string>();
foreach (var result in query.EndExecute(imageResults))
resultList.Add(result.MediaUrl);
FindImageCompleted(this, resultList);
}
public event FindImageUrlsForEventHandler FindImageUrlsForCompleted;
public delegate void FindImageUrlsForEventHandler(object sender, List<string> result);
}
}
Example
And now, let's use the code I provided you with:
using Bing;
using System;
using System.Data.Services.Client;
using System.Linq;
using System.Net;
namespace StackOverflow.Samples.BingSearch
{
public class MyPage
{
private void Button_Click_1(object sender, RoutedEventArgs e)
{
var finder = new Finder();
finder.FindImageUrlsForCompleted += finder_FindImageUrlsForCompleted;
finder.FindImageUrlsFor("candy");
}
void finder_FindImageUrlsForCompleted(object sender, List<string> result)
{
Deployment.Current.Dispatcher.BeginInvoke(() =>
{
foreach (var s in result)
MyTextBox.Text += s + "\n";
});
}
}
}

Related

Trouble Enumerating BLE devices in Win32 Desktop Application Using UWP APIs

I am trying to add BLE functionality into a classic (WinForms?) C# desktop application, and have added references (Windows.winmd and System.Runtime.WindowsRuntime) to allow me to access the new BLE API recently introduced by Microsoft for Windows 10 UWP applications. I need to create a classic desktop application, as I need to use an older driver device wrapper (teVirtualMIDI) and want to create a .exe, not an app package.
I am referencing the aformentioned libraries from the following locations...
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Facade\Windows.WinMD
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Runtime.WindowsRuntime.dll
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework.NETCore\v4.5\System.Runtime.WindowsRuntime.UI.Xaml.dll
At this point, I simply want to be able to view connected services and characteristics in the debug output window, as is done in this blog post...
https://blogs.msdn.microsoft.com/cdndevs/2017/04/28/uwp-working-with-bluetooth-devices-part-1/
It seems that I am getting errors because the BLE API needs to perform async operations, but I am honestly at a loss. The code I have written so far is included below. Essentially, I am receiving errors when trying to call the "GetGattServicesAsync()" method, as Visual Studio says that class "BluetoothLEDevice" does not contain such a definition. That method is included in the online documentation though, and I am wondering why I am not able to access it.
I hope I have given sufficient information, and any help in solving this problem will be more than appreciated. Thank you all for all the helpful advice you give!
using System;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using Windows.Devices.Bluetooth;
using Windows.Devices.Midi;
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.Storage.Streams;
using Windows.UI.Core;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Navigation;
namespace BDBMidiClient
{
public class BLEHandlingDiscovery : Page
{
//private ObservableCollection<BluetoothLEAttributeDisplay> ServiceCollection = new ObservableCollection<BluetoothLEAttributeDisplay>();
//private ObservableCollection<BluetoothLEAttributeDisplay> CharacteristicCollection = new ObservableCollection<BluetoothLEAttributeDisplay>();
public ObservableCollection<BluetoothLEDeviceDisplay> KnownDevices = new ObservableCollection<BluetoothLEDeviceDisplay>();
//private List<DeviceInformation> UnknownDevices = new List<DeviceInformation>();
//private DeviceWatcher deviceWatcher;
//private BluetoothLEDevice bluetoothLeDevice = null;
//private GattCharacteristic selectedCharacteristic;
private void StartBLEDeviceWatcher()
{
string[] requestedProperties = { "System.Devices.Aep.DeviceAddress", "System.Devices.Aep.IsConnected" };
DeviceWatcher deviceWatcher =
DeviceInformation.CreateWatcher(
BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
requestedProperties,
DeviceInformationKind.AssociationEndpoint);
/*
DeviceWatcher deviceWatcher =
DeviceInformation.CreateWatcher(
"System.ItemNameDisplay:~~\"BDB\"",
requestedProperties,
DeviceInformationKind.AssociationEndpoint);*/
deviceWatcher.Added += DeviceWatcher_Added;
deviceWatcher.Updated += DeviceWatcher_Updated;
deviceWatcher.Removed += DeviceWatcher_Removed;
deviceWatcher.Start();
//Debug.WriteLine(requestedProperties);
}
private async void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation deviceInfo)
{
Guid gattService = new Guid();
var device = await BluetoothLEDevice.FromIdAsync(deviceInfo.Id);
var services=await device.GetGattServicesAsync();
foreach (var service in services.Services)
{
Debug.WriteLine($"Service: {service.Uuid}");
var characteristics = await service.GetCharacteristicsAsync();
foreach (var character in characteristics.Characteristics)
{
Debug.WriteLine($"Characteristic: {character.Uuid}");
}
}
}
private void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
{
}
private void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate deviceInfoUpdate)
{
}
async void ConnectToBLEDevice(DeviceInformation deviceInformation)
{
BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync("BDB");
}
private BluetoothLEDeviceDisplay FindBluetoothLEDeviceDisplay(string id)
{
foreach (BluetoothLEDeviceDisplay bleDeviceDisplay in KnownDevices)
{
if (bleDeviceDisplay.Id == id)
{
return bleDeviceDisplay;
}
}
return null;
}
}
The doc says the API belongs to "Windows 10 Creators Update (introduced v10.0.15063.0)". So please try to add the one from "C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.15063.0\Windows.winmd"
Here is the result from my project
You can see my code works well.

Perform a search on google and retrieve results on second page

I am using SharpDevelop platform and I want to do perform a google search for an expression, then generate a list of all web addresses in the first page, another list on the second page, etc. Using some sample code I found, I can retrieve results from the first page. How can I modify the code to get the results on the second page?
Maybe there are better methods than what I found, for example using google API?
Here is the code:
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using System.Net;
using System.Collections.Specialized;
namespace GoogleSearch
{
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form
{
public MainForm()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
//
// TODO: Add constructor code after the InitializeComponent() call.
//
}
void Button1Click(object sender, EventArgs e)
{
string uriString = "http://www.google.com/search";
string keywordString = "search expression";
WebClient webClient = new WebClient();
NameValueCollection nameValueCollection = new NameValueCollection();
nameValueCollection.Add("q", keywordString);
webClient.QueryString.Add(nameValueCollection);
textBox1.Text = webClient.DownloadString(uriString);
}
}
}

Call a 'host' callback from a 'compiled assembly from source'

I'm compiling code on-the-fly using System.CodeDom.Compiler. Everything inside the compiled source works well, whatever I'm putting inside this source. I know how to call my functions:
o = results.CompiledAssembly.CreateInstance("Foo.Bar");
MethodInfo mi = o.GetType().GetMethod("SayHello");
mi.Invoke(o, null);
But let's say I'm using a WebClient to retrieve a string asynchronously using WebClient.DownloadStringAsync. Or any other context where I want my compiled source to tell to the host "Hey, I got a nice string ready for you." For the example, I've used a WebBrowser. Basically, I know how to deal with each of the two instances: My hosting program and the compiled program, but I want my compiled program to communicate with the host. By the way, I'm not a super-experimented programmer, so no obvious method comes to my mind.
What I've tried:
1 . I don't really need to try it because it would work, but I could use a timer reading a strings stack or tasks queue inside the compiled source, but the purpose of my application is to have +- 60 scripts able to execute ponctual tasks, not continuous background processes, so it wouldn't be efficient on the CPU.
2 . I've passed the handler to the compiled source like if it was in the hosting app:
//In the hosting app
MethodInfo mi2 = o.GetType().GetMethod("attachCallbackToHost");
mi2.Invoke(o2, new object[] { new WebBrowserNavigatedEventHandler (wb_navigated) });
//... And the handler
public static void wb_navigated(object sender, WebBrowserNavigatedEventArgs e)
{
string browserHtmlFromCompiledSource = ((WebBrowser)sender).DocumentText;
MessageBox.Show(browserHtmlFromCompiledSource);
}
// Plain text from the compiled source code
public void attachCallbackToHost(WebBrowserNavigatedEventHandler handlerFromTheHost)
{
wb.Navigated += handlerFromTheHost;
}
And it did nothing.
3 . Maybe I could share a class or variable by passing it to the compiled assembly?
So, the question is either this or the other:
How to watch efficiently for change inside a specific variable or property inside the compiled program?
How to attach a callback to the host?
Ok. I got it: In order to access the host from the compiled source, the only thing required is to add the host assembly to the refered assemblies in the compiler parameters:
compilerParams.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
So no need for any special callback or INotifier.
Here's the full code that strictly answers my question and nothing more:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using Microsoft.CSharp;
using System.CodeDom.Compiler;
using System.Reflection;
namespace MamaProgram
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
string source =
#"
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using MyMama = MamaProgram;
namespace Baby
{
public class Program
{
public WebBrowser wb = new WebBrowser();
public void navigateTo(string url)
{
wb.Navigated += wb_navigated;
wb.Navigate(url);
}
public void wb_navigated(object sender, WebBrowserNavigatedEventArgs e)
{
MyMama.Form1.getResult(wb.DocumentText);
}
}
}
";
Dictionary<string, string> providerOptions = new Dictionary<string, string>
{
{"CompilerVersion", "v3.5"}
};
CSharpCodeProvider provider = new CSharpCodeProvider(providerOptions);
CompilerParameters compilerParams = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = false,
TreatWarningsAsErrors = false
};
compilerParams.ReferencedAssemblies.Add(Assembly.GetExecutingAssembly().Location);
compilerParams.ReferencedAssemblies.Add("System.Data.dll");
compilerParams.ReferencedAssemblies.Add(typeof(System.Linq.Enumerable).Assembly.Location); // Trick to add assembly without knowing their name
compilerParams.ReferencedAssemblies.Add(typeof(System.ComponentModel.Component).Assembly.Location); // Trick to add assembly without knowing their name
compilerParams.ReferencedAssemblies.Add("System.Windows.Forms.dll");
CompilerResults results = provider.CompileAssemblyFromSource(compilerParams, source);
if (results.Errors.Count != 0)
throw new Exception("Compilation failed");
object o = results.CompiledAssembly.CreateInstance("Baby.Program");
MethodInfo mi2 = o.GetType().GetMethod("navigateTo");
mi2.Invoke(o, new object[] { "http://www.google.com" });
}
public static void getResult(string result)
{
MessageBox.Show(result);
}
}
}

winform Close self plus another WebBrowserControl

i know i could search proccessId / name of running tasks and kill processes i need .
though till now i was not developing schedualed tasks / self executble Applications,
so i didn't need to know how to make the application close itself after execition
trying to close everything (including WebDriver) via Application.Exit + OR this.Close()
right after i have got what i was looking for. mission Complete .
please close ... no more work for you .
but mr . Program.cs still needs somthing from Form1.
saying somthing about
Cannot access a disposed object.
Object name: 'Form1'.
any combination of both was returning in some point an exeption error
(from program.cs ) even though mission complete . no more code was requested .(?) by me..atleast.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;
using System.IO;
namespace HT_R_WbBrows2
{
public partial class Form1 : Form
{
public IeEnginGenerator Iengn = new IeEnginGenerator();
public Form1()
{
InitializeComponent();
//setLogView(View.Details);
string extractededVal = Iengn.ExtractPageValue(Iengn.itrfWebEng);
string flnm = #" the directory path to file --> \dolarRate.asp";
File.WriteAllText(fn, extractededVal);
this.Close();
Application.Exit();
}
public class IeEnginGenerator
{
private string directory = Environment.CurrentDirectory;///Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
public IWebDriver IwebEngine;
public List<string> ListElementsInnerHtml = new List<string>();
public HtmlAgilityPack.HtmlDocument Dnetdoc = new HtmlAgilityPack.HtmlDocument();
#region <<=========== setupDriver ============>>
public string ExtractPageValue(IWebDriver DDriver, string url="")
{
if(string.IsNullOrEmpty(url))
url = #"http://www.boi.org.il/he/Markets/ExchangeRates/Pages/Default.aspx";
var service = InternetExplorerDriverService.CreateDefaultService(directory);
service.LogFile = directory + #"\seleniumlog.txt";
service.LoggingLevel = InternetExplorerDriverLogLevel.Trace;
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
DDriver = new InternetExplorerDriver(service, options, TimeSpan.FromSeconds(60));
DDriver.Navigate().GoToUrl(url);
Dnetdoc.LoadHtml(DDriver.PageSource);
string Target = Dnetdoc.DocumentNode.SelectNodes("//table//tr")[1].ChildNodes[7].InnerText;
//.Select(tr => tr.Elements("td").Select(td => td.InnerText).ToList())
//.ToList();
return Math.Round(Convert.ToDouble(Target), 2).ToString();
//return "";//Math.Round(Convert.ToDouble( TempTxt.Split(' ')[10]),2).ToString();
}
#endregion
}
}
}
Why use a winform application? A Console application would probably suffice for what you are doing. Once Main() ends your app will close as well. Main() never ends in a winform app because of the applications runloop.
Edit:
Here would be the correct way to do this. You need to register to the forms Load event and run your code there, not in the constructor. You can't close a winform from inside a constructor.
Edit 2: Put this code in the Form1() constructor. Somewhere after InitializeComponent();
this.Load += (sender,args)=>{ /*do all your work here*/
string extractededVal = Iengn.ExtractPageValue(Iengn.itrfWebEng);
string flnm = #" the directory path to file --> \dolarRate.asp";
File.WriteAllText(fn, extractededVal);
Application.Exit();
};

C#: execute a function stored in a string variable

Is it possible to write a simple and fast function in C# that will execute arbitrary methods from a string? For example, if I set MyString="MessageBox.Show("Some Message")" and then call ExecuteString(MyString), a message box would pop up with "Some Message" in it.
(I've probably made some sort of error in the above code. I don't yet know C#; I'm trying to evaluate whether it would be appropriate for a specific project.)
You should be able to use this and wrap the code required to run a string into a function.
Essentially what you're doing is wrapping the small bit of C# code in a Program.Mainstyle function, referencing some assemblies for basic functionality (maybe including your own assembly) then run the compiled program in memory.
It's likely a bit of more overhead than you need to simply run one or two lines of code mind you.
http://support.microsoft.com/kb/304655
what you appear to be looking for is CS-Script
Alas, C# is not a dynamic language in that way. You can't really do this easily, and if it's really something you need to do, consider using a .Net language more in line with your needs, like IronPython or IronRuby.
Your best available alternative is to use the CodeDom namespace, as this truly convoluted and heinous example from this forum thread shows:
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Windows.Forms;
namespace TestApp
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
SampleLib.SampleType test = new SampleLib.SampleType();
private void button1_Click(object sender, EventArgs e)
{
// Dynamically build and call the method
label1.Text = test.MyText;
}
private void button2_Click(object sender, EventArgs e)
{
StringBuilder DynamicCode = new StringBuilder();
DynamicCode.Append("namespace TestDynamic");
DynamicCode.Append("{");
DynamicCode.Append("public class DynamicCode");
DynamicCode.Append("{");
DynamicCode.Append("public static void EditText(SampleLib.SampleType t)");
DynamicCode.Append("{");
DynamicCode.Append("t.MyText = \"Goodbye!\";");
DynamicCode.Append("}");
DynamicCode.Append("}");
DynamicCode.Append("}");
string CodeString = DynamicCode.ToString();
System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
CodeDomProvider provider = CodeDomProvider.CreateProvider("C#");
CompilerParameters CompileParams = new CompilerParameters(new string[] { fi.DirectoryName + "\\SampleLib.dll" },
fi.DirectoryName + "\\Dynamic.dll");
CompileParams.MainClass = "DynamicCode";
CompileParams.GenerateExecutable = false;
//CompileParams.GenerateInMemory = true;
CompilerResults r = provider.CompileAssemblyFromSource(CompileParams, new string[] {CodeString});
foreach (CompilerError er in r.Errors)
{
Console.WriteLine(er.ErrorText);
}
}
private void button3_Click(object sender, EventArgs e)
{
// Dynamically call assembly
System.IO.FileInfo fi = new System.IO.FileInfo(Application.ExecutablePath);
Assembly dynAsm = Assembly.LoadFile(fi.DirectoryName + "\\Dynamic.dll");
if (dynAsm != null)
{
object o = dynAsm.CreateInstance("TestDynamic.DynamicCode", true);
Type t = dynAsm.GetType("TestDynamic.DynamicCode");
t.GetMethod("EditText").Invoke(o, new object[]{test});
}
}
}
}

Categories