The iPhone's built-in GPS (via Google Maps) is very helpful. Not perfect, but definitely very helpful.
So we use it a lot.
It pulled a fast one on us this morning though, causing me much amusement.
"Hang a right". Are you serious? The iPhone - so well spoken - now speaks hip?
"Keep goin' on ..." Goin'? Golly goodness! It's turned Texan! :o)
Or this one :
"ya gotta take the turn off onta ..."
Holey moley! My iPhone has truly become trendy! I don't mean it's trendy to have an iPhone, I mean the iPhone itself has trendiness of its own!!! :o)
So, kudos to whoever in Google or Apple gave me this amusement this morning - well done. :o)
Wednesday, March 31, 2010
Thursday, February 18, 2010
Engin voicebox (Sipura SPA 3102) sharing WiFi via LAN cable to Windows 7 laptop
My laptop has wireless and LAN. I only need the wireless.
My Engin 3102 voicebox (a re-badged Sipura SPA something-or-other) has LAN, but not wireless.
What if I want to run my VoIP over wireless?
OK, ok, if you can, it's simplest to just plug the voicebox directly into your broadband router.
But what if, for whatever reason, you can't, or don't want to?
Turns out, it is possible to plug the voicebox into the laptop via the LAN port, and have the voicebox piggy-back on the laptop's WiFi connection.
You beauty!
Apparently in Windows XP you can do it through Internet Connection Sharing.
I have Windows 7 Ultimate, and whilst I enabled Internet Connection Sharing, I never managed to get the voicebox to work through the laptop that way.
After more digging, I discovered that bridging network connections was the trick I needed.
Open Control Panel, go to Network And Sharing Center, then on the left-hand-side, choose the "Change adapter settings" option.
This will list all of your network adapters, including your LAN and WiFi adapters.
Select both (click on one, then ctrl-click the other), then right-click on either of the selected two and a menu gives an option to bridge the adapters.
Voila! It was that easy!
However, apparently if you have previously enabled Internet Connection Sharing, you'll need to disable it first - apparently it is incompatible with bridged network adapters.
So now I can have my voicebox and phone handset right near my laptop, up the other end of the house, far away from the router and without running cables through the house.
Nice.
My Engin 3102 voicebox (a re-badged Sipura SPA something-or-other) has LAN, but not wireless.
What if I want to run my VoIP over wireless?
OK, ok, if you can, it's simplest to just plug the voicebox directly into your broadband router.
But what if, for whatever reason, you can't, or don't want to?
Turns out, it is possible to plug the voicebox into the laptop via the LAN port, and have the voicebox piggy-back on the laptop's WiFi connection.
You beauty!
Apparently in Windows XP you can do it through Internet Connection Sharing.
I have Windows 7 Ultimate, and whilst I enabled Internet Connection Sharing, I never managed to get the voicebox to work through the laptop that way.
After more digging, I discovered that bridging network connections was the trick I needed.
Open Control Panel, go to Network And Sharing Center, then on the left-hand-side, choose the "Change adapter settings" option.
This will list all of your network adapters, including your LAN and WiFi adapters.
Select both (click on one, then ctrl-click the other), then right-click on either of the selected two and a menu gives an option to bridge the adapters.
Voila! It was that easy!
However, apparently if you have previously enabled Internet Connection Sharing, you'll need to disable it first - apparently it is incompatible with bridged network adapters.
So now I can have my voicebox and phone handset right near my laptop, up the other end of the house, far away from the router and without running cables through the house.
Nice.
What's the (Google) Buzz?
What's the buzz with the Buzz? Buzz off, Buzz, I'm too busy!
OK, I grant it's cool how it pulls in data from so many sources. But still, what, am I supposed to click in to the Buzz several times a day, and scroll through a long list of buzzes, looking for ones that have been updated?
No thanks.
OK, I grant it's cool how it pulls in data from so many sources. But still, what, am I supposed to click in to the Buzz several times a day, and scroll through a long list of buzzes, looking for ones that have been updated?
No thanks.
Sunday, February 7, 2010
Secure data removal when disposing of a PC
So my laptop (er, craptop) Toshiba Tecra A6 is at end-of-life, and I'm getting rid of it.
Of course, the hard disk is laden with commercial-in-confidence data, so what do I do?
Short answer : Eraser! Open-source, and it provides well over a dozen secure data removal options, including deleting specific files, 'wiping' disk free space, etc.
How did I use? I deleted all my files off the laptop, created a new Administrator user account and deleted my old user account, and then I used Eraser to ensure all that juicy data I just deleted can't be retrieved.
Nice. I'm a fan. Get it here.
Of course, the hard disk is laden with commercial-in-confidence data, so what do I do?
Short answer : Eraser! Open-source, and it provides well over a dozen secure data removal options, including deleting specific files, 'wiping' disk free space, etc.
How did I use? I deleted all my files off the laptop, created a new Administrator user account and deleted my old user account, and then I used Eraser to ensure all that juicy data I just deleted can't be retrieved.
Nice. I'm a fan. Get it here.
Tuesday, February 2, 2010
Merging WPF assemblies
Life can be unnecessarily complex, especially if you work with technology!
WPF is great. One of the ten best things Microsoft has ever done. (Er - not that they haven't also done loads of terrible things, but that's another story.)
Unfortunately, WPF windows and user controls are compiled into BAML, every time you rebuild your application, and the compile-to-BAML process is not very efficient.
I have, hmmm, probably 50 to 100 WPF windows and user controls in a particular project, and on a 3.2ghz CPU, app build time is around 12 seconds. And that's with heaps of RAM, the superb Intel X25-M SSD, and other speed features.
Compile the project without WPF windows and user controls, and it takes more like a second.
In other words, compilation to BAML is just plain slow.
Yet every time you change anything in the project's source code - regardless of whether or not you actually modified any XAML files or associated code-behind files - the BAML files are regenerated.
With C#, those BAML files are (it seems) regenerated just when you rebuild the project - which wastes some time.
But with VB.NET, those BAML files are constantly being regenerated as the VB.NET IDE performs ongoing recompilations of the entire project for Intellisense purposes.
This means that, working on a large VB.NET project with lots of XAML windows and user controls, you can face an unresponsive IDE several times a minute as it constantly compiles and recompiles and re-re-compiles, taking more than 10 seconds every time.
Slow, slow, slow, slow, slow, slow.
And for those of us who are into rapid testing and release cycles, slow builds are productivity killers.
So I refactored the solution, putting the windows and user controls in a WPF DLL, leaving most of the application logic in the main project (the WPF EXE that already existed).
There were a few tricks to getting that to work, but now build time is slashed. Unless I actually modify a window or user control in that DLL, the DLL is not rebuilt, and so I save roughly 10 seconds each time. And if you're making a series of minor tweaks and re-running, as is typical during testing cycles, that can easily translate into a 10% to 30% reduction in time spent by the developer. THAT'S good!
Of course, whatever XAML window or user control I happen to be working on at the time, I leave in the main WPF EXE, and only transfer it into the WPF DLL once I've tested it, and the usual flood of change requests for the new screen have died down.
That way, I'm rarely modifying the WPF DLL, and so I'm rarely copping the full 12-ish second build time - sufficiently rarely that the slowness of the full build is largely irrelevant.
All good and well ...
... and I highly recommend it if you need the speed boost ...
... BUT, things fall apart if you try to use a tool that merges assemblies.
I spent hours today digging around, and this is what I found out :
All of the XAML windows and user controls that have "Build Action" set to "Page" (which is the default), are compiled into a single assembly manifest resource named {AssemblyNameMinusFilenameExtension}.g.resources (e.g. MyApp.g.resources).
Within that one assembly manifest resource is a bunch of BAML items, one for each window or user control.
Now, if you change the name of the assembly manifest resource, WPF can no longer locate the BAML files.
So let's for example say you have two assemblies : MyWpfExe and MyWpfDll.
MyWpfExe.exe contains an assembly manifest resource named MyWpfExe.g.resources.
MyWpfDll.dll contains an assembly manifest resource named MyWpfDll.g.resources.
Problem is, if you merge the assemblies together, these two assembly manifest resources do not get merged, and because WPF will ONLY look for assembly manifest resources that match the assembly name, one of the assembly manifest resources (and all associated windows and user controls) will be ignored.
e.g. MyMergedWpfExe.exe contains two assembly manifest resources :
MyWpfExe.g.resources
MyWpfDll.g.resources
... but WPF will only look for one, matching the assembly name. i.e. the MyWpfDll.g.resources will be completely ignored.
Obvious solution? Well, somehow merge the two assembly manifest resources into one. But no easy cigar. I expect it can be done. I'll leave that as an exercise to the reader, if they care. (I found no existing tools that do the job, so it would probably require someone to write a tool especially for this purpose.)
I ended up finding a way that didn't require me to write a special tool. It's cumbersome, it's "clunky", but it does work, and it meets my immediate needs, and I can always improve it later.
So here goes (and warning : it is very technical!) :
There are two parts to my trick.
Part 1) Trick WPF into loading TWO DIFFERENT assembly manifest resources, from the SAME assembly, BOTH of which will be fully consulted when loading windows and user controls. The heart of this trick is to rename one of the assembly manifest resources to include the "en-US" culture. Unfortunately, this trick can only work if there are ONLY two assemblies with BAML stuff being merged, and it gets tricky if you are using localisation for other purposes (although you can still do it). (More details below.)
Part 2) The compiled BAML contains a link to the original assembly name, and of course, post-merging, the original assembly ain't anywhere to be found. So, ridiculous as it might seem, you actually need to temporarily produce a version of the DLL that has the same assembly name as the EXE. (More details below.)
So, step by step, it goes something like this :
Step 1) Alter MyWpfDll.dll's project settings so that its Assembly Name matches the exe's Assembly Name (MyWpfExe).
Step 2) Build just the DLL (MyWpfExe.dll, due to the rename in step #1).
Step 2) Open MyWpfExe.dll in Lutz Roeder's Reflector.
Step 3) Drill down through the tree view until you find the resource named MyWpfExe.g.resources. Right-click it and save it somewhere - e.g. C:\MyWpfExe.g.resources.
Step 4) Revert the name change from step #1. (i.e. reconfigure the MyWpfDll project to use MyWpfDll as its assembly name again instead of MyWpfExe.)
Step 5) Rename MyWpfExe.g.resources to MyWpfExe.g.en-US.resources.
Step 6) "Add existing file" to the MyWpfExe project, and choose MyWpfExe.g.en-US.resources.
Step 7) Ensure that MyWpfExe.g.en-US.resources has Build Action set to "Embedded Resource" (which is the default at least on my computer, so that SHOULD already be fine).
Step 8) Build the "solution" (MyWpfExe.exe and MyWpfDll.dll).
Step 9) Merge assemblies.
Voila! That was very painful and cumbersome, but you now have two WPF assemblies merged together, in a manner that all of the BAML from both assemblies is still accessible.
Alternatives :
* Of course, one option since you have full source code for both projects, is to make a project file that combines all source files into one mega project. Only use that project file when doing your release build. Not ideal, but an option, especially if you can find or make a tool that will automatically combine two VS.NET projects into a single project. (And hey - if you can find or make such a tool, it'll probably be less un-ideal than what I've presently settled for! It's just, when I finally found something that met my immediate purposes, I decided to not waste any further time refining it for the moment.)
WPF is great. One of the ten best things Microsoft has ever done. (Er - not that they haven't also done loads of terrible things, but that's another story.)
Unfortunately, WPF windows and user controls are compiled into BAML, every time you rebuild your application, and the compile-to-BAML process is not very efficient.
I have, hmmm, probably 50 to 100 WPF windows and user controls in a particular project, and on a 3.2ghz CPU, app build time is around 12 seconds. And that's with heaps of RAM, the superb Intel X25-M SSD, and other speed features.
Compile the project without WPF windows and user controls, and it takes more like a second.
In other words, compilation to BAML is just plain slow.
Yet every time you change anything in the project's source code - regardless of whether or not you actually modified any XAML files or associated code-behind files - the BAML files are regenerated.
With C#, those BAML files are (it seems) regenerated just when you rebuild the project - which wastes some time.
But with VB.NET, those BAML files are constantly being regenerated as the VB.NET IDE performs ongoing recompilations of the entire project for Intellisense purposes.
This means that, working on a large VB.NET project with lots of XAML windows and user controls, you can face an unresponsive IDE several times a minute as it constantly compiles and recompiles and re-re-compiles, taking more than 10 seconds every time.
Slow, slow, slow, slow, slow, slow.
And for those of us who are into rapid testing and release cycles, slow builds are productivity killers.
So I refactored the solution, putting the windows and user controls in a WPF DLL, leaving most of the application logic in the main project (the WPF EXE that already existed).
There were a few tricks to getting that to work, but now build time is slashed. Unless I actually modify a window or user control in that DLL, the DLL is not rebuilt, and so I save roughly 10 seconds each time. And if you're making a series of minor tweaks and re-running, as is typical during testing cycles, that can easily translate into a 10% to 30% reduction in time spent by the developer. THAT'S good!
Of course, whatever XAML window or user control I happen to be working on at the time, I leave in the main WPF EXE, and only transfer it into the WPF DLL once I've tested it, and the usual flood of change requests for the new screen have died down.
That way, I'm rarely modifying the WPF DLL, and so I'm rarely copping the full 12-ish second build time - sufficiently rarely that the slowness of the full build is largely irrelevant.
All good and well ...
... and I highly recommend it if you need the speed boost ...
... BUT, things fall apart if you try to use a tool that merges assemblies.
I spent hours today digging around, and this is what I found out :
All of the XAML windows and user controls that have "Build Action" set to "Page" (which is the default), are compiled into a single assembly manifest resource named {AssemblyNameMinusFilenameExtension}.g.resources (e.g. MyApp.g.resources).
Within that one assembly manifest resource is a bunch of BAML items, one for each window or user control.
Now, if you change the name of the assembly manifest resource, WPF can no longer locate the BAML files.
So let's for example say you have two assemblies : MyWpfExe and MyWpfDll.
MyWpfExe.exe contains an assembly manifest resource named MyWpfExe.g.resources.
MyWpfDll.dll contains an assembly manifest resource named MyWpfDll.g.resources.
Problem is, if you merge the assemblies together, these two assembly manifest resources do not get merged, and because WPF will ONLY look for assembly manifest resources that match the assembly name, one of the assembly manifest resources (and all associated windows and user controls) will be ignored.
e.g. MyMergedWpfExe.exe contains two assembly manifest resources :
MyWpfExe.g.resources
MyWpfDll.g.resources
... but WPF will only look for one, matching the assembly name. i.e. the MyWpfDll.g.resources will be completely ignored.
Obvious solution? Well, somehow merge the two assembly manifest resources into one. But no easy cigar. I expect it can be done. I'll leave that as an exercise to the reader, if they care. (I found no existing tools that do the job, so it would probably require someone to write a tool especially for this purpose.)
I ended up finding a way that didn't require me to write a special tool. It's cumbersome, it's "clunky", but it does work, and it meets my immediate needs, and I can always improve it later.
So here goes (and warning : it is very technical!) :
There are two parts to my trick.
Part 1) Trick WPF into loading TWO DIFFERENT assembly manifest resources, from the SAME assembly, BOTH of which will be fully consulted when loading windows and user controls. The heart of this trick is to rename one of the assembly manifest resources to include the "en-US" culture. Unfortunately, this trick can only work if there are ONLY two assemblies with BAML stuff being merged, and it gets tricky if you are using localisation for other purposes (although you can still do it). (More details below.)
Part 2) The compiled BAML contains a link to the original assembly name, and of course, post-merging, the original assembly ain't anywhere to be found. So, ridiculous as it might seem, you actually need to temporarily produce a version of the DLL that has the same assembly name as the EXE. (More details below.)
So, step by step, it goes something like this :
Step 1) Alter MyWpfDll.dll's project settings so that its Assembly Name matches the exe's Assembly Name (MyWpfExe).
Step 2) Build just the DLL (MyWpfExe.dll, due to the rename in step #1).
Step 2) Open MyWpfExe.dll in Lutz Roeder's Reflector.
Step 3) Drill down through the tree view until you find the resource named MyWpfExe.g.resources. Right-click it and save it somewhere - e.g. C:\MyWpfExe.g.resources.
Step 4) Revert the name change from step #1. (i.e. reconfigure the MyWpfDll project to use MyWpfDll as its assembly name again instead of MyWpfExe.)
Step 5) Rename MyWpfExe.g.resources to MyWpfExe.g.en-US.resources.
Step 6) "Add existing file" to the MyWpfExe project, and choose MyWpfExe.g.en-US.resources.
Step 7) Ensure that MyWpfExe.g.en-US.resources has Build Action set to "Embedded Resource" (which is the default at least on my computer, so that SHOULD already be fine).
Step 8) Build the "solution" (MyWpfExe.exe and MyWpfDll.dll).
Step 9) Merge assemblies.
Voila! That was very painful and cumbersome, but you now have two WPF assemblies merged together, in a manner that all of the BAML from both assemblies is still accessible.
Alternatives :
* Of course, one option since you have full source code for both projects, is to make a project file that combines all source files into one mega project. Only use that project file when doing your release build. Not ideal, but an option, especially if you can find or make a tool that will automatically combine two VS.NET projects into a single project. (And hey - if you can find or make such a tool, it'll probably be less un-ideal than what I've presently settled for! It's just, when I finally found something that met my immediate purposes, I decided to not waste any further time refining it for the moment.)
Tuesday, January 26, 2010
PLINQO : Data caching for the masses
The single biggest way to improve the speed of a database app is to cache data in memory, cutting-down on round-trips to remote servers.
But caching usually requires tedious hand-coding.
Apparently not-so any more.
I haven't checked it out yet, but CodeSmith claims their new PLINQO technology has built-in data caching mechanisms. That sounds like a very easy way to get substantial speed improvements in one's app!
It works in concert with LINQ to SQL.
In short, it's an entity framework that purportedly makes data caching easy. Exactly how easy? I haven't played with it yet, so I can't comment.
Switching frameworks is obviously a big effort, and I'm reasonably satisfied with the frameworks I'm already using, but this data-caching feature of PLINQO is enough to intrigue me - I think I might check it out.
But caching usually requires tedious hand-coding.
Apparently not-so any more.
I haven't checked it out yet, but CodeSmith claims their new PLINQO technology has built-in data caching mechanisms. That sounds like a very easy way to get substantial speed improvements in one's app!
It works in concert with LINQ to SQL.
In short, it's an entity framework that purportedly makes data caching easy. Exactly how easy? I haven't played with it yet, so I can't comment.
Switching frameworks is obviously a big effort, and I'm reasonably satisfied with the frameworks I'm already using, but this data-caching feature of PLINQO is enough to intrigue me - I think I might check it out.
Thursday, January 21, 2010
LogMeIn : Remote Mac screen sharing to Windows
A client has a Mac that I frequently need to log into remotely.
It's a brand-new Mac Mini, running Snow Leopard.
Getting the built-in VNC server to work with a Windows client was a very major pain.
Most VNC viewers simply refused to connect at all.
I did eventually find one Windows-based VNC viewer that would connect to the "Screen Sharing" on the Mac.
But lo-and-behold, the Screen Sharing service would frequently freeze up and stop accepting new connections, and I would need to call the client and get someone to physically disable and re-enable the Screen Sharing service to resolve the problem.
Further, the VNC connection would usually drop out after just a few minutes of inactivity, meaning I was constantly closing the VNC viewer and restarting it.
All in all, it was like doing a forced march on a broken leg.
Ouch.
So I went a huntin' for other options.
Must share a Mac's screen to a Windows client.
Preferrably free, although I would willing pay up to a few tens of dollars.
The only options I found wanted around $100 per year. That's not scalable. What if I picked up another client with a Mac needing similar remote support? That'd be another $100 per year per Mac being supported. Worth it for some, but not worth it in my particular case.
Then I found LogMeIn.
I tried it.
The Free edition supports screen sharing exactly like I want.
The Pro (non-free) edition has extra cool features like a "whiteboard" mode where the viewer can 'draw' on the screen, and both the person on the Mac, and the viewer on his remote PC, can see the drawing.
The Free version, it turns out, comes with time-limited access to the Pro features.
Smart move on LogMeIn's part.
I was experimenting with all these cool features, and then the Mac died the death.
My client told me that not only was I unable to connect, but they found the Mac in some unusable state and had to reboot it.
Hmmm.
Et tu, LogMeIn?
After such a surge of hope when LogMeIn initially worked, I was feeling very disappointed.
A web search turned up an odd clue : someone recommended running LogMeIn in 32-bit mode.
I'm not a Mac man, and I don't know how to enable "32-bit" mode for an app.
But I did manage to find a "Rosetta" mode for LogMeIn.
After enabling "Rosetta" mode for LogMeIn (right-click the Start LogMeIn app, and the option is in there somewhere), and studiously avoiding the fancy whiteboard and other tools (just in case they were to blame), LogMeIn now works WONDERFULLY for me. WONDERFULLY.
I can actually have a reliable, unbroken remote desktop session from a Windows box to a Mac box, any time of day or night!
It's like humanity finally arrived in the 21st century!
So, kudos to LogMeIn.
And if you give it a try and the Mac dies the death, then the solution is one or both of : Use Rosetta mode, and/or don't use those delicious tempting "Pro" tools.
I could experiment more and figure out exactly which of those two variables made the difference, but time is so short I could hardly justify writing this note, let alone doing another half hour or hour of experiments, so sorry - hopefully this article will at least help some other wandering soul out there on the road to PC-Mac blissdom. :o)
It's a brand-new Mac Mini, running Snow Leopard.
Getting the built-in VNC server to work with a Windows client was a very major pain.
Most VNC viewers simply refused to connect at all.
I did eventually find one Windows-based VNC viewer that would connect to the "Screen Sharing" on the Mac.
But lo-and-behold, the Screen Sharing service would frequently freeze up and stop accepting new connections, and I would need to call the client and get someone to physically disable and re-enable the Screen Sharing service to resolve the problem.
Further, the VNC connection would usually drop out after just a few minutes of inactivity, meaning I was constantly closing the VNC viewer and restarting it.
All in all, it was like doing a forced march on a broken leg.
Ouch.
So I went a huntin' for other options.
Must share a Mac's screen to a Windows client.
Preferrably free, although I would willing pay up to a few tens of dollars.
The only options I found wanted around $100 per year. That's not scalable. What if I picked up another client with a Mac needing similar remote support? That'd be another $100 per year per Mac being supported. Worth it for some, but not worth it in my particular case.
Then I found LogMeIn.
I tried it.
The Free edition supports screen sharing exactly like I want.
The Pro (non-free) edition has extra cool features like a "whiteboard" mode where the viewer can 'draw' on the screen, and both the person on the Mac, and the viewer on his remote PC, can see the drawing.
The Free version, it turns out, comes with time-limited access to the Pro features.
Smart move on LogMeIn's part.
I was experimenting with all these cool features, and then the Mac died the death.
My client told me that not only was I unable to connect, but they found the Mac in some unusable state and had to reboot it.
Hmmm.
Et tu, LogMeIn?
After such a surge of hope when LogMeIn initially worked, I was feeling very disappointed.
A web search turned up an odd clue : someone recommended running LogMeIn in 32-bit mode.
I'm not a Mac man, and I don't know how to enable "32-bit" mode for an app.
But I did manage to find a "Rosetta" mode for LogMeIn.
After enabling "Rosetta" mode for LogMeIn (right-click the Start LogMeIn app, and the option is in there somewhere), and studiously avoiding the fancy whiteboard and other tools (just in case they were to blame), LogMeIn now works WONDERFULLY for me. WONDERFULLY.
I can actually have a reliable, unbroken remote desktop session from a Windows box to a Mac box, any time of day or night!
It's like humanity finally arrived in the 21st century!
So, kudos to LogMeIn.
And if you give it a try and the Mac dies the death, then the solution is one or both of : Use Rosetta mode, and/or don't use those delicious tempting "Pro" tools.
I could experiment more and figure out exactly which of those two variables made the difference, but time is so short I could hardly justify writing this note, let alone doing another half hour or hour of experiments, so sorry - hopefully this article will at least help some other wandering soul out there on the road to PC-Mac blissdom. :o)
Labels:
PC-Mac interoperation,
Remote desktop
Subscribe to:
Posts (Atom)