Simple Example – Local SQL, PC control service - !?

Category: windows phone howto

Question

Orencosoft on Sun, 05 Feb 2012 02:50:01


I see a lot of questions about services, remote databases, PC control. Haven’t seen any inclusive info, just bits and pieces. So I thought I would post a simple example. I used WP7 and Visual Web Developer Express 2010 free tools. Pretty powerful tools for free.

 

Haven’t written this type of code for awhile, so I wanted to slap jack something together and write it down for later, always forget exactly how to do it. The code and instructions are a little rough, no error handling. It all runs local on your PC, with a local database. I picked linq to entities instead of linq to sql. Didn’t try linq to sql in the example but have used it before, supposedly entities are going to replace linq to sql.

 

Not much of database programmer so the schema and code is a little clunky. But it’s just an example. It will store first name, last name. Return all last names ,tap one and it will list all full names.

 

PC control I have written using sockets in other applications. Click the PC Interaction button, back key to go back to the database page. The PC control code is just eye candy in this example. Fun to play with and see your desktop, processes and open notepad (or whatever). It should be implemented over RDP, or sockets, but was just a fun exercise using the service running local on my PC. I suppose you could run a small web server on your PC, that would make a pretty easy project for local phone to PC use. I see IIS 7.5 Express is available as a separate download, don’t know if it can be used outside of a dev environment. You could still develop using a simple setup like this and port a lot of the code over to something else.

 

The project UI layout is pretty bad, tried to put it all on one page, wouldn’t fit so I added a popup to make it easy.

 

Be careful experimenting with the process class, it can hose your PC. I didn’t add Process.CloseMainWindow or Kill. But it would be easy to add by sending to the service a process name from the process list and close it, or kill it. You can also send a string argument(s) to a modified start note pad and fire up anything you want. Some more eye candy.

 

As mentioned it is a slap jacked together project, just for fun. I haven’t published to a remote web site, just tested it locally. Didn’t spend a lot of time checking the instructions, code works on my PC. May be some bugs or errors, but it may give someone a start if they want to really use this type of stuff.

 

SERVICE;

 

Open Visual Web Developer Express 2010.

 

ASP.NET WEB APPLICATION;

 

New web project select Asp.net web application. Use default name, WebApplication1.

 

Solution explorer right mouse WebApplication1 add new item, Silverlight, Silverlight enabled webservice, Use default name, service1, add.

 

ADD LOCAL DATABASE;

 

Solution explorer right mouse App_Data add new item, Data SQL Server Compact 4.0 Local Database, add.

 

Use default name, Database1.sdf

 

Build, make sure no errors.

 

ADD TABLE;

 

View, database explorer. Database connections.

 

Click Database1.sdf arrow, right mouse tables, create table. Name it Table1.

 

In column name, type in Index, int, 4, no,no,yes. (last yes is key, need a col set as a key), set Identity = true in second section, take defaults (inc = 1, seed = 1).

 

Next column name, type in FirstName, nvarchar,100, ,no,no,no.

 

Next column name, click type in LastName, nvarchar,100, ,no,no,no,

 

Click ok.

 

ADD ENTITIES;

 

Solution explorer right mouse WebApplication1 add new item, data, add ADO.NET Entity Data Model, default name Model1.edmx, add. Generate from database, next, use defaults, (Database1.sdf, Model1.edmx, save connection checked), next.

 

Choose your database objects, check tables, make sure Table1 also checked. Use default namespace, Database1Model. Finish.

 

Build, make sure no errors.

 

Open Service1.svc.cs. Copy and paste in the code.

 

Solution explorer right mouse, references, add .net, add  using System.Windows.Forms;

 

Build, make sure no errors.

 

Run the project (with Service1.svc.cs displayed). ASP.NET dev sever will start. Get from the address bar (example http://localhost:50105/Service1.svc)

 

CREATE A 7.1 WINDOWS PHONE APPLICATION;

 

Open VS2010 Express WP. Create PhoneApp1, 7.1, build, and make sure no errors.

 

Solution explorer right mouse PhoneApp1 add Service Reference (make sure service is running). In the address box paste address from running asp.net app above, go, ok. (example http://localhost:50105/Service1.svc).

 

Copy and paste in the cs and xaml code.

 

Build, make sure no errors

 

Run PhoneApp1, should connect.

 

If any changes in service, like adding methods. Right mouse ServiceReference1, update service reference. MAKE SURE THE SERVICE IS RUNNING, PhoneApp1 SHOULD NOT BE RUNNING.

<phone:PhoneApplicationPage   
    x:Class="PhoneApp1.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone" 
    xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768" 
    FontFamily="{StaticResource PhoneFontFamilyNormal}" 
    FontSize="{StaticResource PhoneFontSizeNormal}" 
    Foreground="{StaticResource PhoneForegroundBrush}" 
    SupportedOrientations="Portrait" Orientation="Portrait" 
    shell:SystemTray.IsVisible="True">  
 
    <!--LayoutRoot is the root grid where all page content is placed-->  
    <Grid x:Name="LayoutRoot" Background="Transparent">  
        <Grid.RowDefinitions>  
            <RowDefinition Height="Auto"/>  
            <RowDefinition Height="*"/>  
        </Grid.RowDefinitions>  
 
        <!--TitlePanel contains the name of the application and page title-->  
        <StackPanel x:Name="TitlePanel" Grid.Row="0" Margin="0">  
            <TextBlock x:Name="ApplicationTitle" Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}" Margin="0,0,8,0"/>  
            <TextBlock x:Name="PageTitle" Text="page name" Margin="9,-7,8,0" Style="{StaticResource PhoneTextTitle1Style}"/>  
        </StackPanel>  
 
        <!--ContentPanel - place additional content here-->  
        <Grid x:Name="ContentPanel" Grid.Row="1" Margin="0">  
            <Canvas Margin="0">  
                <TextBlock Height="30" x:Name="textBlock1" Text="First Name" Canvas.Left="27" Canvas.Top="27" />  
                <TextBox Height="72" HorizontalAlignment="Left" x:Name="textBox1" Width="253" Canvas.Left="172" Canvas.Top="6" />  
                <TextBlock Height="30" x:Name="textBlock2" Text="Last Name" Width="127" Canvas.Left="27" Canvas.Top="108" />  
                <TextBox Height="72" HorizontalAlignment="Left" x:Name="textBox2" Width="253" Canvas.Left="172" Canvas.Top="87" />  
                <TextBlock Height="30" x:Name="textBlock3" Text="Response" Width="127" Canvas.Left="27" Canvas.Top="199" />  
                <TextBox Height="103" HorizontalAlignment="Right" x:Name="textBox3" FontSize="16" Width="253" TextWrapping="Wrap" Canvas.Left="172" Canvas.Top="162" />  
                <Button Content="Add To DB" Height="59" x:Name="button1" Width="145" Click="button1_Click" FontSize="18" Canvas.Left="9" Canvas.Top="235" />  
                <ListBox Height="100" HorizontalAlignment="Left" x:Name="listBox1" VerticalAlignment="Top" Width="438" SelectionChanged="listBox1_SelectionChanged" Canvas.Left="9" Canvas.Top="300" />  
                <Button Content="Get DB Last Names" Height="61" x:Name="button2" VerticalAlignment="Top" Width="189" FontSize="16" Click="button2_Click" Canvas.Left="12" Canvas.Top="406" />  
                <TextBlock Height="30" HorizontalAlignment="Left" x:Name="textBlock4" Text="All Full Names Response" VerticalAlignment="Top" Canvas.Left="131" Canvas.Top="473" />  
                <ListBox Height="100" HorizontalAlignment="Left" x:Name="listBox2" VerticalAlignment="Top" Width="435" Canvas.Left="12" Canvas.Top="505" />  
                <Button Content="PC Interaction" Height="63" HorizontalAlignment="Left" x:Name="button3" VerticalAlignment="Top" Width="186" FontSize="16" Click="button3_Click" Canvas.Left="239" Canvas.Top="404" />  
            </Canvas>  
            <Popup x:Name="pcPopUp" Margin="0" Visibility="Collapsed">  
                <Grid x:Name="pcPopupGrid" Background="{StaticResource PhoneBackgroundBrush}" Height="600" Width="480" HorizontalAlignment="Center" VerticalAlignment="Center">  
                    <Grid.RowDefinitions>  
                        <RowDefinition Height="Auto"/>  
                        <RowDefinition Height="Auto"/>  
                        <RowDefinition Height="Auto"/>  
                        <RowDefinition Height="Auto"/>  
                        <RowDefinition Height="Auto"/>  
                    </Grid.RowDefinitions>  
                    <Grid.ColumnDefinitions>  
                        <ColumnDefinition Width="Auto"/>  
                    </Grid.ColumnDefinitions>  
                    <Image Height="225" HorizontalAlignment="Center" Margin="40,0,0,0" x:Name="image1" Stretch="Fill" VerticalAlignment="Center" Width="400" />  
                    <Button Content="Get PC Desk Top" Padding="0" Grid.Row="1" Name="button4" Click="button4_Click" Margin="0" d:LayoutOverrides="Width, Height" HorizontalAlignment="Center" VerticalAlignment="Center" />  
                    <Button Content="Start NotePad" Padding="0" Grid.Row="2" x:Name="button5" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center" Click="button5_Click" />  
                    <ListBox x:Name="listBox3" HorizontalAlignment="Left" Height="100" VerticalAlignment="Top" Width="435" Grid.Row="3"/>  
                    <Button Content="Get PC Processes" Padding="0" Grid.Row="4" x:Name="button6" Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center" Click="button6_Click" />  
                </Grid>  
            </Popup>  
        </Grid>  
    </Grid>  
 
    <!--Sample code showing usage of ApplicationBar-->  
    <!--<phone:PhoneApplicationPage.ApplicationBar>  
        <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">  
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button1.png" Text="Button 1"/>  
            <shell:ApplicationBarIconButton IconUri="/Images/appbar_button2.png" Text="Button 2"/>  
            <shell:ApplicationBar.MenuItems>  
                <shell:ApplicationBarMenuItem Text="MenuItem 1"/>  
                <shell:ApplicationBarMenuItem Text="MenuItem 2"/>  
            </shell:ApplicationBar.MenuItems>  
        </shell:ApplicationBar>  
    </phone:PhoneApplicationPage.ApplicationBar>-->  
 
</phone:PhoneApplicationPage> 

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Net;  
using System.Windows;  
using System.Windows.Controls;  
using System.Windows.Documents;  
using System.Windows.Input;  
using System.Windows.Media;  
using System.Windows.Media.Animation;  
using System.Windows.Shapes;  
using Microsoft.Phone.Controls;  
using PhoneApp1.ServiceReference1;  
using System.Collections.ObjectModel;  
using System.IO;  
using System.Windows.Media.Imaging;  
 
namespace PhoneApp1  
{  
    public partial class MainPage : PhoneApplicationPage  
    {  
        Service1Client testService;  
 
        // Constructor  
        public MainPage()  
        {  
            InitializeComponent();  
            testService = new Service1Client();  
            testService.SaveNameCompleted += new EventHandler<SaveNameCompletedEventArgs>(testService_SaveNameCompleted);  
            testService.GetLastNamesCompleted += new EventHandler<GetLastNamesCompletedEventArgs>(testService_GetLastNamesCompleted);  
            testService.GetFullNamesCompleted += new EventHandler<GetFullNamesCompletedEventArgs>(testService_GetFullNamesCompleted);  
            testService.CaptureScreenCompleted += new EventHandler<CaptureScreenCompletedEventArgs>(testService_CaptureScreenCompleted);  
            testService.StartNotePadCompleted += new EventHandler<System.ComponentModel.AsyncCompletedEventArgs>(testService_StartNotePadCompleted);  
            testService.RunningProcessesCompleted += new EventHandler<RunningProcessesCompletedEventArgs>(testService_RunningProcessesCompleted);  
 
        }  
 
        ObservableCollection<string> pcProcesses = new ObservableCollection<string>();  
        void testService_RunningProcessesCompleted(object sender, RunningProcessesCompletedEventArgs e)  
        {  
            pcProcesses.Clear();  
            pcProcesses = e.Result;  
            listBox3.ItemsSource = pcProcesses; // bind  
        }  
 
        void testService_StartNotePadCompleted(object sender, System.ComponentModel.AsyncCompletedEventArgs e)  
        {  
            // could return errors, modify web service to add return var  
        }  
 
        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)  
        {  
            // if its visible hide it  
            if (pcPopUp.Visibility == System.Windows.Visibility.Visible)  
            {  
                pcPopUp.Visibility = System.Windows.Visibility.Collapsed;  
                pcPopUp.IsOpen = false;  
                e.Cancel = true;  
                return;  
            }  
        }  
 
        void testService_CaptureScreenCompleted(object sender, CaptureScreenCompletedEventArgs e)  
        {  
            BitmapImage bitMapImage = new BitmapImage();  
            MemoryStream mstream = new MemoryStream(e.Result);  
            bitMapImage.SetSource(mstream);  
            mstream.Close();  
            image1.Source = bitMapImage;  
        }  
 
        ObservableCollection<string> dbFullNames = new ObservableCollection<string>();  
        void testService_GetFullNamesCompleted(object sender, GetFullNamesCompletedEventArgs e)  
        {  
            dbFullNames.Clear();  
            dbFullNames = e.Result;  
            listBox2.ItemsSource = dbFullNames; // bind  
        }  
 
        ObservableCollection<string> dbLastNames = new ObservableCollection<string>();  
        void testService_GetLastNamesCompleted(object sender, GetLastNamesCompletedEventArgs e)  
        {  
            dbLastNames.Clear();  
            // error handler example  
            try 
            {  
                dbLastNames = e.Result;  
            }  
            catch (Exception ex)  
            {  
                MessageBox.Show("GetLastNamesAsync error = " + ex.Message.ToString(), "ERROR", MessageBoxButton.OK);  
                return;  
            }  
            listBox1.ItemsSource = dbLastNames; // bind  
        }  
 
        void testService_SaveNameCompleted(object sender, SaveNameCompletedEventArgs e)  
        {  
            textBox3.Text = e.Result;  
        }  
 
        private void button1_Click(object sender, RoutedEventArgs e)  
        {  
            if (textBox1.Text == "")  
            {  
                MessageBox.Show("You need to type in a first name""ERROR", MessageBoxButton.OK);  
                return;  
            }  
            if (textBox2.Text == "")  
            {  
                MessageBox.Show("You need to type in a last name""ERROR", MessageBoxButton.OK);  
                return;  
            }  
 
            testService.SaveNameAsync(textBox1.Text, textBox2.Text);  
        }  
 
        private void button2_Click(object sender, RoutedEventArgs e)  
        {  
            testService.GetLastNamesAsync();  
        }  
 
        private void listBox1_SelectionChanged(object sender, SelectionChangedEventArgs e)  
        {  
            if (listBox1.SelectedIndex == -1) { return; }   // need this when seting selectedindex = -1 to clear  
            testService.GetFullNamesAsync(listBox1.SelectedItem.ToString());  
            listBox1.SelectedIndex = -1;    // clear selection  
        }  
 
        private void button3_Click(object sender, RoutedEventArgs e)  
        {  
            pcPopUp.Visibility = System.Windows.Visibility.Visible;  
            pcPopUp.IsOpen = true;  
        }  
 
        private void button4_Click(object sender, RoutedEventArgs e)  
        {  
            testService.CaptureScreenAsync();  
        }  
 
        private void button5_Click(object sender, RoutedEventArgs e)  
        {  
            testService.StartNotePadAsync();  
        }  
 
        private void button6_Click(object sender, RoutedEventArgs e)  
        {  
            testService.RunningProcessesAsync();  
        }  
    }  

Service1 code

using System;  
using System.Linq;  
using System.Runtime.Serialization;  
using System.ServiceModel;  
using System.ServiceModel.Activation;  
using System.Collections.Generic;  
using System.Data;   // added  
using System.Drawing;   // added  
using System.Windows.Forms;   // added plus ref  
using System.IO;   // added  
using System.Drawing.Imaging; // added   
using System.Diagnostics;   // added  
using System.ComponentModel;   // added  
 
namespace WebApplication1  
{  
    [ServiceContract(Namespace = "")]  
    [SilverlightFaultBehavior]  
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]  
    public class Service1  
    {  
        [OperationContract]  
        public void DoWork()  
        {  
            // Add your operation implementation here  
            return;  
        }  
 
        // Add more operations here and mark them with [OperationContract]  
        [OperationContract]  
        public string SaveName(string firstName, string lastName)  
        {  
            //*********** linq to entity **************  
            Database1Entities SaveNameToDB = new Database1Entities();  
            IEnumerable<string> query = from n in SaveNameToDB.Table1  
                                        where n.LastName == lastName  
                                        orderby n.LastName descending  
                                        select n.FirstName;  
 
            foreach (string name in query)  
            {  
                {  
                    if (name == firstName)  
                    {  
                        return (firstName + " " + lastName + " already in database");  
                    }  
                }  
            }  
 
            Table1 names = new Table1() { FirstName = firstName, LastName = lastName };  
            SaveNameToDB.AddToTable1(names);  
            SaveNameToDB.SaveChanges();  
            return (firstName + " " + lastName + " saved in database");  
        }  
 
        [OperationContract]  
        public List<string> GetLastNames()  
        {  
            //*********** linq to entity **************  
            Database1Entities GetLastNamesFromDB = new Database1Entities();  
            IEnumerable<string> query = from n in GetLastNamesFromDB.Table1  
                                        where n.LastName.Length > 0  
                                        orderby n.LastName descending  
                                        select n.LastName;  
 
            List<string> lastNames = new List<string>();  
            foreach (string name in query)  
            {  
                if (!lastNames.Contains(name))   // remove duplicates from return list  
                {  
                    lastNames.Add(name);  
                }  
            }  
            return (lastNames);  
        }  
 
        [OperationContract]  
        public List<string> GetFullNames(string lastName)  
        {  
            //*********** linq to entity **************  
            Database1Entities GetLastNamesFromDB = new Database1Entities();  
            IEnumerable<string> query = from n in GetLastNamesFromDB.Table1  
                                        where n.LastName.Length > 0 && n.LastName == lastName  
                                        orderby n.LastName descending  
                                        select n.FirstName;  
 
            List<string> fullNames = new List<string>();  
            foreach (string name in query)  
            {  
                fullNames.Add(name + " " + lastName);  
            }  
            return fullNames;  
        }  
 
        [OperationContract]  
        public byte[] CaptureScreen()  
        {  
            Size sz = Screen.PrimaryScreen.Bounds.Size;  
            Bitmap bmp = new Bitmap(sz.Width, sz.Height);  
            Graphics g = Graphics.FromImage(bmp);  
            g.CopyFromScreen(0, 0, 0, 0, sz);  
 
            MemoryStream ms = new MemoryStream();  
            // Save to MemoryStream as Jpeg  
            bmp.Save(ms, ImageFormat.Jpeg);  
            byte[] byteArray = ms.GetBuffer();  
            bmp.Dispose();  
            ms.Close();  
            return byteArray;  
        }  
 
        [OperationContract]  
        public void StartNotePad()  
        {  
            Process notePad = new Process();  
            notePad.StartInfo.FileName = "notepad.exe"// could be any exe  
            //notePad.StartInfo.Arguments = "somefile.txt"; // start arg  
            notePad.Start();  
        }  
 
        [OperationContract]  
        public List<string> RunningProcesses()  
        {  
            Process[] pcProcesses = Process.GetProcesses();  
            List<string> processes = new List<string>();  
 
            foreach (Process process in pcProcesses)  
            {  
                processes.Add(process.ProcessName);  
            }  
            return processes;  
        }  
    }  
}  
 

 


Edit, Bug fix, instanced Service1Client testService twice