Windows Mobile 6 Applikation als Anruf-"Firewall" in C# Teil 2/2

Windows Mobile 6 Applikation als Anruf-"Firewall" in C# Teil 2/2

Im zweiten Teil des Video-Tutorials (Teil 1 hier) zur Entwicklung einer Windows Mobile 6 Applikation zum Annehmen oder Ablehnen eingehender Anrufe wird die Implementierung abgeschlossen sowie ein Installer gebaut.

Die Videos in diesem Teil summieren sich auch wieder zu ca. 1 Stunde, somit liegt die Gesamtdauer bei knapp 2 Stunden.

Ferner findet sich in diesem Artikel noch der Beispielcode in C#.

Den Download gibt es am Ende des Artikels, hinter den Videos und dem Code.

Windows Mobile 6 Call Blocker in C# – 5. Konsolenapplikation mit Call Handler

(29 Minuten)

In diesem Video geht es primär um das 2. Projekt, die Konsolenapplikation, in der auch der Call Handler beheimatet ist. Diese Applikation kümmert sich um das Registrieren und Deregistrieren des Call Handlers, insbesondere jedoch auch um das Auslesen der Liste der Telefonnummern sowie Aktion, und auch (auf Basis dieser Daten) um eine entsprechende Handhabung eines eingehenden Anrufes.

Windows Mobile 6 Call Blocker in C# – 6. CAB Installer

(7 Minuten)

Das gleiche Video ist auch ausnahmsweise wieder auf youtube verfügbar

Hier werden die erzeugten Binärdaten in eine .cab Datei als Installer eingefügt. Auch werden Link-Dateien (Verknüpfungen) erzeugt, sowohl für den Autostart wie auch für einen leichten Start über das Programme-Menü.

Windows Mobile 6 Call Blocker in C# – 7. CAB Installer Test und Feinschliff

(22 Minuten)

Zusammen mit dem Autostart/Startup Ordner werden hier noch ein paar kleine Probleme beseitigt, bis die Applikation schließlich am Ende insbesondere auch den ersten Anruf nach dem Anschalten des Telefons handhaben kann.


Der Inhalt der Form1.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Diagnostics;
using Microsoft.WindowsMobile.Status;
 
namespace CallBlockerG
{
    public partial class Form1 : Form
    {
        NumberData data;
        string appPath;
        string dataFile = @"numbers.txt"; // appended to appPath
        string consoleFile = @"CallBlockerC"; // appended to appPath
        string appId = "CallBlockerApp";
 
        public Form1()
        {
            InitializeComponent();
        }
 
        private void buttonAdd_Click(object sender, EventArgs e)
        {
            NumberData.Payload pl = new NumberData.Payload();
            pl.action = NumberData.eActions.accept;
            if (radioButtonAccept.Checked)
                pl.action = NumberData.eActions.accept;
            if (radioButtonAcceptEnd.Checked)
                pl.action = NumberData.eActions.acceptandend;
            if (radioButtonReject.Checked)
                pl.action = NumberData.eActions.reject;
            pl.number = makeNumberJust(textBoxNumber.Text);
            pl.seconds = 0;
            try
            {
                pl.seconds = int.Parse(textBoxSeconds.Text);
            }
            catch (Exception)
            { }
            AddPayloadToList(pl);
            data.list.Add(pl);
        }
 
        private void buttonMinExit_Click(object sender, EventArgs e)
        {
            if (buttonMinExit.Text.CompareTo("ok=exit") == 0)
            {
                buttonMinExit.Text = "x=minimieren";
                this.MinimizeBox = true;
            }
            else
            {
                buttonMinExit.Text = "ok=exit";
                this.MinimizeBox = false;
            }
        }
 
        void AddPayloadToList(NumberData.Payload pl)
        {
            string str = "";
            switch (pl.action)
            {
                case NumberData.eActions.accept:
                    str += "Annehmen";
                    break;
                case NumberData.eActions.acceptandend:
                    str += "Ann + beenden";
                    break;
                case NumberData.eActions.reject:
                    str += "Ablehnen";
                    break;
            }
            str += " " + pl.number + " nach ";
            str += " " + pl.seconds.ToString() + "s";
            listBoxNumbers.Items.Add(str);
        }
 
        string makeNumberJust(string s)
        {
            return s.Replace("(", "").Replace(")", "").Replace(" ", "").Replace("-", "").Replace("+", "00");
        }
 
        private void buttonDelete_Click(object sender, EventArgs e)
        {
            int idx = listBoxNumbers.SelectedIndex;
            if (idx >= 0)
            {
                data.list.RemoveAt(idx);
                listBoxNumbers.Items.RemoveAt(idx);
            }
        }
 
        private void buttonSave_Click(object sender, EventArgs e)
        {
            write();
        }
 
        void write()
        {
            try
            {
                StreamWriter sw = File.CreateText(dataFile);
                //sw.WriteLine(data.enabled.ToString());
                foreach (NumberData.Payload pl in data.list)
                    sw.WriteLine(((int)pl.action).ToString() + " " + pl.number + " " + pl.seconds.ToString());
                sw.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show("Fehler beim Schreiben. Vermutlich ist die Datei gesperrt. Nachricht: " + e.ToString());
            }
        }
 
        void readAndFillList()
        {
            read();
 
            listBoxNumbers.Items.Clear();
            foreach (NumberData.Payload pl in data.list)
                AddPayloadToList(pl);
        }
 
        private void buttonReload_Click(object sender, EventArgs e)
        {
            readAndFillList();
        }
 
        void read()
        {
            // reset all
            //data.enabled = 0;
            data.list.Clear();
 
            // read
            try
            {
                StreamReader sr = File.OpenText(dataFile);
                string strRead;
                //if ((strRead = sr.ReadLine()) != null)
                //    data.enabled = int.Parse(strRead); //.Contains("1")?1:0;
                while ((strRead = sr.ReadLine()) != null)
                {
                    string[] sarr = strRead.Split(' ');
                    if (sarr.Length == 3)
                    {
                        NumberData.Payload pl = new NumberData.Payload();
                        pl.action = (NumberData.eActions)int.Parse(sarr[0]);
                        pl.number = sarr[1];
                        pl.seconds = int.Parse(sarr[2]);
                        data.list.Add(pl);
                    }
                }
                sr.Close();
            }
            catch (FileNotFoundException)
            {
                // just catch file not found (in case we don't do anything)
            }
            catch (Exception e)
            {
                MessageBox.Show("Error while writing. Probably file is locked. Msg: " + e.ToString());
            }
        }
 
        private void Form1_Load(object sender, EventArgs e)
        {
            #region setup form
            buttonEnable.Text = (SystemState.IsApplicationLauncherEnabled(appId) ? "Deaktivieren" : "Aktivieren");
            #endregion
 
            #region setup data
            data = new NumberData();
            //data.list = new List<sData.sPayload>();
            appPath = Path.GetDirectoryName((System.Reflection.Assembly.GetExecutingAssembly().GetModules())[0].FullyQualifiedName);
            dataFile = appPath + @"" + dataFile;
            consoleFile = appPath + @"" + consoleFile;
            readAndFillList();
            #endregion
        }
 
        private void buttonEnable_Click(object sender, EventArgs e)
        {
            Process proc = new Process();
            proc.StartInfo.FileName = consoleFile;
            proc.StartInfo.Arguments = buttonEnable.Text;
            proc.StartInfo.WorkingDirectory = @"";
            proc.StartInfo.UseShellExecute = false;
 
            proc.Start();
 
            //proc.WaitForExit();
            System.Threading.Thread.Sleep(200);
            proc.WaitForExit(2600);
            System.Threading.Thread.Sleep(200);
 
            buttonEnable.Text = (SystemState.IsApplicationLauncherEnabled(appId) ? "Deaktivieren" : "Aktivieren");
 
            string startup = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
            string program = appPath;
            string shortcut = @"CallBlocker.lnk";
            // fiddle with autostart
            if (SystemState.IsApplicationLauncherEnabled(appId))
            {
                // move from program to startup
                string dst = startup + @"" + shortcut;
                string src = program + @"" + shortcut;
                try
                {
                    File.Move(src, dst);
                }
                catch (Exception /*ex*/)
                { }
            }
            else
            {
                // move from startup to program
                string src = startup + @"" + shortcut;
                string dst = program + @"" + shortcut;
                try
                {
                    File.Move(src, dst);
                }
                catch (Exception /*ex*/)
                { }
            }
        }
 
        private void buttonHelp_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Links kann eine Telefonnummer eingegeben werden, sowie eine der Optionen Annehmen, Annehmen + Beenden, Ablehnen ausgewählt werden.");
            MessageBox.Show("Annehmen + Beenden nimmt der Anruf direkt an und beendet ihn nach n Sekunden.");
            MessageBox.Show("In die Liste unten können Nummer hinzugefügt (+) oder daraus gelöscht (-) werden.");
            MessageBox.Show("Mit Speichern können die letzten Änderungen gesichert werden - ohne diese Option gehen sie beim Beenden des Programmes verloren.");
            MessageBox.Show("Mit Laden kann die letzte gespeicherte Version wieder hergestellt werden, aktuelle Änderungen gehen verloren.");
            MessageBox.Show("Aktivieren/Deaktivieren installiert und entfernt die Routine, die Anrufe annimmt (oder ablehnt) und den Eintrag im Autostart.");
            MessageBox.Show("Mit x=minimieren oder ok=exit kann bestimmt werdne, ob das Programm minimiert oder beendet wird.");
            MessageBox.Show("Erste Schritte:");
            MessageBox.Show("a) Einige Telefonnummern und Aktionen in die Liste unten hinufügen (+)");
            MessageBox.Show("b) Speichern der Liste");
            MessageBox.Show("c) Aktivieren der Anrufroutine (danach steht auf dem Knopf Deaktivieren)");
            MessageBox.Show("Deinstallieren: vor einer Deinstallation erst die Deaktivieren-Funktion benutzen, dann über das Systemmenü von Windows Mobile deinstallieren.");
        }
    }
 
    class NumberData
    {
        public enum eActions
        { accept, acceptandend, reject };
 
        //public int enabled;
        public class Payload
        {
            public string number;
            public eActions action;
            public int seconds;
        };
 
        public List<payload> list;
 
        public NumberData()
        {
            list = new List<payload>();
        }
    }
}

Inhalt der Program.cs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;
using System.IO;
using Microsoft.WindowsMobile.Status;
 
namespace CallBlockerC
{
    class Program
    {
        static NumberData data;
        static string dataFile = @"numbers.txt"; // appended to appPath
        static string appId = "CallBlockerApp";
 
        [System.Runtime.InteropServices.DllImport("coredll.dll")]
        static extern void keybd_event(byte bVk, byte bScan, int dwFlags, int dwExtraInfo);
 
        static void Main(string[] args)
        {
            // setup path information
            string appPath = Path.GetDirectoryName((System.Reflection.Assembly.GetExecutingAssembly().GetModules())[0].FullyQualifiedName);
            dataFile = appPath + @"" + dataFile;
 
            string commandLine = (args.Length > 0) ? args[0] : ""; // (System.Reflection.Assembly.GetExecutingAssembly().GetModules())[0].FullyQualifiedName;
            bool disable = commandLine.IndexOf("Deaktivieren") >= 0;
            bool enable = commandLine.IndexOf("Aktivieren") >= 0;
 
            // always disable - just as a hack
            SystemState.DisableApplicationLauncher(appId);
 
            {
                SystemState ss = new SystemState(SystemProperty.PhoneIncomingCall, false);
                ss.EnableApplicationLauncher(appId); //, (System.Reflection.Assembly.GetExecutingAssembly().GetModules())[0].FullyQualifiedName);
 
                ss.Changed += new ChangeEventHandler(HandleCall);
            }
            if (disable)
            {
                SystemState.DisableApplicationLauncher(appId);
            }
 
            // get phone number data
            data = new NumberData();
            read();
        }
 
        static void read()
        {
            // reset all
            //data.enabled = 0;
            data.list.Clear();
 
            // read
            try
            {
                StreamReader sr = File.OpenText(dataFile);
                string strRead;
                //if ((strRead = sr.ReadLine()) != null)
                //    data.enabled = int.Parse(strRead); //.Contains("1")?1:0;
                while ((strRead = sr.ReadLine()) != null)
                {
                    string[] sarr = strRead.Split(' ');
                    if (sarr.Length == 3)
                    {
                        NumberData.Payload pl = new NumberData.Payload();
                        pl.action = (NumberData.eActions)int.Parse(sarr[0]);
                        pl.number = sarr[1];
                        pl.seconds = int.Parse(sarr[2]);
                        data.list.Add(pl);
                    }
                }
                sr.Close();
            }
            catch (Exception)
            {
            }
        }
 
        public static void HandleCall(Object obj, ChangeEventArgs arg)
        {
            System.Threading.Thread.Sleep(100);
 
            {
                object o = SystemState.GetValue(SystemProperty.PhoneIncomingCallerNumber);
                if (o != null)
                {
                    string PhoneNumber = o.ToString();
 
                    PhoneNumber = makeNumberJust(PhoneNumber);
 
                    foreach (NumberData.Payload pl in data.list)
                        if (pl.number.Equals(PhoneNumber))
                        {
                            switch (pl.action)
                            {
                                case NumberData.eActions.accept:
                                    System.Threading.Thread.Sleep(pl.seconds * 1000);
                                    AcceptCall();
                                    break;
                                case NumberData.eActions.acceptandend:
                                    AcceptCall();
                                    System.Threading.Thread.Sleep(pl.seconds * 1000);
                                    EndCall();
                                    break;
                                case NumberData.eActions.reject:
                                    System.Threading.Thread.Sleep(pl.seconds * 1000);
                                    EndCall();
                                    break;
                            }
                        }
                }
            }
        }
 
        static string makeNumberJust(string s)
        {
            return s.Replace("(", "").Replace(")", "").Replace(" ", "").Replace("-", "").Replace("+", "00");
        }
 
        const byte VK_TTALK = 0x72;
        const byte VK_END = 0x73;
        const int KEYEVENTF_KEYPRESS = 0x0000;
        const int KEYEVENTF_KEYUP = 0x0002;
 
        static void AcceptCall()
        {
            SendKey(VK_TTALK);
        }
 
        static void EndCall()
        {
            SendKey(VK_END);
        }
 
        static void SendKey(byte key)
        {
            keybd_event((byte)key, 0, KEYEVENTF_KEYPRESS, 0); // key press
            keybd_event((byte)key, 0, KEYEVENTF_KEYUP, 0); // key release
        }
    }
 
    class NumberData
    {
        public enum eActions
        { accept, acceptandend, reject };
 
        //public int enabled;
        public class Payload
        {
            public string number;
            public eActions action;
            public int seconds;
        };
 
        public List<payload> list;
 
        public NumberData()
        {
            list = new List<payload>();
        }
    }
}



Download der Videos
Die ersten 4 Videos noch einmal auf megaupload. Zum Download läßt sich z. B. sehr gut JDownloader verwenden.
http://www.megaupload.com/?d=IVHJ6VVV
http://www.megaupload.com/?d=HRPLBS3R
http://www.megaupload.com/?d=NYJ9F4J7
Direkt auf der blip.tv Seite kann man sich die Videos auch anschaun:
http://blip.tv/file/4845973
http://blip.tv/file/4845992
http://blip.tv/file/4846016



Download der Videos
Alle Videos noch einmal auf megaupload. Zum Download läßt sich z. B. sehr gut JDownloader verwenden.
1.-4.
http://www.megaupload.com/?d=RCCZ4J1W
http://www.megaupload.com/?d=0JA7AZA3
http://www.megaupload.com/?d=5KGB3TSD
http://www.megaupload.com/?d=6NPMSWPG
5.-7.
http://www.megaupload.com/?d=IVHJ6VVV
http://www.megaupload.com/?d=HRPLBS3R
http://www.megaupload.com/?d=NYJ9F4J7
Direkt auf der blip.tv Seite kann man sich die Videos auch anschaun:
1.-4.
http://blip.tv/file/4846322
http://blip.tv/file/4845881
http://blip.tv/file/4845895
http://blip.tv/file/4845940
5.-7.
http://blip.tv/file/4845973
http://blip.tv/file/4845992
http://blip.tv/file/4846016
Download der Projekte
Deutsche Lösung für Visual Studio 2008 und Windows Mobile 6 in C#
Englische Solution für Visual Studio 2008 und Windows Mobile 6 in C# – nicht aufgeräumt, mit Debug und Release Installer

Alternativ gibt es auch noch den iSecretary, von dem ich aber nicht weiß, wie er gerade vermarkter wird/ob er jetzt Freeware ist, die offizielle Seite ist wohl geschlossen.

Freue mich immer über Anregungen in den Kommentaren!

One thought on “Windows Mobile 6 Applikation als Anruf-"Firewall" in C# Teil 2/2

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.