|
Tue
Jul 28 2009 |
Resharper Shortcuts |
|
A few custom shortcuts because I can never remember which Resharper command they are… Alt-N: ReSharper.ReSharper_UnitTest_ContextRun Visual Studio macro for resetting these bindings: Imports System Imports EnvDTE Imports EnvDTE80 Imports EnvDTE90 Imports System.Diagnostics Public Module Module1 Public Sub BindShortcuts() Bind("ReSharper.ReSharper_UnitTest_ContextRun", "Alt+n") Bind("ReSharper.ReSharper_ShowUnitTestExplorer", "Ctrl+Alt+T") Bind("ReSharper.ReSharper_ShowUnitTestSessions", "Ctrl+Alt+R") Bind("ReSharper.ReSharper_UnitTest_RunCurrentSession", "Ctrl+Alt+E") Bind("File.CloseAllButThis", "Ctrl+Alt+Shift+W") MsgBox("Done.") End Sub Private Sub Bind(ByVal commandName As String, ByVal globalBinding As String) Dim command As Command command = DTE.Commands.Item(commandName, 1) command.Bindings = "Global::" & globalBinding End Sub End Module |
|
Mon
Jan 26 2009 |
EvoLisa Video |
|
Here is a video of Roger Alsing’s EvoLisa project evolving an image of the Mona Lisa using random polygons. The video was made using Roger’s source code modified with Dan Bystrom’s FitnessCalculator written in assembler. The program was changed to output a frame whenever the image improves by 5%. The program was run for 16 hours to generate the 660 frames used in the video below. The final image uses 242 polygons (average 6.9 points per polygon) and is the 7,052,061th generation. It only took 48 seconds to generate the first half of this video and the remaining 16 hours to generate the second half. I used VirtualDub to combine the frames into a video. The music clip is Company I from Philip Glass. By the way, Vimeo kicks butt on YouTube – higher quality videos and a better interface for uploading/managing videos. |
|
Sun
Jan 25 2009 |
Anti-Virus Software is Useless |
|
Over the holidays I was infected with multiple viruses. One them was Trojan.Vundo.GCY. It’s job is to download other viruses and malware. I had over a dozen files infected with various viruses causing popups and network slowdown. I tried 6 or 7 anti-virus / anti-malware products and found they had abysmally low detection rates. The best only finding 30% of infected files. This included software from Symantec Online Security Scan, Eset Nod32 Online Scanner, BitDefender Free Edition, AVG Free Edition, Spyware Doctor from the Google Pack, Malware Byte’s Anti-Malware and Ad-Aware Free. Perhaps using installed, retail versions would have given better results but I doubt it. All of the companies claim the free/online scanners use the same core engine and virus definitions as their retail products. I suspect this is true as it looks like these companies are competing on features like email integration, phishing protection and real-time scanning. I ran these scans from a fresh, uninfected install so its unlikely that any viruses were actively attempting to hide from a scan. As a result, I won’t be purchasing anti-virus software in the near future. I will keep AVG Free for quick scanning of files I believe are already clean. That statement shows how little confidence I have in these scanners. Despite this I think they are still good for catching the older viruses propagating among completely unprotected machines. I did find a useful website: VirusTotal.com lets you upload a file and scan it with almost 50 scanners. Here is an here is an example report). They also have a small utility you can install to get a right-click -> Send To target. You are limited to scanning one file at a time though can you can upload a zip archive to scan several. There are a number of similar websites, but VirusTotal appears to be the best. My anti-virus/malware strategy:
To recover from an infection:
How do you prevent infections? |
|
Fri
Nov 7 2008 |
Zebra striping |
|
From the article Zebra Striping: Does it Really Help?: - no difference in speed or accuracy If you are going to use zebra striping, keep it subtle. Update: a followup post with more research confirming this approach. |
|
Thu
Nov 6 2008 |
User Interface Design for Programmers |
|
From Joel Spolsky’s article User Interface Design for Programmers: - A user interface is well-designed when the program behaves exactly how the user thought it would. |
|
Wed
Apr 30 2008 |
Upgrading to WordPress 2.5 on BlueHost |
|
WordPress 2.5 was released last month. Why can’t we upgrade using Fantastico? It turns out BlueHost has started their own Fanastico competitor called SimpleScripts. I doubt we’ll be seeing any new Fantastico updates. While Fantastico has had WordPress 2.5 scripts for at least three weeks, BlueHost’s tech support claims they are waiting on Fantastico to release updated scripts. This is the first problem. The second problem is the recommended migration procedure here and here. It involves FTP clients and pulling database configuration bits from php files. This does not leave a good first impression of a product that is supposed to provide one-click installation and upgrades. I ended up using the Wordpress Automatic Upgrader Plugin. I still needed to use an FTP client to install the plugin but now I am not dependent on Fanastico or SimpleScripts. This plugin downloads the latest files directly from WordPress so updates should be available as soon as WordPress releases them. I encountered two problems while upgrading to 2.5:
On the positive side, SimpleScripts appears to be a more polished product compared to Fantastico. |
|
Sun
Apr 6 2008 |
Canon Elph on Steroids |
|
The open source project CHDK has built firmware enhancements for many of Canon’s compact cameras. Some features: - RAW support Some first impressions… The UI is organized but far from user friendly. Lightroom cannot open the RAW files. At high shutter speeds the flash power was too high and there was no flash compensation. I ended up holding a white envelope in front of the flash. I tried taking some high speed photos with the new firmware on my Canon SD500. The best photo was taken with the stock firmware. The high speed shutter wasn’t needed for this shot – the focus and timing were more important. These photos were taken in daylight with no additional lighting beyond the flash. Canon SD500 with CHDK (1/4000s) I think I will keep it on my camera for the extra information on the display and the scripting. A few links: installing, download, usage, more usage info |
|
Fri
Mar 28 2008 |
Processing |
|
A friend told me I needed to write more blog posts. I’m not sure if he was interested in what I have to say or just didn’t want to link to a dead blog. Either way I will put down a few more posts! Take a look at the work from Robert Hodgin at flight404.com. He is using Processing, a programming language created for experimenting with computer graphics. At the core of these images and videos is a model following simple rules of physics (e.g. two positively charged particles will move away from each other) that is affected by the music (e.g. particle size increases with volume). The final image or video isn’t designed, it is the result of programming these rules and letting the model play itself out. Solar (high definition version, alternate version with lyrics) |
|
Fri
Aug 3 2007 |
Global exception handling |
|
Some general notes on exception handling:
In ASP.NET void Application_Error(object sender, EventArgs e) { Exception ex = Server.GetLastError(); if (ex is System.Web.HttpUnhandledException) { ex = ex.InnerException; } LogHelper.Log.Error("Unhandled exception", ex); Server.Transfer("~/Error.aspx"); } 2. Create an Error.aspx page: 3. If you are using Forms Authentication, add the following to your web.config. It ensures unauthenticated users can see the Error.aspx page in case an error occurs during logon/logoff. You should do the same for any images and stylesheets as well. <configuration> <location path="Error.aspx"> <system.web> <authorization> <allow users="?"/> </authorization> </system.web> </location> </configuration> 4. If you are using AJAX, you have to add an event handler on every page (are there any better solutions?): protected void ScriptManager1_AsyncPostBackError(object sender, AsyncPostBackErrorEventArgs e) { LogHelper.Log.Error("Unhandled exception during asyncpostback", e.Exception); ScriptManager1.AsyncPostBackErrorMessage = "An unexpected error occured. Please try again or contact the Help Desk."; } ASP.NET Web Services using System; using System.Web.Services.Protocols; using TDR.Common.Utility; namespace MySolution.MyProject.SoapExtensions { public class LoggingSoapExtension : SoapExtension { public override object GetInitializer(LogicalMethodInfo methodInfo, SoapExtensionAttribute attribute) { return null; } public override object GetInitializer(Type serviceType) { return null; } public override void Initialize(object initializer) { } public override void ProcessMessage(SoapMessage message) { if (message.Stage == SoapMessageStage.AfterSerialize) { if (message.Exception != null) { LogManager.Log.Error(message.Exception.Message, message.Exception); } } } } } 2. Add this to your web.config: <system.web> <webServices> <soapExtensionTypes> <add type="MySolution.MyProject.SoapExtensions.LoggingSoapExtension,MySolution" priority="1" group="1" /> </soapExtensionTypes> </webServices> </system.web> Note: SoapExtensions are not called when invoking the a webservice from the built-in test webpage. WinForms, Console Apps and Services static void Main() { AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler( CurrentDomain_UnhandledException); } /// <summary> /// Log unhandled exceptions that occur anywhere in the appdomain. /// </summary> static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) { try { LogHelper.Log.Error("Unhandled exception.", e.ExceptionObject as Exception); } catch { } } |
|
Fri
Aug 3 2007 |
MSBuild Automated Deploy Scripts for Web Applications |
|
These are suggested steps for creating batch scripts that will deploy a solution to DEV, TEST and PROD. If this article looks like it is more complicated than it should be, I agree. I think batch scripts with an XML read/write utility or NAnt would be a better choice:
Here is the MyApp.build file: <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <!-- MY WEB APPLICATION DEPLOY SCRIPT To deploy this application use the batch files DeployToXXX.bat --> <Import Project="..\..\Utilities\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> <PropertyGroup> <TempFolder>..\..\_tempfolder</TempFolder> <DevFolder>\\mydevserver\wwwroot\myapp</DevFolder> <TestFolder>\\mytestserver\wwwroot\myapp</TestFolder> </PropertyGroup> <Target Name="DeployToDev"> <AspNetCompiler VirtualPath="MyApp" PhysicalPath="..\ " TargetPath="$(TempFolder)" Clean="true" Force="true" Debug="false" Updateable="false" /> <XmlRead XmlFileName="$(TempFolder)\web.config" XPath="/configuration/appSettings/add[@key='DEV.Log4NetConnectionString']/@value"> <Output TaskParameter="Value" PropertyName="Log4NetConnectionString"/> </XmlRead> <XmlUpdate XmlFileName="$(TempFolder)\web.config" XPath="/configuration/appSettings/add[@key='Environment']/@value" Value="DEV" /> <XmlUpdate XmlFileName="$(TempFolder)\web.config" XPath="/configuration/log4net/appender[@type='log4net.Appender.ADONetAppender']/connectionString/@value" Value="$(Log4NetConnectionString)" /> <XmlUpdate XmlFileName="$(TempFolder)\web.config" XPath="/configuration/system.web/compilation/@debug" Value="false" /> <CreateItem Include="$(DevFolder)\**\*" <Output TaskParameter="Include" ItemName="FilesToCleanFromTarget" /> </CreateItem> <Delete Files="@(FilesToCleanFromTarget)" /> <CreateItem Include="$(TempFolder)\**\*" Exclude="$(TempFolder)\Deploy\*"> <Output TaskParameter="Include" ItemName="FilesToDeploy"/> </CreateItem> <Copy SourceFiles="@(FilesToDeploy)" DestinationFiles="@(FilesToDeploy->'$(DevFolder)\%(RecursiveDir)%(Filename)%(Extension)')" /> <RemoveDir Directories="$(TempFolder)" /> </Target> <Target Name="DeployToTest"> <CreateItem Include="$(DevFolder)\**\*" Exclude="$(DevFolder)\Deploy\*"> <Output TaskParameter="Include" ItemName="FilesToDeploy"/> </CreateItem> <Copy SourceFiles="@(FilesToDeploy)" DestinationFiles="@(FilesToDeploy->'$(TestFolder)\%(RecursiveDir)%(Filename)%(Extension)')" /> <XmlRead XmlFileName="$(TestFolder)\web.config" XPath="/configuration/appSettings/add[@key='TEST.Log4NetConnectionString']/@value"> <Output TaskParameter="Value" PropertyName="Log4NetConnectionString"/> </XmlRead> <XmlUpdate XmlFileName="$(TestFolder)\web.config" XPath="/configuration/appSettings/add[@key='Environment']/@value" Value="TEST" /> <XmlUpdate XmlFileName="$(TestFolder)\web.config" XPath="/configuration/log4net/appender[@type='log4net.Appender.ADONetAppender']/connectionString/@value" Value="$(Log4NetConnectionString)" /> <XmlUpdate XmlFileName="$(TestFolder)\web.config" XPath="/configuration/system.web/compilation/@debug" Value="false" /> </Target> <Target Name="DeployToProd"> <Copy SourceFiles="$(TestFolder)\web.config" DestinationFiles="$(TestFolder)\Web.config.test" /> <XmlRead XmlFileName="$(TestFolder)\web.config" XPath="/configuration/appSettings/add[@key='PROD.Log4NetConnectionString']/@value"> <Output TaskParameter="Value" PropertyName="Log4NetConnectionString"/> </XmlRead> <XmlUpdate XmlFileName="$(TestFolder)\web.config" XPath="/configuration/appSettings/add[@key='Environment']/@value" Value="PROD" /> <XmlUpdate XmlFileName="$(TestFolder)\web.config" XPath="/configuration/log4net/appender[@type='log4net.Appender.ADONetAppender']/connectionString/@value" Value="$(Log4NetConnectionString)" /> <XmlUpdate XmlFileName="$(TestFolder)\web.config" XPath="/configuration/system.web/compilation/@debug" Value="false" /> <Prompt Text="Please ask the production administrator to copy MyApp from test to production. Press Enter when complete."/> <Copy SourceFiles="$(TestFolder)\Web.config.test" DestinationFiles="$(TestFolder)\Web.config" /> <Delete Files="$(TestFolder)\Web.config.test" /> </Target> </Project> Then to run use the following batch script: @echo off echo. echo -------------------------------------------------- echo. echo Deploy the Application to Dev echo. echo Ensure you have retrieved the latest version echo from source control. echo. echo -------------------------------------------------- echo. call "%VS80COMNTOOLS%\vsvars32.bat" set MSBuildCommunityTasksPath=..\..\Utilities\MSBuildCommunityTasks msbuild deploy.build /target:DeployToDev pause This requires the MSBuildCommunityTasks DLLs. Download, install, copy the DLLs to your project directory under Utilities, checkin to VSS and then uninstall. Placing the DLLs in VSS ensures subsequent developers can use the project without hacking their way through a bunch of dependencies. |