Wednesday, December 20, 2006
Alpha Blending on SmartPhone
The tool I am using to record the video is called CoolCapture (I'm using the trial version here). It's very cool. It's essentially a fully featured screen capture tool for Windows Mobile 5 devices. You can generate both videos or pictures. I was fairly impressed with the performance as well; capturing these two videos below only resulted in about a ~6 fps reduction in my animation (thus the blending doesn't look as smooth as it actually is). The trial version limits the recording interval to ~10 seconds (though the webpage says 5 seconds).
Note that the capture resolution was 240x320 (the device resolution); however, this was automatically changed to 640x480 when I uploaded the video to YouTube. This is why the videos have that stretched out look.
Wednesday, December 13, 2006
2125 ActiveSync Internet Pass Through
1) Open ActiveSync on your computer, select File->Connection Settings. In the ComboBox below "This computer is connected to:" make sure "The Internet" is selected.
2) In PIE, select Tools->Options->Connections. Then, select "The Internet" as your network.
Now, I'm going to see if my own app can do this.
Tuesday, December 12, 2006
Link to Files in VS2005
I would prefer to not create a duplicate of this file as maintaining changes between the two copies can be time consuming and error prone. Fortunately, Visual Studio 2005 has a great feature to allow for file sharing between projects -- you can add an existing file as a link. Here's how:
1. In the project where you wish to add the file, right click the project name in the Solution Explorer
2. Select Add and then Existing Item...
3. In the Add Existing Item dialog, navigate to the desired file
4. Click the downward pointing arrow next to the Add button and select Add As Link.
Once added to a project, linked files are easy to identify by the small arrow in the lower-left corner of the file icon in the Solution Explorer.
Sunday, November 19, 2006
Measuring CPU Load
Note, it appears that the pps tool from http://www.xs4all.nl/~itsme/projects/xda/tools.html might do the trick. Further investigation is needed.
Monday, November 13, 2006
Cannot Create Native C++ Projects
This problem is due to the New Project dialog not playing nice with the changes in Internet Explorer 7 (the New Project dialog for native projects is actually a glorified web browser control).
The workaround is simple - Open the registry entry:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Ext\PreApproved
Add a new entry and name it
{D245F352-3F45-4516-B1E6-04608DA126CC}
Again this is something we have fixed for Visual Studio 2005 SP1.
(link)
Update 11/13/2006 2:50PM: Note: this did not work for me. I am currently installing the Visual Studio 2005 SP1 Beta release; hopefully this fixes the problem as well.
Update 11/13/2006 6:50PM: VS2005 SP1 Beta works!
Tuesday, November 07, 2006
SQL Server Everywhere Renamed
(link)
Thursday, September 28, 2006
Platforms for .NET CF 2.0
- PocketPC 2003 & PocketPC 2003 SE
- PocketPC 2005 (or 5.0)
- SmartPhone 2005 (or 5.0)
- WindowsCE 5.0
WindowsCE vs. Windows Mobile
Windows CE is a customizable, embedded operating system for a variety of small-footprint devices. OEMs can use Windows CE to design platforms and customize applications to maximize the user experience for devices such as handhelds, thin clients, logic controllers, and advanced consumer electronics.
Windows Mobile is a complete software platform built on Windows CE. Unlike Windows CE, the Windows Mobile Smartphone and Pocket PC operating systems are specifically designed for devices that require a specialized hardware configuration. The software includes standardized interfaces and applications that ensure compatibility across hardware designs. For more information, visit the Windows Mobile Web site.
(link)
Mike Hall adds his two cents here with regards to the above as well as Windows XP Embedded.
Thursday, September 14, 2006
Installing a Windows Mobile Application from Desktop
Tuesday, August 29, 2006
Appointment ListChanged Event
Has anyone been able to receive an event when you've registered to receive events from ListChanged?
Here is the code I'm using (I'm using VS 2005 RC1 with CF 1.0):
OutlookSession outlook = new OutlookSession();
outlook.Appointments.Items.ListChanged += new
ListChangedEventHandler(Items_ListChanged);
This code runs just fine, but changing the calendar doesn't fire this event in my application. I've searched the net, but haven't found anyone who appears to have used it.
Peter Foot, from InTheHand fame, then responded:
I haven't checked, but it's possible that the events in Microsoft.WindowsMobile.PocketOutlook only fire when the changes are made through these APIs not when changed from another application...
The original poster, however, corrected Peter with information from the MSDN docs:
Here's what the docs say:
"Occurs when either the collection changes, or when an individual PIM item in the collection changes."
Additionally, the MSDN article "What's New for Developers in Windows Mobile 5.0" says that you can track changes made to Pocket Outlook folders using managed code and gives an example, so it sounds like it should show changes made by other applications. As far as I can tell, that's the whole idea, in fact.
But I can't get it to trigger any events.
SystemState CalendarAppointment Events Seem Very Broken
For the most part, I've had good experiences with the new Microsoft.WindowsMobile.Status.SystemState infrastructure in .NET CF 2.0. However, recently I've run up against numerous issues with the CalendarAppointment* and CalendarNextAppointment* events. Incidentally, I've tested this on the I-Mate KJAM Pocket PC Phone as well as the Cingular 2125, T-Mobile SDA, and the I-Mate SP5m SmartPhones. It shouldn't be too hard to repo what I'm describing on your own device.
I will describe the problems in descending importance:
1. The SystemState calendar related events do not properly notify subscribers when the calendar appointment state changes. My impression of these system states is that an event will be fired throughout the day as a user's calendar appointments occur. I would say that in more than 90% of the cases, no event is triggered. I haven't been able to diagnose exactly why this is. The problem I'm describing here seems relevant for all calendar related events. For example,
private SystemState _stateCalendarAppointmentBusyStatus;
private void Init()
{
_stateCalendarAppointmentBusyStatus = new
SystemState(SystemProperty.CalendarAppointmentBusyStatus, true);
_stateCalendarAppointmentBusyStatus.Changed += new
ChangeEventHandler(OnStateCalendarAppointmentBusyStatusChanged);
ChangeEventArgs args)
{
AppendText(SystemProperty.CalendarAppointmentBusyStatus,
(BusyStatus)args.NewValue);
{
_textBox.Text += systemProperty + ": " + newValue + "\r\n";
2. At this point, I thought perhaps I misunderstood what the current calendar appointment events did particularly because I seemed to get events when I would go into the calendar and modify the current appointment. However, this isn't the issue. I setup a polling sensor that would, instead of relying on the events, constantly poll the calendar related system states. You can do this because calling SystemState.CalendarAppointment, for example, returns the current value of that system state. However, what I found through polling was that this system state was not actually changing. To test this out, setup a "refresh" button in your GUI or run a windows Timer object to spit out the current state of the CalendarAppointment* system states. Then, add 5 or 6 test appointments to your calendar that will occur over the course of the next 10 minutes. You'll note that the states don't actually change with the calendar appointments. I've found that the CalendarAppointment* and CalendarNextAppointment* seem to be particularly troublesome while CalendarHomeScreenAppointment* stuff works a little more frequently (though these events are much less useful to us).
3. Going back to using the system state events. Interestingly, the following code will sometimes throw a NullReferenceException because the args object passed in is null. Perhaps this makes sense--if the current appointment is deleted the BusyStatus switches from a known state to a null state--however, this is underdocumented. An unsavvy programmer could easily fail to null check the ChangeEventArgs argument.
private void OnStateCalendarAppointmentBusyStatusChanged(object sender,
ChangeEventArgs args)
{
AppendText(SystemProperty.CalendarAppointmentBusyStatus,
(BusyStatus)args.NewValue);
UPDATE 09/11/2007: I received word from Microsoft today that this is indeed a bug in WM 5.0. Direct quote from the Microsoft employee, "I’ve confirmed the bug on WM 5.0, but it seems to be fixed in WM 6.0. That is, that the Notification Broker (and associated registry settings) don’t update properly when the calendar changes."
Friday, August 25, 2006
Issues with SystemState.Date
The first relates to SystemProperty.Date. Subscribing to the SystemProperty.Date results in a ChangedEventArgs object with the wrong value type, or, at least a value type that is inconsistent with documentation. Even the SystemState.Date type (which is of type System.DateTime) would leave you to believe that the ChangedEventArgs.NewValue object would be of type DateTime. In this case, however, it's actually a byte array of length 8. We believe this represents milliseconds in UTC time (8 bytes in C# is a long type). See this Date and Time article at MSDN for more on working with date and time. This typing issue results in a InvalidCastException in the following code.
private SystemState _stateDate;
cstr(){
_stateDate = new SystemState(SystemProperty.Date);
stateDate.Changed += new ChangeEventHandler(OnStateDateChanged);
}
private void OnStateDateChanged(object sender, ChangeEventArgs args){
//The code below will throw an exception as the args.NewValue type is actually
//a byte array of size 8! This is undocumented and unexplained.
DateTime date = ((DateTime)args.NewValue);
}
I have not comprehensively explored this issue. Other than the fact that the arg.NewValue is a byte array of length 8, I cannot elaborate. It is only conjecture that args.NewValue here is a timestamp in milliseconds at UTC. Regardless, it seems to contradict documentation and go against the paradigm established by other SystemState functions.
One final note about this state. The SystemState.Date docs say:
Gets the current date. This Date/Time value changes once per day. Monitor this property to perform actions on a daily basis. Do not use Date to get an accurate clock time; instead, use Time.
The documentation does not explicitly point out the strategy or time of day that SystemState.Date changes, only that it changes daily. I had hoped that it would change at midnight each and every day; however, what we found was that SystemState.Date appeared to change at midnight GMT (or 5PM PST). So, even if you were to schedule a daily routine with this property, it wouldn't necessarily be at the beginning of the day. Given this limitation, we decided to roll our own SystemState.Date event class that fires at midnight each day.
If I get a chance this weekend, I'd like to follow up this post with the problems we've experienced at my lab with the SystemState.CalendarAppointment* properties. They don't appear to change at all no matter what the calendar/appointment structure is like on the phone.
Update February 9th, 3:15AM: My suspicions about the 8-byte array were somewhat correct. It is a representation of DateTime. This is how you properly convert the byte array to a DateTime object:
byte[] rawValue = SystemState.GetValue (SystemProperty.Time) as byte[];
long value = BitConverter.ToInt64 (rawValue, 0);
DateTime time = DateTime.FromFileTime (value);
Tuesday, August 22, 2006
Size Limit of SQL Server 2005 Mobile Database
Size limit of SQL Server Everywhere Edition database: 4 Gigabytes.
(link)
Monday, August 21, 2006
SqlCeParameter Bug?
The following SqlCeCommand throws an exception. Is this a bug or am I doing something wrong?
SqlCeCommand sqlCmd = sqlConn.CreateCommand();
sqlCmd.CommandText = String.Format("INSERT INTO {0} (UserId, VersionId, {1}, PropertyName, PropertyValue, PropertyValueType) VALUES (@userid, @versionid, @headercolumnval, @propertyname, @propertyvalue, @propertyvaluetype)", strTable, headerName);
String strValue = p.Value.ToString();
sqlCmd.Parameters.Add("@userid", SqlDbType.NVarChar, 255, "UserId").Value = Globals.UserId;
sqlCmd.Parameters.Add("@versionid", SqlDbType.BigInt, 8, "VersionId").Value = Globals.VersionId;
sqlCmd.Parameters.Add("@headercolumnval", SqlDbType.NVarChar, 255, headerName).Value = headerColumnValue;
sqlCmd.Parameters.Add("@propertyname", SqlDbType.NVarChar, 255, "PropertyName").Value = p.Key;
sqlCmd.Parameters.Add("@propertyvalue", SqlDbType.NVarChar, 4000, "PropertyValue").Value = strValue;
sqlCmd.Parameters.Add("@propertyvaluetype", SqlDbType.NVarChar, 255, "PropertyValueType").Value = p.Type.FullName;
sqlCmd.Transaction = sqlTransact;
sqlCmd.Prepare();
sqlCmd.ExecuteNonQuery();
sqlCmd.Dispose();
Throws the following exception at the sqlCmd.ExecuteNonQuery() line:
System.InvalidOperationException was unhandled
Message="@propertyvalue : String truncation: max=255, len=463, value="(removed for posting clarity)"."
StackTrace:
at System.Data.SqlServerCe.SqlCeCommand.FillParameterDataBindings()
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommandText()
at System.Data.SqlServerCe.SqlCeCommand.ExecuteCommand()
at System.Data.SqlServerCe.SqlCeCommand.ExecuteNonQuery()
at MyExperience.IO.DatabasePopulator.InsertProperty()
at MyExperience.IO.DatabasePopulator.ParseTriggers()
at MyExperience.IO.DatabasePopulator.Populate()
at MyExperience.MyExperienceFramework.Initialize()
at MyExperience.Application.MainForm.OnLoad()
at System.Windows.Forms.Form._SetVisibleNotify()
at System.Windows.Forms.Control.set_Visible()
at OpenNETCF.Windows.Forms.Application2.RunMessageLoop()
at OpenNETCF.Windows.Forms.Application2.Run()
at MyExperience.Application.Program.Main()
However, if I change the line:
sqlCmd.Parameters.Add("@propertyvalue", SqlDbType.NVarChar, 4000, "PropertyValue").Value = strValue;
to
sqlCmd.Parameters.Add("@propertyvalue", SqlDbType.NVarChar).Value = strValue;
no exception is thrown and, better yet, the full amount of data actually makes it into the database. That is, the value is not truncated to the 255 length that Sql somehow thinks exists as a constraint.
Note that my schema for this table looks like:
TableName:
TriggerProperties
Columns:
UserId (PK, nvarchar(255), not null)
VersionId (PK, nvarchar(255), not null)
TriggerName (PK, nvarchar(255), not null)
PropertyName (PK, nvarchar(255), not null)
PropertyValue (nvarchar(4000), not null)
PropertyValueType (nvarchar(255), not null)
I followed this post up with this one on August 18th:
Ah, it looks like SqlCeParameter forces the Size property to 255. That's strange given the fact that the docs say, as previously mentioned, that the nvarchar data type can range from 1 to 4000 characters.
However, bear in mind, that by simply avoiding setting the Size property (either via the constructor or the property itself) allows one to INSERT nvarchar data much larger than 255. In other words, it looks like this "bug" is at the parameter level and not database level.
This is the test code:
for (int i = 0; i <= 500; i+=100){ SqlCeParameter param = new SqlCeParameter("@Test", SqlDbType.NVarChar, i); Debug.WriteLine(i + ": " + param.Size);
//Just in case the property acts differently, set it and print again
param.Size = i;
Debug.WriteLine(i + ": " + param.Size);
}
0: 0
0: 0
100: 100
100: 100
200: 200
200: 200
300: 255
300: 255
400: 255
400: 255
500: 255
500: 255
Any input from MS (or MVPs) on this? I'm far from being a seasoned C# SQL developer so maybe I'm doing something wrong.
Unfortunately I haven't heard any substantive comments back on usenet from MS or otherwise. Anyone in the blogosphere have an idea?
Update 8/25/2006 @ 11:08PM: On August 21st, I e-mailed the SQL Server Everywhere team via their contact page about this issue. Here's what I said:
Not sure how appropriate it is to contact you about problems I'm experiencing with Sql Mobile 2005, but I thought I'd give this a shot. If this is the wrong venue of communication, just ignore this plead for help.I'm having issues with the SqlCeParameter class, particularly with regards to how it handles setting the Size property. I can't seem to set the size to anything larger than 255 for the nvarchar datatype.
Please see my usenet post for more details (unfortunately no one with any expertise in this area has responded yet): direct link here
I received a response on August 24th:
Yes Jon you are right that there seems to be some problem with larger than 255 chars. I just tried and could repro it.
I shall come back to you on this after some more digging around to see if there is any work around.
To which I responded:
Thank you so much for the response. I was really hoping I'd hear back from someone at Microsoft to help me with this.
The work around that I've come up with is to simply leave out specifying the length parameter in the SqlCeParameter object. So, for my SQL data columns that are of type nvarchar and length > 255 I do this:
SqlCeParameter param = new SqlCeParameter("@custid", SqlDbType.NVarChar);
Rather than explicitly including a length and column:
SqlCeParameter param = new SqlCeParameter("@custid", SqlDbType.NVarChar, 2000, “CustomerID”);
You’ll note that in the former case your data can be of length > 255 and, critically, it will still make it into the database. In the latter case, however, you incur an exception.
Perhaps my workaround will shed some light on the underlying problem.
On August 25th I received another response:
I found the work around you used works perfectly and some of the internal apps also use it the same way as you mentioned. However, while digging I found that you can not use parameterized query when you have image/ntext columns (Large Object Datatype). Will update you more once I get some clarity.
To which I responded:
Hmm, I also use image data types in my SQL Mobile 2005 database and it appears to be working. In fact, a parameterized query, I believe, is the only way to get binary data into the database. What was the issue you ran into here?
Saturday, August 19, 2006
Nullable Types
More on the C# 2.0 Nullable Types
Jon Skeet's Blog : Elegant comparisons with the null coalescing operator
Jon Skeet's Blog : Nullable types and the null coalescing operator
MSDN Reference : ?? Operator (C# Reference)
MSDN Reference : Nullable Types (C# Programming Guide)
Friday, August 18, 2006
Recently Published Mobile Device Downloads
Hard Reset T-Mobile SDA
Update 08/26/2007: I couldn't get this to work on my Cingular 2125 device. I finally figured out what I was doing wrong; I held down the power button too long. You do not need to hold the power button down until you see the boot screen... simply press it for 0.5-1 seconds. Also, Mike Poulson points out there are two ways to reset the HTC Torando/Faraday-based SmartPhone.
The first way requires you to be able to boot the phone and get to the start menu. The second is if you cannot do this (i.e., forgot PIN or will not boot all the way).
First way:
Second way:
1. Remove Battery
3. Hold down right and left soft keys
4. Press Power button for ~1.45 seconds then release Power button only
5. Confirm prompt to reset
Monday, August 14, 2006
Usage of SqlCeCommand.Parameters
I'm curious about the Parameters property in SqlCeCommand. Is this the preferred/best usage of the SqlCeCommand object? I suppose one benefit of using Parameters is the ability to set binary/image data (as those are byte arrays) for insertions/updates. Are there other benefits? I tend to format all of my command statements like the following:
SqlCeCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = String.Format("INSERT INTO {0} (ActionName,
ActionType) VALUES ('{1}', '{2}')", "Actions", actionName, actionType);
cmd.Transaction = sqlTransact;
cmd.ExecuteNonQuery();
instead of
SqlCeCommand cmd = sqlConn.CreateCommand();
cmd.CommandText = "INSERT INTO @tablename (ActionName, ActionType)
VALUES (@actionname, @actiontype)";
cmd.Parameters["@tablename"].Value = "Actions";
cmd.Parameters["@actionname"].Value = actionName;
cmd.Parameters["@actiontype"].Value = actionType;
cmd.Transaction = sqlTransact;
cmd.ExecuteNonQuery();
Ilya Tumanov, a member of the .NET Compact Framework Team, responded with:
Yes, parameterized query is a preferred way. Benefits are:
- No need to create bunch of string objects all the time (in your code).
- No need to convert parameters from binaries to strings (in your code).
- No need to parse strings to get binaries back (in SQL CE).
- No locale/format specific issues as binary is format less and locale independent.
- No need to redo each command from scratch, prepared execution plan can be used with just different parameters.
- Works for all data types including binary/image.
(link)
Update 08/16/2006 12:57AM: I followed up the above post with:
Thanks so much for this thorough response--it clarified much for me. One follow-up question, what do you mean by "No need to redo each command from scratch, prepared execution plan can be used with just different parameters?" This is most certainly my naivete here with respect to SQL; a short elaboration would probably suffice.
Illya once again responded:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sqlc...
Preparing Commands
To be able to execute a query, the database engine must first parse, compile, and optimize the SQL statement. Often, this work can be done once if the command is to be executed multiple times, potentially saving time. If clients expect to run a query more than once, it is recommended that the command be prepared once, then call Execute multiple times. This should maximize performance by avoiding query recompilation. Commands can be prepared prior to execution by calling ICommandPrepare::Prepare. This is equivalent to compiling the command.
Friday, August 11, 2006
Reduce Size of .NET Executables
The technique we used for compressing .NET applications does not work with .NET Compact Framework (CF) [17]. The .NET CF does not implement the methods of the Assembly and AppDomain classes that make this technique possible. However, the devices that run .NET CF use compression by default for storing programs and data in the non-volatile device memory ([17] reports up to 2:1 compression ratio). This means that this technique may not be directly needed in .NET CF devices9.
[17] P. Yao and D. Durant. .NET Compact Framework Programming with C#. Addison Wesley, 2004.
Monday, July 31, 2006
SQL Mobile Size Limit
The limit for a SQL Mobile database is 4 gb, so unless my math is wrong, you shouldn't have any problems at all with 80,000 records of that size assuming you enough space on the device. I have a production app that handles 65,000 records and on a mobile device seeking to a unique key using the table's index is almost instantaneous. One thing I have found with big databases is that sometimes queries get very slow because the query processor apparently wants more memory for its own work than I have available. I've been able to reduce a 30-minute query to well under a second by switching from using SQL syntax to TableDirect in situations like that.
One other point with large amounts of data - don't try to load all that data into a DataSet. Use SqlCeResultSet and only load the data you need at any given point in your app.
VS2005 Debugging Problem, Breakpoints AutoDisabling Themselves
My colleague is having problems debugging in VS2005. When he sets
breakpoints in his code and launches his application via Debug->Start
New Instance, the breakpoints autodisable themselves and the
"breakpoint icon" switches from being filled in to outlined with a
warning glyph on the bottom right hand corner. When moused-over, the
icon reads "The breakpoint will not currently be hit. The specified
module is not being loaded." I checked the loaded modules list via the
Debug->Windows->Modules interface and the specified module was, indeed
loaded, with a pointer to a valid pdb (as far as I can tell).
I even started a brand new Form application from scratch and ran it in
debug mode without adding any new code. I set a breakpoint at the first
line in Program.cs but this too was autodisabled with the same "module
is not being loaded" warning.
I Googled around the newsgroups/web for a while but did not find
anything that directly related.
System.Diagnostics.Debugger.Breakpoint() works as does Debug->Step Into
new instance.
Thursday, July 27, 2006
Benchmarking StringBuilder vs. String
In the following article I will show you the numbers for StringBuilder vs String which I did measure with .NET 2.0 a P4 3.0 GHz and 1 GB RAM. Every test was performed 5 million times to get a stable value. (link)
I wonder if the same performance would be observed on Windows Mobile Devices.
Wednesday, July 26, 2006
Saturday, July 15, 2006
TextBox OnPaint in .NET CF 2.0
SqlServer Mobile Edition, In-Proc Database
On Sriram Krishnan's blog he writes, "Sql Mobile is a super-lightweight, in-proc database that runs on devices. The key phrase for me personally is 'in-proc'. This means that there is no IPC involved and as a result, performance is blindingly fast."
This is really the only discussion I could find about in-proc databases via a quick Google search. Can anyone provide me with any more information on what an "in-proc database" is and how it differs from an "out-of-proc?" database. The implication of Sriram's post is that SqlMobile is efficient because it doesn't use interprocess communcation (assuming that's what IPC stands for). Do most databases use IPC?
(direct link)
(Update: 07/16/2006 1:37PM) I received the following response from Ginny Caughey, a Device Application Development MVP.
Some databases such as SQL Server run as services in their own process space, often on a different machine from the apps that consume those services. Others such as SQL Server Everywhere/SQL Mobile are DLLs that run in the same process space as the application that uses them. Not only does this imply that there is no process boundary to impact perforamance, but also when the hosting application ends, so does the database engine so there is no service running to serve as a potential security threat. There are advantages to client/server databases such as SQL Server, but for stand-alone and mobile apps, there are also advantages for an in-process database such as SQL Mobile/Everywhere.
(direct link)
Thursday, July 06, 2006
Purchased OpenNetCF SDF 2.0
Oh and by the way, the installer for the purchased version of SDF 2.0 takes about 15 minutes on my 3Ghz HT 1.5GB RAM Pentium 4 machine to complete. I was almost going to e-mail support that their installation package was broken but then I discovered the h2reg process, which is started by the installer, was just taking forever. I believe this is because of some of the integrated VS2005 stuff they've done in SDF 2.0. Note that the free version installs rather quickly.
Tuesday, July 04, 2006
ActiveSync, A Lesson Learned
Now, I'm not 100% confident that this will solve all of my ActiveSync issues but it appears that, at the moment, I've figured out the connection problem.
Sunday, July 02, 2006
ActiveSync Connection Problems Continue
My laptop will not connect to any of my WM 5.0 devices (including the i-mate KJAM, the Cingular 2125, and the T-MOBILE SDA). Though I've experienced this problem in the past, I've been able to uinstall and reinstall ActiveSync 4.2 and restart my computer to solve the problem.
I've been blogging about my problematic encounters with ActiveSync for a while now but have never sought the expertise of this newsgroup. I'll provide a quick summary of my ActiveSync issues here. You can visit my blog for more details: http://csharponphone.blogspot.com/2006/05/activesync-41-sit-spin.html
Basically, I plug-in my WM 5.0 device, the little networking animation starts up in the taskbar (and says acquiring network address, etc.). This icon dissapears and then the ActiveSync icon in the taskbar turns green and starts to spin. This continues until a timeout is reached at which point I'm given a choice of visiting Microsoft's troubleshooter webpage (it then forwards me on to the "If ActiveSync Cannot Receive Data Through Port 990" page). I've tried following all of the previous advice posted here and on the web, but to no avail. My laptop is running Windows Firewall and McAfee VirusScan Enterprise 8.0.0.
Any help from MVPs, Microsoft employees, or anyone with a clue into what might be happening would be much appreciated.
NETSTAT RETURNS:
Active Connections
Proto Local Address Foreign Address State
TCP 127.0.0.1:1150 127.0.0.1:1151 ESTABLISHED
TCP 127.0.0.1:1151 127.0.0.1:1150 ESTABLISHED
TCP 192.168.2.76:1038 64.233.167.125:5222 ESTABLISHED
IP-CONFIG RETURNS:
Ethernet adapter Local Area Connection 16:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Windows Mobile-based Device #14
Physical Address. . . . . . . . . : 80-00-60-0F-E8-00
Dhcp Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : No
IP Address. . . . . . . . . . . . : 169.254.2.2
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . :
DHCP Server . . . . . . . . . . . : 169.254.2.1
Lease Obtained. . . . . . . . . . : Sunday, July 02, 2006 1:53:41 PM
Lease Expires . . . . . . . . . . : Tuesday, August 01, 2006 1:53:41 PM
Update: 07/04/2006 11AM: Here's my follow-up to the post above:
I'm ashamed to admit this, but it never occurred to me to check my
process list to see if there was any networking software running on my
computers that I did not know about. Imagine my surprise when I saw
blackd.exe (part of the BlackICE firewall package). As soon as I
noticed this, I figured this might be the root of my problem. It seems
the company that I work for includes a custom install of the BlackICE
installation with their VPN software. I force closed the process in
Task Manager, plugged in my WM 5.0 device and, what do you know,
ActiveSync turns green immediately and says connected.
I probably would have thought of this earlier on, but ActiveSync would
occassionally work--it wasn't a consistent problem. This maybe more an
issue with BlackICE however.
Unfortunately, the install of BlackICE that I have does not include a
frontend, so I must manually edit their configuration file to open the
ActiveSync related ports (despite warnings in the file itself against
it).
So, in the end, it appears my frustration was misdirected at Microsoft.
It really should have been at my IT department for not disclosing that
BlackICE was packaged with our VPN.
Hopefully now my ActiveSync problems are solved.
Two Inch View
Friday, June 30, 2006
Microsoft Bluetooth Stack
Friday, June 23, 2006
.NET CF 2.0 SP1 Released
Download it here.
Thursday, June 22, 2006
Sql Server 2005 Mobile
Tuesday, June 13, 2006
More ActiveSync Woes
Ah, ActiveSync, how you destroy my workday efficiency.
Update (07/12/2006 11:00AM): OK, thanks to Sriram's feedback (see Comments), I figured this out. Here are the steps (click on the images to see full size screenshots).
Step 1: Open Device Emulator Manager in VS2005 (Tools->Device Emulator Manager)
Step 2: Right click on your device of interest, start it.
Step 3: After the device has started, right click on the device again and select 'Cradle.' See Figure 1 below.
Step 4: The icon should change to represent that the device has been cradled. However, this does not necessarily mean that ActiveSync has actually connected to the device. See Figure 2 below.
Step 5: If ActiveSync has not actually connected to the device, yet the cradled icon is shown, open up ActiveSync, select File->Connection Settings. This will open up a Connection Settings Dialog. From there, click the Connect button. See Figure 3 below. This should find and connect your emulator device to ActiveSync.
Tuesday, June 06, 2006
Installation Error, Support Info: 4
I've been unable to successfully load a small test app I've written in VS2005 and .NET CF 2.0 (C#) for the i-mate K-Jam PocketPC Phone Edition.
The error that pops up on the K-JAM when deploying and debugging from VS2005, "Installation error. Stop all applications and processes and maximize available storage space, and run installation again. Support info: 4."
If I attempt to run the app by clicking on it in the file explorer on the K-JAM, I get the error, "This application (TestPocket.exe) requires a newer version of the Microsoft .NET Compact Framework than the version installed on this device." When I click details, I get:
TestPocket.exe
InvalidProgramException
I've tried this with the target device selected as both "Windows Mobile 5.0 Pocket PC Device" and "Windows Mobile 5.0 SmartPhone Device." I receive the same error in both cases.
Mark Prentice replied with a pointer to a working solution at his blog:
I’m happy to report the workaround for the system failure, which will be included in SP1, has now also been slipstreamed into the current download. If .NET Compact Framework v2 CAB installation on a Windows Mobile 5.0 device fails with error #4 then this fix is for you. Just re-download the NETCFv2 package and re-install!
Here's a link to the .NET CF 2.0 download.
Sunday, June 04, 2006
.NET CF Menu Item Size
Daniel Moth talks about a work around which involves modifying registry settings:
Menus (MainMenu, ContextMenu and MenuItem) are resized according to their Font. However, they do not expose a Font property, so you are stuck with whatever the default Font is for the platform. You can change that through the registry:
HKLM\Menu\BarFnt
DWORD "Ht" for height , DWORD "Wt" for boldness: 700 or 400
HKLM\Menu\PopFnt
same as above, but this applies to menu items rather than the menu bar
Friday, June 02, 2006
Params Keyword
The params keyword lets you specify a method parameter that takes an argument where the number of arguments is variable.
For example,
{
TestArgsMethod("Hello", " goodbye ", " hello");
TestArgsMethod("Numbers", 1, 2, 3, 4);
}
static void TestArgsMethod(String text, params Object[] args)
{
StringBuilder sb = new StringBuilder();
sb.Append(text);
foreach(Object o in args)
{
sb.Append(o.ToString());
}
Debug.WriteLine(sb.ToString());
}
Thursday, June 01, 2006
XmlReader and LineNumber
"According to the MSDN documentation within the XmlTextReader class for
.NET 2.0, the recommended practice to create XmlReader instances is
using the XmlReaderSettings class and the XmlReader.Create() method.
However, the problem is, the XmlReader class does not expose certain
properties that I need, e.g., LineNumber, LinePosition, etc. I would
like to follow Microsoft's recommended practices, but I'm not sure how
I can get XmlTextReader functionality out of XmlReader.
Should I instantiate a XmlTextReader object and pass this to the
XmlReader.Create() method and then access this underlying text reader
to obtain the info I need? Or is there some way to get the
XmlReader.Create() method to return a XmlTextReader object? Or should I
ignore there suggestion and simply create an XmlTextReader object
manually and not use the XmlReader.Create() method at all.
Update 07/12/2006 @ 1:03PM: Zafar Abbas responded with a solution,
The reader obtained via XmlReader.Create supports the IXmlLinfInfo interface
from which you can access the line properties:
reader = XmlReader.Create (...)
IXmlLineInfo info = reader as IXmlLineInfo;
Console.WriteLine(info.LineNumber);
Console.WriteLine(info.LinePosition);
Monday, May 29, 2006
Windows CE != Windows Mobile
Wednesday, May 24, 2006
Alpha Blending
Briefly, there are two ways to do alpha blending in WM5: the AlphaBlend() function and with the Image COM object in the Imaging API.
He then goes on to explain how to implement these two methods. (direct link). The happy alternative is offered through OpenNetCF (who else) in their SDF 2.0 library. See Alex Feinman's post here.
Transparency
ImageAttributes attr = new ImageAttributes();
attr.SetColorKey(Color.White, Color.White);
Rectangle rDest = new Rectangle(xImage, yImage, Image.Width, Image.Height);
g.DrawImage(Image, rDest, 0, 0, Image.Width, Image.Height, GraphicsUnit.Pixel, attr);
In this case, the color "white" would be made transparent in the given Image. Note that although SetColorKey allows the developer to specify a transparency color range, I believe that this range is limited to one color on .NET CF. During my search, I found that the standard chroma key is "bright pink." However, it's also convention to automatically select the chroma key based on the upper-left hand corner pixel of the image, in hopes that this is representative of the "background" pixels. Here's a post by Ed Kaim (MSFT) that really explains this well imo.
"However, the issue you're raising is why Microsoft recommends the usage of ImageAttributes in order to draw transparency, and why the top left pixel is called out as a prime source. First of all, ImageAttributes is the only feasible way to draw transparency in managed code on the .NET Compact Framework. Otherwise you'd have to go pixel by pixel and only draw the nontransparent ones, which would be slow and painful. The reason the top left pixel is offered is because it's often transparent in images with transparency. Sure, it's not *always* transparent, but it's usually transparent, due to its location in the image and the fact that most pictures on buttons don't go all the way to the top left border. However, you can decide that your standard chroma key color is bright pink (as many do) and hardcode your ImageAttributes object to use that color for all images, provided you do the work in the art to make sure the same exact color is used on the transparent spots in your files, whatever format they may be."
Monday, May 22, 2006
Retrieving an Assembly's PublicKeyToken
1. Open up the Visual Studio 2005 Command Prompt from the Start Menu. That should set the environment for using VS2005 commands.
2. C:\>cd "C:\Program Files\Microsoft Visual Studio 8\SmartDevices\SDK\SQL Server\Mobile\v3.0\"
3. Type "sn -T System.Data.SqlServerCe.dll"
The sn utility will return something like: Public key token is 3be235df1c8d2ad3
Note: if you do not include a capital T (but instead a lowercase, -t), you will receive the following error: "Failed to convert key to token -- The public key for assembly '(null)' was invalid."
ActiveSync 4.1, Sit & Spin
I've scoured the net for a solution and have found none. This has been happening off and on since I started working on Windows Mobile 5.0 devices. Unfortunately, I have not been able to diagnose the cause. Restarting the device does not solve the problem. Restarting the desktop (which I hate doing) does not solve the problem. Sometimes, moving the USB cable from one port to another works, but not always. I can waste a full hour or so simply trying to get my activesync connection up so I can debug my program. :(
Oh and the online KB has a few reported issues with regards to ActiveSync 4.1:
http://support.microsoft.com/kb/911422/en-us
http://support.microsoft.com/kb/912240/en-us
and, perhaps most relevant,
http://support.microsoft.com/kb/911423/en-us
Sadly, however, none of these quite get at the issue I am experiencing. This last link is closest but simply blames the problem on Windows Firewall (which I've disabled to see if it has any effect, it does not).
Update (05/22/2006 11:42AM): It appears that the ActiveSync 4.2 Beta Preview is now available and it comes with a USB troubleshooter. I'm going to try it now. See these two blog posts by Jason Langridge (here and here).
Update (05/24/2006 5:27PM): So far ActiveSync 4.2 has worked perfectly for me--I have not run into the "sit and spin" problem (or any problem) since upgrading.
Update (05/26/2006 1:59PM): Despite upgrading to ActiveSync 4.2 on my laptop, I still have the "sit & spin" problem when connecting to my Windows Mobile 5.0 devices. The horribly ironic thing is that the "USB troubleshooter" promised in ActiveSync 4.2 is actually just a webpage and not, say, a tool. This is so frustrating. I really can't imagine being the only one with this problem as its occurred on my desktop machines (both work, school and home) and laptop with a variety of WM 5.0 devices. I am not running any firewall except the Windows XP built-in firewall (and even when I disable it, ActiveSync still just sits there spinning).
Update (06/02/2006 9:07PM): I got my laptop to work again with ActiveSync. I uinstalled ActiveSync 4.2, restarted, and then reinstalled 4.2. Now things seem to be working for the moment. Incidentally, after this reinstall, I actually got the SmartPhone emulator to cradle via the Device Manager which has never worked for me properly. Note that my work desktop machine, which had a behaving install of ActiveSync 4.2 just stopped working today. However, like with my laptop, a full reinstall of 4.2 seemed to fix the problem.
Update (06/13/2006 10:21AM): Both my advisor and my mentor at work have run into the "sit & spin" problem. The solution of upgrading to 4.2 beta and restarting seems to solve the problem, but only temporarily. My advisor also tried to manually unblock all the ActiveSync ports in Windows Firewall; however, this did not seem to make a difference. As I've noted in the past, I've completely disabled Windows Firewall to try and debug the "sit & spin" problem and it's not made a difference, so his experiences are not surprising.
Update (06/13/2006 11:00AM): I want to reemphasize how I often solve the "sit & spin" problem as strange as it might sound. I have four USB ports on the back of my computer. If I encounter the feared continuously spinning green ActiveSync icon, I unplug my USB cord from the back of the computer and move it to another port while my WM 5.0 device is still connected to the other end. ActiveSync then appears to do some initialization (e.g., my tray shows off another icon that's animated) and then immediately connects properly. This only works for those ports in the back of my computer that have not yet had ActiveSync connections. Once I move the cord to all four ports, I must uninstall ActiveSync and start the process all over.
Update (07/02/2006 1PM): I spent a large amount of my Sunday morning and early afternoon determined once and for all to get to the bottom of the ActiveSync sit & spin problem. My laptop (Dell 710m) has Windows Firewall installed as well as McAfee VirusScan 8 and two USB ports. I tested both USB ports with two different USB cords and three different WM 5.0 devices (the i-Mate K-JAM, the Cingular 2125, and the T-Mobile SDA), all of which would not connect to my laptop, despite all efforts (see the sit & spin problem above). Once the green ActiveSync taskbar icon spins for a certain amount of time, a dialog (new to ActiveSync 4.2) asks me if I'd like to be forwarded to a troubleshooter webpage. If I select OK, I am forwarded to a page entitled "If ActiveSync Cannot Receive Data Through Port 990" (here) . The first three steps are trivial and meant to ensure that you have USB connections enabled both on the desktop and device (and yes I double and triple checked, everything looks fine in this regard). The last point (point 4), states that if I have an internet firewall, make sure its enabled to accept ActiveSync connections. Well, as previously stated, I only run Microsoft's Firewall program and upon examination, they do specifically allow connections from all ActiveSync related .exes. Just to ensure the firewall wasn't my problem, I turned it off but ran into the same problem. Finally, I uninstalled ActiveSync 4.2 and reinstalled it as directed by the USB troubleshooter here (step 9). Unfortunately, though this has worked for me in the past, uninstalling ActiveSync and rebooting my devices and desktop did not solve the problem. So, now I'm stuck. No ActiveSync and no solution. I did find a set of relatively helpful links though for ActiveSync troubleshooting (the fact that there is a community formed around this problem should say something to Microsoft, no?). Here are the links:
1. ActiveSync 4.X Troubleshooting Guide - Connection Flow - provides a very thorough look at ActiveSync issues with respect to establishing a connection (by Chris De Herrera)
2. ActiveySync 4.X Troubleshooting Guide - Firewall, VPN, Proxy Issues (also by Chris De Herrera)
3. Bev Howard's Solving ActiveSync Issues
4. TCP ports required by ActiveSync (I found this the first day I experienced the sit & spin problem, but since tweaking these ports in Windows Firewall never solved anything I never linked to it. I do so for thoroughness now).
5. ActiveSync 4.0/4.1 TroubleShooter Guide
6. The ActiveSync Troubleshooter (which 4.2 dynamically links to when a problem is encountered)
I have not seen an outpouring of complaints on the newsgroups about this problem, though this post is one of the most actively visited on my website so presumably others are encountering it as well. By a rough estimate, I figure the Microsoft ActiveSync development team owes me about 20 hours of my time (perhaps more) based on this problem alone. Others at my research lab have also spent countless hours trying to get their WM 5.0 devices to connect to ActiveSync. Now, as computer scientists we are used to tooling around and debugging programs as well as fault-prone systems. We typically can navigate around these problems. However, if ActiveSync 4.X is broken (and, imo, it is very f*ing broken) it have dramatic implications for the userbase of our WM 5.0 product. If our users can't sync their devices, then they can't (#1) install our application and (#2) use the desktop side of our application.
Update (07/02/2006 8PM): I made a post to the microsoft.public.pocketpc.activesync newsgroup about this problem (here). I also copied the post to my blog here.
Update (07/04/2006 11AM): It appears that my ActiveSync Sit & Spin issue has been resolved and in bit of probably all too common misplaced blame, it was not the fault of Microsoft as I suspected. See here and here.
Wednesday, May 17, 2006
Tuesday, May 16, 2006
Simkin# (or SimkinCS if you will)
Here's a screenshot of SimkinCS running in .NET in a demo app. Click on the picture for a larger view. You can download this proof-of-concept application here.
(left: before execution, right: after execution)
Update (May 17th, 2006 @ 2:02PM): You need the .NET 2.0 runtime environment to run this application. You can download the .NET 2.0 redistributable package here. This is the reason why the application fails to run and returns the error "The application failed to initialize properly (0xc0000135)" on some systems. My guess is, though, if you read this blog you likely have .NET 2.0 installed on your machine.
Tuesday, April 25, 2006
Buggers, Scripting Support in .NET CF 2.0
Hopefully someone will get around to answering this post.
Monday, April 24, 2006
Cingular 2125 Developer Locked
Genius!
Tuesday, April 11, 2006
Primary Key Efficiency
Also, from link, "A primary key is an attribute (or combination of attributes) that uniquely identify each instance of an entity. A primary key cannot be null and the value assigned to a primary key should not change over time. A primary key also needs to be efficient. For example, a primary key that is associated with an INTEGER datatype will be more efficient than one that is associated with a CHAR datatype. Primary keys should also be non-intelligent; that is, their values should be assigned arbitrarily without any hidden meaning. Sometimes none of the attributes of an entity are sufficient to meet the criteria of an effective primary key. In this case the database designer is best served by creating an "artificial" primary key."
Monday, April 10, 2006
Multiple Columns as Primary Key?
Here are a few links.
1. "Primary Key" (Google Groups).
2. "Design: multiple columns for primary key" (Google Groups)
3. "SQL Server Performance Questions & Answers" (in favor of IDENTITY columns)
Adding Foreign Keys to .SDF via VS2005
"You can't add a foreign key to a SQL Mobile database from within VS2005 - you cannot do it graphically nor by using the query designer (where it would be tempting to enter an ALTER TABLE .. ADD FOREIGN KEY statement).
In the absence of SQL Server 2005 Management Studio in your situation, you will need to run the ALTER TABLE command either from your program code or inside of Query Analyzer 3.0 on device."
(link)
Sunday, April 09, 2006
SqlCeConnection Keep Connection Open?
- SqlCeConnection guidelines (MSDN Forums)
- Performance with SqlCeConnection (Usenet)
- Data Architecture & Pooling (Usenet) <- this is for SqlServerCe 2003
Creating and destroying SQL Mobile database connections is an expensive task and so the SqlCeConnection is designed to be a long lived, shared instance across the lifetime of the application. For a complex app, ideally the SqlCeConnection instance would be placed in a singleton wrapper class that manages access to the database.
Though this information comes from a Microsoft employee, it still seems contentious. Dave Hayden, a MS MVP, said in this MSDN forum post:
For 99% of all applications, the best practice is to open and dispose of database connections right when you need them and not to leave them open for the duration of the application. Open the database connection as late as possible and close/dispose of it as soon as possible.
Nicholas Paldino (a .NET/C# MVP) seems to agree with Dave:
You shouldn't keep a connection open and lying around. The SqlConnection class uses a connection pool in the background, and keeping your connection open is actually going to degrade your performance. You will want to create a new connection, open it, use it, and then close it for every operation that you do (or group of operations). You shouldn't be holding the connection open across operations. You will also notice MUCH better performance when you do this. The same thing holds with the command object. Don't use the same one. Use new ones. If you want to use a command object over and over again, you can, but use it for the same parameterized command. Don't keep changing the command string.
Both Dave and Nicholas are basing their advice on SQL Server's behavior (not SQL Server Mobile). SQL Server supports connection pooling, SQL Server Mobile does not. Again, from MS Employee Marcus Perry (link),
There is no connection pool used for local database access for SQL Mobile.
If only one SqlCeConnection is used, note that it is not thread safe. Thus, a multithread application must provide mechanisms to safely access the SQL database from multiple threads. There seem to be two approaches: one is to make the singleton wrapper class (mentioned above) thread safe and the other is to give each thread access to its own SqlCeConnection object. See these MSDN forum posts (here and here). Microsoft has yet to endorse a specific approach as a "best practice" (a discussion about this can be found here).
Tuesday, February 14, 2006
Application Verifier Tool for Windows Mobile 5.0
(link)
Thursday, February 09, 2006
Lock on this?
1. .NET Safe Thread Synchronization
2. Lock Choice
Friday, February 03, 2006
OpenNet CF 2.0 Beta1 Out Now.
Power management stuff has been greatly simplified, see:
http://blog.opennetcf.org/ctacke/PermaLink,guid,cf2c3926-e875-4a25-b635-39e227b358f5.aspx