- Download and install Visual Studio 2013
- Download and install the Web Platform Installer, v5.0 or greater
- From the Web Platform Installer, install:
- Windows Azure SDK and related Powershell utilities and command line tools
- Start a new solution (or open an existing one)
- From the NuGet package manager in your solution, ensure that you've installed the 'WindowsAzure.Storage' package, or at least have it in your cache. This is going to be required by the New Project wizard when generating the project.
- Add a new project
- In the 'Add new project' wizard, select the C# projects -> Cloud -> Windows Azure Cloud Service
- Follow this absurdly easy tutorial on implementing an ErrorHandler interceptor (behavior)
- Add logging to your application using the Microsoft Patterns & Practices Enterprise Library Logging Application Block (which can be found here).
- Create a SQL server database in Azure using this tutorial on MSDN. When designing the user roles and authentication, it's recommended that you use the ASP.NET Identity membership design and design your tables accordingly around this.
- Microsoft has provided an extension to the ASP.NET Identity membership framework specifically for EntityFramework. They recommend that you use a code-first model for generating entities.
- Log in to Azure through the management portal: http://manage.windowsazure.com/
- Configure all of your connections and permissions to the database. e.g. you may want to have multiple users: one for read-only operations, another for read-write operations.
- Generate or write your data model. This article will show you how to create a code-first data model with Entity Framework. Ensure that you include users so that you can support proper application authentication and authorization via the ASP.NET Identity membership framework.
- The link above also includes instructions on using code-first migrations for when you update your data model.
- TODO: Elaborate on how to properly set up the database when performing a code-first database design
- Add an IoC container to your WCF service to enable you to easily develop and unit test it. I've chosen to use Ninject because despite a few minutes of inital frustration, it's actually exceedingly easy to integrate with WCF, especially now that there's the Ninject WCF extensions NuGet package. To integration Ninject with your WCF service, perform the following steps:
- Install-Package Ninject.Extensions.Wcf -Version 3.2.1.0 (Ninject and Ninject.Web.Common are installed as dependencies for you automatically).
- Create a NinjectModule descendant to bind your interfaces to concrete implementations. It should look something like the following:
namespace MyService.CloudStorage.Support { using System.Diagnostics.CodeAnalysis; using System.ServiceModel; using Common.Interfaces; using global::Ninject.Modules; using global::Ninject.Syntax; using Services; using NinjectServiceHost = global::Ninject.Extensions.Wcf.NinjectServiceHost; /// <summary> /// A <see cref="NinjectModule"/> descendant for bootstrapping our application /// </summary> public class MyServiceCloudStorageNinjectModule : NinjectModule { /// <inheritdoc/> [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1604:ElementDocumentationMustHaveSummary", Justification = "InheritDoc")] public override void Load() { this.Bind<IResolutionRoot>().ToConstant(Kernel); this.Bind<ServiceHost>().To<NinjectServiceHost>(); this.Bind<IMyServiceStorage>().To<MyServiceStorage>(); this.Bind<ILoggingService>().To<MicrosoftEnterpriseLoggingBlockLoggingService>(); } } } - Create a Global Application Class (global.asax) if one's not already created: Right-click on your project -> Add -> New Item ... and in the window that comes up, go to Visual C# -> Web -> Global Application File
Update your Global class to extend from Ninject.Web.Common.NinjectHttpApplication and override the CreateKernel() method and return a new CustomNinjectModule (as created above). The method should look something like this:namespace MyService.CloudStorage { using System.Diagnostics.CodeAnalysis; using System.Web; using Ninject; using Ninject.Web.Common; using Support; /// <summary> /// A global <see cref="HttpApplication"/> class for managing the lifecycle /// of the application /// </summary> public class Global : NinjectHttpApplication { /// <inheritdoc/> [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1604:ElementDocumentationMustHaveSummary", Justification = "InheritDoc")] [SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1615:ElementReturnValueMustBeDocumented", Justification = "InheritDoc")] protected override IKernel CreateKernel() { return new StandardKernel(new NinjectSettings(), new MyServiceCloudStorageNinjectModule()); } } }- Update your .svc file for your service(s) and add an extra XML attribute that looks like this: <%@ ServiceHost Service="HelloNinjectWcf.Service.GreetingService" Factory="Ninject.Extensions.Wcf.NinjectServiceHostFactory" %>
- Implement your business logic
- If you're designing your service properly, you'll need to ensure that communications between clients and your service are secure. Toward that end, you'll need to use SSL to encrypt your communications. There's a number of things involved in this:
- Generate certificates for your server and your client
- Ensure that your IIS server is correctly configured to use 'https' bindings on your site, along with the server-side certificate that you've generated.
- If you're using Windows Store Apps to access a WCF service, you'll need to ensure that you use a CustomBinding correctly configured with the right *BindingElement objects to create an SSL secured, HTTPS-transported binding.
- For the server, in your service's concrete implementation, you'll need to remove any .config file configuration, and add a method specified according to a convention that WCF recognizes that looks like the following:
/// <summary> /// The service certificate store name /// </summary> private const StoreName ServiceCertificateStoreName = StoreName.My; /// <summary> /// The service certificate store location /// </summary> private const StoreLocation ServiceCertificateStoreLocation = StoreLocation.LocalMachine; /// <summary> /// Configures the specified configuration. /// </summary> /// <param name="config">The configuration.</param> /// <remarks> /// A service endpoint configuration method determined by convention. /// <see href="http://msdn.microsoft.com/en-us/library/hh205277(v=vs.110).aspx"/> /// </remarks> public static void Configure(ServiceConfiguration config) { ServiceEndpoint serviceEndpoint = new ServiceEndpoint( ContractDescription.GetContract(typeof(IMyServiceStorage), typeof(MyServiceStorage)), new CustomBinding( new TransportSecurityBindingElement(), new SslStreamSecurityBindingElement { RequireClientCertificate = false }, new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8), new HttpsTransportBindingElement() ), new EndpointAddress("https://localhost/MyService.CloudStorage/MyServiceStorage.svc") ); config.AddServiceEndpoint(serviceEndpoint); const string ServiceCertificateThumbprint = "[a 40 digit hexadecimal certificate thumbprint here]"; X509Store certificateStore = new X509Store(ServiceCertificateStoreName, ServiceCertificateStoreLocation); certificateStore.Open(OpenFlags.ReadOnly); X509Certificate2Collection x509Certificate2Collection = certificateStore.Certificates.Find( findType: X509FindType.FindByThumbprint, findValue: ServiceCertificateThumbprint, validOnly: false ); certificateStore.Close(); X509Certificate2 serviceCertificate = x509Certificate2Collection.Cast<X509Certificate2>().FirstOrDefault(); if (serviceCertificate == null) { throw new ConfigurationErrorsException(String.Format("No certificate representing the service with thumbprint {0} could be found in {1} store at {2} location", ServiceCertificateThumbprint, ServiceCertificateStoreName, ServiceCertificateStoreLocation)); } ServiceCredentials serviceCredentials = new ServiceCredentials { IdentityConfiguration = new IdentityConfiguration { // TODO: Change this to authenticate the clients CertificateValidationMode = X509CertificateValidationMode.None }, ServiceCertificate = { Certificate = serviceCertificate }/*, ClientCertificate = { // TODO: Resolve the client certificate Certificate = serviceCertificate }*/ }; config.Description.Behaviors.Add(serviceCredentials); // config.Description.Behaviors.Add(new ServiceMetadataBehavior { HttpGetEnabled = true, HttpsGetEnabled = true }); } - For the Windows Store App client, you'll need to have a similarly configured counterpart channel factory and binding for connecting to the service:
this.channelFactory = new ChannelFactory<IMyServiceStorageChannel>( binding: new CustomBinding( new TransportSecurityBindingElement(), new SslStreamSecurityBindingElement(), new TextMessageEncodingBindingElement(MessageVersion.Soap12WSAddressing10, Encoding.UTF8), new HttpsTransportBindingElement() ), remoteAddress: new EndpointAddress(serviceUri) ); this.passwordVault = new PasswordVault(); // This IDispatchMessageInspector is a custom addition for our own brand of authentication this.channelFactory.Endpoint.EndpointBehaviors.Add(new ClientAuthenticationDispatchMessageInspector(this.passwordVault));
- For the Windows Store App, you'll also need to have the server's public key (assuming it's not trusted, e.g. a self-signed certificate) added to the app's certificate declarations in the package manifest. There's a video on how to do it here on Channel 9. For the sake of convenience, I'll reproduce the steps here:
- Obtain your server's public key in DER-encoded .cer format.
- Open the Package.appxmanifest file for your App in Visual Studio
- Go to the Declarations tab.
- Under the 'Available Declarations' box, select 'Certificates' and click 'Add' if there's no Certificates declaration already added.
- Select the 'Certificates' declaration in the 'Supported Declarations' box.
- In the 'Certificates' group on the large pane, click 'Add New'.
- In the certificate parameters box that comes up, enter 'Root' in the 'Name' field, and select your public key file. Once you do this, Visual Studio will automatically import it into your project.
- Save the manifest.
- Publish it to Azure Services
- If you've designed your application correctly, you'll be using HTTPS for communicating with your clients. Read Microsoft's guide on MSDN to uploading a certificate with your service.
- Implement your Windows 8.1 client // TODO: Elaborate on this
- Unit test your Windows 8.1 client on your own local machine.
- Visual Studio 2012 / .NET 4.5 added the ability to do asynchronous unit tests to MSTest!
- In order to unit test the Windows 8.1 Metro client against services on your localhost, you'll have to read this. It describes the new security features in Windows 8(.1) and how to explicitly enable your application to communicate through the network loopback interface.
- You can also read this. Bottom line, you have to ensure that you enable a loopback exemption for your unit tests.
- Unit / integration test it against your Azure service
- Ensure that you've created a 'Staging' area in your Azure configuration panel and you're not testing against production! Testing against production is extremely poor practice!
- Publish your App on the Windows Store if you so choose
Wednesday, November 26, 2014
Creating Azure Services with Visual Studio 2013 and Windows 8.1
Tuesday, October 28, 2014
Correcting the default check-in action for associated work items in Team Foundation Server
I've found that it's a giant pain in the ass in TFS when associating work items to checkins because the default assocation action is 'Resolve' rather than 'Associate'. When I'm working on features, I like to do bits of functionality in units and check them in to source control in small batches to make my changes more manageable. Unfortunately, many times I've forgotten to change the association action when associating work items with change sets and it's resolved my issue instead of just associating the work item with the change set. This becomes problematic because it skews my records and metrics for how much time is spent working on a task. Fortunately one can change this in the registry:
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\[Version Number]\TeamFoundation\SourceControl\Behavior
Quick fix.
HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\[Version Number]\TeamFoundation\SourceControl\Behavior
Quick fix.
Friday, October 24, 2014
Regarding pre-test invocation scripts when deploying to a Test Agent with TFS
So, I learned something interesting about TFS Test Agents today and they way they handle pre-test invocation scripts when running tests on a Test Agent. In Microsoft Test Manager, do the following:
- Connect to a Team Project
- Change into 'Lab Center' mode
- Click on 'Test Settings' in the top bar-ish area. This will open up the Test Settings Manager.
- Edit or create a new 'Test Settings' item and open it up.
- In the 'test settings' editor, under the 'Steps' column on the left-hand side, go to 'Advanced' -> 'Scripts'. You're now presented with the scripts page where you can specify scripts to be invoked before and after the execution of your test run.
Now, **here's the important thing** :
The script file(s) you specify in these boxes do not get copied to the Test Agent per se. Instead, their contents get read and merged with an automatically generated script that's created by the Test Agent. The script that actually gets run on the Test Agent will look similar to the following:
REM **************************************************************************** REM * Generated by Microsoft Visual Studio REM * Copyright (c) Microsoft Corporation. All rights reserved. REM * REM **************************************************************************** set ResultsDirectory=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1\Results set DeploymentDirectory=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1\DEPLOY~1 set TestRunDirectory=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1 set TestRunResultsDirectory=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1\Results\00C4EF~1 set TotalAgents=1 set AgentWeighting=100 set AgentLoadDistributor=Microsoft.VisualStudio.TestTools.Execution.AgentLoadDistributor set AgentId=1 set TestDir=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1 set BuildDirectory=\\SOMESERVER\SomeShare\TFSDrops\HRST\CWSTAM~1.SPR\CWSTAM~3.1 set DataCollectionEnvironmentContext=Microsoft.VisualStudio.TestTools.Execution.DataCollectionEnvironmentContext set TestLogsDir=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1\Results\00C4EF~1 set ControllerName=TSTTFSTHR01:6901 set TestDeploymentDir=C:\Users\Autotest\AppData\Local\VSEQT\QTAgent\23620\00C4EF~1\DEPLOY~1 set AgentName=00C4EFD8-A65F-4B5E-AD5F-04F93895B543 REM **************************************************************************** REM * User Commands REM * REM **************************************************************************** echo "My actual user commands from my script file here"
This is important to keep in mind when you're writing the commands in the script to be executed, because no files get copied with the script file you reference in the Test Settings, and there's no mention of where that script file originally came from, so the script is effectively executed without any context except for that which is given to it by the TFS Test Agent in the prefixed lines.
Sunday, October 19, 2014
A huge annoyance in Windows 8 store apps
Apparently Bindings are no longer TwoWay by default as they were in WPF. They're now OneWay, which was a huge annoyance and wasted a solid half hour of my time trying to debug my bindings.
Monday, September 01, 2014
Creating a WPF app with Microsoft Prism Framework 5
To get started, do the following:
- follow the tutorial provided by Microsoft.
- follow the followup tutorial for linking views and view models, specifically the section titled "Creating the View Model Using a View Model Locator"
- setup auto-wiring for the container in this section of the tutorial.
- Ensure that you set the default ViewModel factory in the Bootstrapper.ConfigureContainer method: ViewModelLocationProvider.SetDefaultViewModelFactory(viewModelType => this.Container.Resolve(viewModelType));
Wednesday, August 20, 2014
Getting an "RPC endpoint not found/not listening" exception when connecting to a remote machine with PowerShell
Lately I've been dealing with a lot of remote management for the purposes of automating our deployment process for the product on which I'm working. I've been able to connect other (pre-configured) machines, but when I wanted to connect to my own machine in unit tests, I've been unable to do so until now. Each time I try to connect, I'd get an exception along the lines of "The remote RPC server is not responding". I double checked that my "Windows Remote Management (WS-Management)" service is up and running, so I was perplexed as to why I still couldn't connect. I had turned off my firewall (temporarily, of course), and as if that wasn't enough, I'd explicitly enabled the rules for Windows Remote Management. As it turns out, (at least when you're running Windows Server 2008 R2) the service runs by default, but is not configured to allow remote management by default. (Totally makes sense, right ? /sarcasm) To remedy this, you need only run the following under and Administrator command line:
winrm quickconfig
This will enable your machine to accept incoming connections. You should also ensure that your firewall has been properly configured to allow the remote management rules (pre-existing, come with Windows). Also make sure that your service is actually running.
winrm quickconfig
This will enable your machine to accept incoming connections. You should also ensure that your firewall has been properly configured to allow the remote management rules (pre-existing, come with Windows). Also make sure that your service is actually running.
Saturday, August 09, 2014
Creating a certificate chain of self-signed certificates for development / testing / private environments
As anybody who's ever tried to develop secure services with SSL knows, it's expensive to buy trusted certificates from a certification authority. This is especially true if you're an independent developer who doesn't have a lot of resources. Therefore, we need to be able to generate self-signed certificates in order to develop and test our code before we actually go buy a Trusted Certificate for production. This tutorial will show you how to create a chain of trust and start generating certificates from a self-signing authority. The information here is based off of Microsoft's documentation on MSDN about the matter.
- Create a signing authority certificate:
- makecert -n "CN=My Signing Authority" -r -sv MySigningCert.pvk MySigningCert.cer
- Merge the private key file and public key file into an encrypted key (this isn't mentioned in the MSDN article linked above, but you can find the documentation here):
- pvk2pfx /pvk MySigningCert.pvk /spc MySigningCert.cer /pfx MySigningCert.pfx /pi mycertpassword /po mycertpassword /f
- Start creating site certificates with your signing certificate:
- makecert -iv MySigningCert.pvk -n "CN=www.mywebsite.com" -ic MySigningCert.cer -sv sitekey.pvk sitekey.cer -pe
You'll be prompted for passwords for securing the private key. Ensure that you remember them, you'll need them to create the merged file.
This step isn't necessary for signing site certificates, but does make things more convenient for storing the certificate and installing it on different machines. Be careful: you should never leave keys laying around file systems on machines, they should always either: a) be stored in an encrypted store like that provided by Windows, or b) be stored on separate storage media that can be physically locked away with access only available to trusted personnel.
Now, as above, I recommend that you merge the .pvk and .cer into a .pfx for easy transport and storage.
Labels:
cer,
certificate,
encryption,
makecert,
pfx,
pfx2pvk,
pvk,
self,
signing,
ssl
Thursday, July 17, 2014
Retargeting a Windows 8 application to Windows 8.1
Apparently, fuck Windows 8. So says everybody. Including Microsoft. That's why at some point you're going to have to retarget your Windows 8 app (if you were crazy enough to make any) for Windows 8.1. Fortunately, Microsoft provides a guide for doing so in Visual Studio 2013 here. Fortunately, it's as simple as right-clicking on your solution in the Solution Explorer and clicking on Retarget for Windows 8.1
Tuesday, July 15, 2014
Making TFS builds consistent with desktop builds when invoking MSBuild directly on a .*proj file
As it turns out, MSBuild has more than a few quirks when being invoked through TFS compared to being invoked through a command line or from Visual Studio. Some of them are pretty well documented. Others are not, like the fact that in a .*proj file, the OutDir variable is inherited to sub-MSBuild tasks. There's also quirks because OutputPath is used to determine OutDir, but not in all cases. If you're going to specify OutputPath in the properties when invoking the MSBuild task, you should also explicitly override the OutDir variable as well to ensure consistency, unless you **TRULY** understand the differences between the two and how MSBuild determines OutDir, and you **REALLY** want it to be that way.
Thursday, June 26, 2014
Getting code signing to work with ClickOnce on a TFS Build Agent
Code signing is a giant pain in the butt. You have to :
- Obtain the certificate for signing the code by:
- buying the certificate from an issuer.
- generating your own self-signed certificate
- Configure ClickOnce within your project file with the following property elements:
- <signmanifests>true</signmanifes>
- <manifestcertificatethumbprint>A387B95104A9AC19230A123773C7347401CBDC69</manifestcertificatethprint>
- Log into your machine **as the user running the build controller / agents ** and import the key to their user Personal certificate store!
- Run 'certmgr.msc' from the Run command in the start menu (WinKey + R is the hotkey)
- In the Certificate Manager that comes up, go to Personal in the tree, right-click, and select All Tasks -> Import ...
- In the Certificate Import Wizard window that comes up, select Next to move to the 'File To Import' screen.
- Select your certificate file, which has the same thumbprint as specified in your project file, then click Next to move to the 'Certificate Store' screen.
- In the 'Certificate Store' screen, select the 'Place all certificates in the following store' option, then click Browse to select the store. Choose 'Personal' in the selection window. Click Next to move to the "Completing the Certificate Import Wizard" window.
- On the "Completing the Certificate Import Wizard" window that comes up, click Finish to import the certificate.
You should now be able to build and sign your code on a TFS Build controller / agent.
Labels:
agent,
build,
certificate,
clickonce,
code,
controller,
sign,
tfs,
thumbprint
Sunday, June 22, 2014
Converting an existing Windows Store app to using the Prism Framework
I began converting an existing Windows Store App to using the Prism Framework provided by Microsoft. However, I'm running into the following error:
The primary reference "Microsoft.Practices.Prism.StoreApps" could not be resolved because it was built against the ".NETCore,Version=v4.5.1" framework. This is a higher version than the currently targeted framework ".NETCore,Version=v4.5".
This post on stackoverflow.com recommends installing the Microsoft Build Tools 2013 package, which is available here:
http://www.microsoft.com/en-ca/download/details.aspx?id=40760
That didn't work.
I later realized that I had installed Prism with NuGet, so I went and checked the publishing dates on the versions. The latest (and default, which I had installed) was 1.1.0. The date on 1.0.1 was much older, and after reverting to that version, I was able to get my program to compile and run with a few modifications to the steps in this tutorial. The modifications are as follows:
The primary reference "Microsoft.Practices.Prism.StoreApps" could not be resolved because it was built against the ".NETCore,Version=v4.5.1" framework. This is a higher version than the currently targeted framework ".NETCore,Version=v4.5".
This post on stackoverflow.com recommends installing the Microsoft Build Tools 2013 package, which is available here:
http://www.microsoft.com/en-ca/download/details.aspx?id=40760
That didn't work.
I later realized that I had installed Prism with NuGet, so I went and checked the publishing dates on the versions. The latest (and default, which I had installed) was 1.1.0. The date on 1.0.1 was much older, and after reverting to that version, I was able to get my program to compile and run with a few modifications to the steps in this tutorial. The modifications are as follows:
- Change the return type of the App.OnLaunchApplication method to 'void' to match the 1.0.1 version of the Prism.StoreApps library.
- In the App.OnLaunchApplication method, ensure that there's a call to :
- NavigationService.Navigate("Main", null); where "Main" is the initial page name, and there's a MainPage class in your Views folder.
- Move the existing MainPage class into the Views folder in the root of the project.
Creating my first Windows 8 store app
As you may or may not be aware, there are multiple types of applications that can be created for Windows 8:
- Windows store apps, which use the new Metro interface
- Desktop-based apps which are like those created for previous versions of Windows that can still run in the Desktop app.
I'm quite familiar with creating WPF apps for Windows, but Metro apps are new, and those are what I'll be working on. With that in mind, Microsoft provides the Prism framework which helps provide additional classes, interfaces, events etc to help people develop Windows Store apps that keep consistent with Windows 8 design principles and help the apps perform properly. I'll be starting with the MSDN link here.
Beginning to work with Windows Store apps
I really hate Windows 8. I think the majority of the applications that have been written for it are complete pieces of shit, for the following reasons:
- The developers who wrote them didn't pay any attention to Microsoft's best practices and they :
- perform poorly
- don't follow UI conventions and are hard to understand as a result
- crash
- don't always save data properly
- Many are piss-poorly written and adapted by third party developers for first-party systems because those first-parties don't want to write software in a competing ecosystem, and instead want to force users to use their ecosystem, which has their own set of flaws and deficiencies. Case in point: Google. At the time of this writing, there are no native Windows 8 applications put out by Google. There's no native YouTube app for Windows 8 (which there damn well should be), presumably because those fuckers couldn't find a good way to generate advertising revenue in a Windows 8 app. (can't really blame them for that because if I see ads in an app, I immediately delete it from my device without hesitation. I can't stand that shit.)
- Windows 8 is a shit operating system. It was built on the new Modern interface (aka Metro), and initially had piss-poor integration with the desktop paradigm on which all previous incarnations of Windows were based. Add to this the fact that Microsoft didn't give people an easy choice of which paradigm they wanted to use right off the bat, and the fact that in successive iterations like Windows 8.1 they've tacked on hacky additions to make the Metro interface more like the previous desktop interface, you end up with a shitty operating system that's a pain to use; this pain stems from the fact that it's a horrible amalgamation of multiple user interface paradigms.
As long as Microsoft continues to force their shitty iterations of Windows on the world, I, as a software developer, will be forced to deal with it because of the immense investment most employers have in Microsoft technology. With that in mind, I'm going to start learning Windows 8 applications so that I can make myself more marketable to employers everywhere. I'm going to document my learning here for my usual reasons:
- So that I have a reference for myself for the future
- So that others may learn more easily what I have learned.
Tuesday, June 17, 2014
Resolving ssh: connect to host xxx.xxx.xxx.xxx port 22: Connection refused
There are a number of reasons why an SSH server may fail to allow a client to connect. Many aren't readily apparent, even from tailing system log files or using ssh -v on the client. Here are some of the ones I've encountered:
1. Incorrect permissions / ownership on the key files in /etc/ssh/
2. Incorrect permissions / ownership on the ~/.ssh/id_rsa private key file of the user as which we're trying to connect. I'll add more to this list as I encounter them.
3. systemd just plain being a piece of shit. Running 'systemctl restart sshd.socket' has fixed the problem in the past.
1. Incorrect permissions / ownership on the key files in /etc/ssh/
2. Incorrect permissions / ownership on the ~/.ssh/id_rsa private key file of the user as which we're trying to connect. I'll add more to this list as I encounter them.
3. systemd just plain being a piece of shit. Running 'systemctl restart sshd.socket' has fixed the problem in the past.
Wednesday, May 28, 2014
Apache fails to handle requests with "libgcc_s.so.1 must be installed for pthread_cancel to work"
I recently had an apache2 server go down while I was using it. I still don't know what caused it, but I do know how I fixed it, thanks to this thread on Launchpad. Adding libgcc_s.so.1 to the ld pre-load got me back up and running.
echo "/lib/i386-linux-gnu/libgcc_s.so.1" >> /etc/ld.so.preload ldconfigThe value echoed is the path to the libgcc_s.so.1 file on your system. It can be found with:
gcc --print-file-name=libgcc_s.so.1I hope this helps anybody who has a similar problem.
Thursday, April 03, 2014
Waiting for the network to be up on the BeagleBone Black
It finally hit me today as I was reading over this article, and it should have hit me sooner. The article mentions that in order to get past the network startup hurdles in systemd, you need to wait on the NetworkManager service. However, I use connman. It didn't occur to me until today that they provide exactly the same functionality, and I just needed to swap one with the other. Now, I have all my network dependent programs simply After=connman.service in the systemd service descriptor files, and they're golden.
ImportError: No module named pkg_resources when trying to use pip on the BeagleBone Black
I've recently been trying to use Python on the BeagleBone Black, for a number of reasons:
- I want to learn a new language which could be useful to me in another job in the future (and this job, even better!)
- Given all the effort I've put into making our embedded systems work on multiple platforms, I think I've finally got enough infrastructure in place that we can start leveraging other cross platform products to shorten up our development time.
- As a scripting language capable of using bindings to other languages, Python should help me create very functional code that doesn't need extremely high performance in a very short amount of time and reduce my development time for complicated tasks.
Unfortunately, like many other things on the BeagleBone Black, things aren't going as well or as simply as you'd think they should at first glance. For starters, the pip package manager for Python isn't installed by default on the BeagleBone Black (at least not as of the 2012.12 image). So, I had to install that first:
opkg install python-pip
When I tried to run the package manager, I ran into the following error:
Traceback (most recent call last):
File "/usr/bin/pip", line 5, in
from pkg_resources import load_entry_point
ImportError: No module named pkg_resources
After Googling around for a bit, I found these questions on Stack Overflow. Apparently you must also have the setuptools package installed in order to be able to use pip because it's not a simple package manager like apt in Ubuntu. It's more like emerge in Gentoo, where it downloads code packages and is capable of compiling them and performing custom installations. Fortunately, there's an opkg package for that:
opkg install python-setuptools
After that was installed, it became a simple matter of finally importing the actual package that I originally wanted that started all of this:
pip install psutil
... the process utils library for Python
Friday, March 21, 2014
Undefined reference to `log' when compiling on Ubuntu 13.10 with gcc
After I upgraded to Ubuntu 13.10, I inexplicably started getting errors in a build that had been perfect for a very long time. It turned out, there was a significant change in the linker and a bug introduced. The fix is described beautifully on this blog post, but for convenience sake:
Add '-Wl,--no-as-needed' to your LDFLAGS
Add '-Wl,--no-as-needed' to your LDFLAGS
Labels:
--no-as-needed,
13.10,
error,
gcc,
ld,
LDFLAGS,
linker,
salamander,
saucy,
ubuntu
Monday, March 17, 2014
Slow login times in Ubuntu 13.10 (not just SSH)
I recently setup a new install of Ubuntu 13.10 for a server and found that a lot of my login times were slow when remotely logging in (and not just via SSH). The culprit turned out to the the /etc/nsswitch.conf file:
This line:
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns 4 mdns
Should be changed to this line:
hosts: files dns
... to resolve the issue
This line:
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns 4 mdns
Should be changed to this line:
hosts: files dns
... to resolve the issue
Thursday, March 13, 2014
Developing a cape for the BeagleBone (Black)
Due to the needs of our company, we're developing an in-house cape for the BeagleBone Black to integrate it with our equipment. Yes, there are numerous capes already in existence, but they each provide a singular function that would require stacking in combination with other capes to meet our needs. Additionally, it increases the number of external vendors on which we must rely to meet our demands. Instead, we've chosen to create a custom cape that has multiple extensions on the same cape and integrates nicely with our existing board stacks. Unfortunately, I'm not that familiar with BeagleBone Black capes, so I'm going to be learning how to create the software necessary for a new cape and configure it using the Device Tree system on the BeagleBone Blacks. I'll be tracking my progress and things that I've learned on this blog for my own future reference and hopefully it'll even help out somebody else.
Friday, January 31, 2014
Recovering the root password on a BeagleBone Black
I recently went to use a BeagleBone Black board on which I'd never booted from the eMMC before (that I could recall) and had been instead booting off of a microSD card. To the best of my knowledge, the root password on this board should never, ever have been changed from the default (blank password), but apparently it was. None of the passwords that I had ever used for any of my BeagleBone Blacks was working, which created a problem: I needed to recover the root password to this BeagleBone Black so that I could use it for my projects again. I was in luck. The BeagleBone Black has the tools that I needed to do it. I'm writing this blog post (like many other posts in the blog) so that I can have a reference to come back to if I ever need it in the future.
To recover the root password of a BeagleBone Black, you'll need the following items:
To recover the root password of a BeagleBone Black, you'll need the following items:
- A 5V, minimum 1 A dedicated power source (you shouldn't really be powering the board off of the micro USB port)
- An SD card (and reader, of course)
- An FTDI USB-to-serial cable for accessing the debug serial port of the BeagleBone Black.
- Flash the SD card with an image that you can obtain from BeagleBone.org/GettingStarted.
- Insert the SD card into the *unpowered* BeagleBone Black.
- Apply power.
- The BeagleBone Black should boot from the SD card (assuming that you've flashed the correct image)
- Connect the FTDI serial cable to the board and your compter, and open your serial client of choice to connect to the board.
- Hit enter once or twice, and a command prompt should come up, assuming you've used the correct settings:
- 115200
- 8N1
- Log in using root and a blank password (should be the default on the SD card image that you downloaded from the BeagleBoard.org website.)
- Mount the eMMC flash: mount /dev/mmcblk1p2 /media/card
- Change the root of the file system to be the partition on the eMMC flash which you just mounted: chroot /media/card
- Change the password of the root user to something you know: passwd root
- Exit out of the changed root: exit
- Shutdown the BeagleBone Black : shutdown -h now
- Disconnect the power from the board
- Eject the microSD card.
- Reconnect the power to the board
- Watch the board boot up, and log in as root. You should be able to log in with the password that you just set.
Implicit rules with Makefile
In my ongoing quest to make my builds less complex and faster, I've been going through my Makefiles and trying to learn as much as possible to simplify it and leverage Make as much as I can. To that end, I discovered something incredibly useful today that I suppose I would have known had I taken the time to read the man page for Make:
This command will list all of the implicit rules for make, which you can then use to optimize the living crap out of your Makefile.
make -p
This command will list all of the implicit rules for make, which you can then use to optimize the living crap out of your Makefile.
Thursday, January 02, 2014
Installing NTP on an Ubuntu server
NTP is used to synchronized time between machines. You can read the Ubuntu HOWTO here.
Installing a TFTP server using xinetd on Ubuntu
I recently had need to redo an old server that had been running an ancient Gentoo installation for which there was no longer a software upgrade path, so I chose to install Ubuntu on it. Part of the requirements of the server were that it runs a TFTP server for hosting files for configuring embedded devices. I had previously found an article on how to setup TFTP through inetd, but I could find it, so I'm cobbling this tutorial together from various sources.
- # apt-get install xinetd tftpd
- Ensure that the following lines are in the /etc/services file:
- tftp 69/tcp
- tftp 69/udp
- Open the /etc/xinetd.d/tftp file (create it if it doesn't exist) and ensure that it contains the following:
# default: off # description: The tftp server serves files using the Trivial File Transfer \ # Protocol. The tftp protocol is often used to boot diskless \ # workstations, download configuration files to network-aware printers, \ # and to start the installation process for some operating systems. service tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot disable = no } # /etc/init.d/xinetd restart
Test the server:# tftp localhosttftp> get hello.txt Received 23 bytes in 0.1 seconds tftp> quit
Wednesday, November 13, 2013
Digging into Raspberry Pi: Part 2
So, further into my quest to build a control system with the Raspberry Pi, I've been looking around at ways to have simple input from the user for a simple system. The first thing that came to my mind was using an Xbox controller to provide input from the user:
- It's simple for the user to use, and given that many people grew up with game consoles, it'll be intuitive and not require retraining the user.
- The Xbox controller plugs into USB and should therefore provide an easy way to integrate a controller for my system.
- The command to download joystick support for the Raspberry Pi was dead simple:
- sudo apt-get install joystick
Sunday, November 10, 2013
Digging into Raspberry Pi
I've recently purchased several Raspberry Pi boards so that I could use them with the RasPlex distribution to run Plex clients and connect them to my TVs and stream media from a central box in my house. However, I've now realized that with their ability to output to HDMI by default, I can use them as video controllers for projects at work. On my blog I'm going to document my experiences with the Pi, mostly as a list for me to follow if I ever have to recreate my work.
Today, I started off by doing the following :
1. Running NOOBS
2. Installing Raspbian
3. Used 'sudo apt-get install fluxbox' to install the Fluxbox window manager.
4. 'touch ~/.xsession' and 'vi ~/.xsession' and appended 'fluxbox' to the end of the file to start fluxbox when X starts.
Today, I started off by doing the following :
1. Running NOOBS
2. Installing Raspbian
3. Used 'sudo apt-get install fluxbox' to install the Fluxbox window manager.
4. 'touch ~/.xsession' and 'vi ~/.xsession' and appended 'fluxbox' to the end of the file to start fluxbox when X starts.
Tuesday, September 24, 2013
Converting a .cer and .pvk to a .pfx file
The Windows SDK comes with a built-in tool for performing this conversion, the details of which you can find here. The command you'll need looks something like the following :
pvk2pfx /pvk MyCert.pvk /pi inputpassword /pfx MyCert.pfx /po outputpassword /spc MyCert.cer
pvk2pfx /pvk MyCert.pvk /pi inputpassword /pfx MyCert.pfx /po outputpassword /spc MyCert.cer
Wednesday, August 14, 2013
Journey to robust windows services: killing a service that failed during OnStartup and now won't stop (even though Stop() has been called)
I've found that sometimes I don't exactly get my service configuration right the first time, and this can cause a failure when calling OnStartup. As a result, when I call Stop() during the exception handling in OnStartup(), the service gets stuck in the 'Stopping' state in the services manager. Here's a quick command line to help you out with that :
TaskKill /F /FI "Services eq [service name as diplayed in the service's properties]"This will get your process knocked off so that you can resume debugging and building.
Thursday, August 08, 2013
System.ArgumentException: Unable to find the requested .Net Framework Data Provider when using SQLite with MSTest unit tests in Visual Studio 2012
I recently encountered the exception in the post title while migrating solutions from Visual Studio 2010 to Visual Studio 2012. Going back and forth between versions, the problem only occurred for me in Visual Studio 2012, it otherwise did not appear in 2010. I ran across this post on StackOverflow about another developer in a similar circumstance, but I didn't want to depend on whatever machine I was using having the SQLite Db Provider installed in the GAC, so I chose a different route: I added [DeploymentItem]s for each of SQLite.Interop.dll, System.Data.SQLite.dll and System.Data.SQLite.Linq.dll to the top of each of my test suites that require them. It's perhaps not an ideal solution, but it does seem to be the most pragmatic one for my circumstances.
Sunday, August 04, 2013
Journey to robust web services: Fixing an error 404.3 message in IIS 7.0 / 8.0
I've recently had to go out of town, and only had my personal laptop to take with me. I usually develop in a Windows 7 environment with IIS 7.0 / IIS Express 7.5, but my laptop is Windows 8, so of course I have to go through the process of setting up my development environment all over again. One of the common errors I see when setting up a new environment is error 404.3: Not found. I run into it over and over again and when I fix it, it seems like such a trivial thing and I never remember to write down the fix to reduce my setup time in the future. Today that changes. The problem can be caused by a couple of things:
1) You don't have the application setup in IIS. You need to setup the application in IIS, *and* you need to point it to your web project directory.
2) You don't have all the requisite components installed in IIS. In order to properly install WCF, you must have IIS installed, you must have ASP.NET installed, and you must have WCF registered. Up to Windows 7 / .NET 4.0, this means you must have, at some point, run aspnet_regiis.exe -ir. On Windows 8, this means you must have installed ASP.NET 3.5 / 4.5, and installed HTTP activation for each (as well as corresponding activations for any other protocols such as net.tcp.
1) You don't have the application setup in IIS. You need to setup the application in IIS, *and* you need to point it to your web project directory.
2) You don't have all the requisite components installed in IIS. In order to properly install WCF, you must have IIS installed, you must have ASP.NET installed, and you must have WCF registered. Up to Windows 7 / .NET 4.0, this means you must have, at some point, run aspnet_regiis.exe -ir. On Windows 8, this means you must have installed ASP.NET 3.5 / 4.5, and installed HTTP activation for each (as well as corresponding activations for any other protocols such as net.tcp.
Tuesday, June 18, 2013
Journey to robust Windows Services: Overriding the default web site when deploying your applications from the command line
I recently ran into a problem where I wanted to deploy a new application to the default web site on an old IIS 6 instance via MSDeploy on the command line from my build machine. Unfortunately, it decided to deploy the application in a folder immediately underneath the default web site, rather than as the default website itself. This post on the IIS forums provided the solution.
Journey to robust Windows Services: NHibernate throws with System.InvalidOperationException: Unable to generate a temporary class
Recently I've been trying to deploy a new web application to an old machine running Windows Server 2003 (not by choice). When I would start the application, NHibernate would thrown in its class constructor with a message along the lines of :
System.InvalidOperationException: Unable to generate a temporary class (result=1).
error CS2001: Source file 'C:\WINDOWS\TEMP\wz58eig4.0.cs' could not be found
error CS2008: No inputs specified
The problem was caused by the fact that the user under which I was running the application didn't have access to the 'C:\Window\Temp' folder where the temporary folder was being created. The solution was simple: update the security settings of that folder to allow Read and List for the Users group. The idea was given to me by answers to this question on Stack Overflow.Friday, May 31, 2013
How to fix the ugly ass Ubuntu boot splash OR Damn, Ubuntu, you ugly
TL;WR: http://news.softpedia.com/news/How-to-Fix-the-Big-and-Ugly-Plymouth-Logo-in-Ubuntu-10-04-140810.shtml
If you've had Ubuntu for a while and you've got an nVidia video card, chances are you've got the ugly ass default boot screen. Fortunately, you can fix this. You just need to follow the instructions above. I hope you're comfortable with the command line.
If you've had Ubuntu for a while and you've got an nVidia video card, chances are you've got the ugly ass default boot screen. Fortunately, you can fix this. You just need to follow the instructions above. I hope you're comfortable with the command line.
Wednesday, May 29, 2013
Changing the password complexity requirements on Windows Server
To change the password complexity requirements on Windows Server (2008 at least) (for whatever reason), do the following :
Start -> Run -> gpedit.msc -> Computer Configuration -> Windows Settings -> Security Settings -> Account Policies -> Password Policy
Then in the right-hand policy pane, set 'Password must meet complexity requirements' to 'Disabled' (right-click -> Properties)
Saturday, May 25, 2013
Journey to robust windows services: Service could not be installed. Verify that you have sufficient privileges to install system services
This is an annoying and almost entirely useless error. It can be caused by any number of things. However, in my case today, it was caused by the fact that the EventLog Source hadn't been created when I tried to install my Windows Service using the WiX installer that I had developed (which it turned out wasn't quite complete). Fortunately, WiX (at least as of 3.5) has built-in support for creating Windows Event Log sources as part of the installation process. Fortunately, I was able to rely on this article on stackoverflow.com to guide me through the process. The gist of the article:
- Add the "http://schemas.microsoft.com/wix/UtilExtension" namespace to your .wxs file root XML element
- Add a util:EventSource Log="Application" Name="MyServiceLogSourceName" EventMessageFile="%SystemRoot%\Microsoft.NET\Framework\v2.0.50727\EventLogMessages.dll" element to each component which requires an Event Log source
- Problem solved
Thursday, May 16, 2013
Journey to robust windows services: debugging your WiX custom actions
I've recently had some trouble getting WiX custom actions to work, and after searching around for a while, I found this article. It gives the reader two options for how to debug WiX custom actions, but I had to use both in combination to get it to work. I'll repeat the steps here, just in case the link goes stale:
- Follow all the necessary steps to create a WiX setup project, along with a separate Custom Action project (available as a project type in the New Project dialog in Visual Studio 2010+ with WiX 3.7)
- After you've created your custom action method and gotten the project building, add System.Diagnostics.Debugger.Launch(); at the beginning of your custom action method. This will kick the custom action into the debugger so that you can debug it (assuming you've got the wixpdb in the same directory from which you launched the installer).
- Go to Control Panel -> System -> Advanced System Settings -> Advanced (tab) -> Environment Settings (button) -> System Variables (group) -> New .... (button)
- In the dialog that comes up, create a new variable called 'MMsiBreak' (without the quotes) and give it the value of your custom action method (e.g. MyCustomActionMethod)
- Now run the debug version of your installer and it should get kicked right into your method and allow you to debug your custom action.
Tuesday, May 14, 2013
Journey to robust windows services: creating custom actions for your WiX installers
I've lately been trying to update my WiX installers to perform custom actions so that I can do some security configuration of my applications after they're installed. I got started with this article on CodeProject, but it was missing some information. Apparently, in addition to creating the separate project for the CustomAction DLL, you need to include as part of that assembly a CustomAction.config file with the following contents:
xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup useLegacyV2RuntimeActivationPolicy="true">
<supportedRuntime version="v2.0" />
<supportedRuntime version="v3.5" />
<supportedRuntime version="v4.0" />
</startup>
</configuration>
But what really got the thing working was targeting the CustomAction DLL to .NET framework v3.5, rather than 4.0 because I was getting some bad image format exceptions when trying to run it. Thankfully I found the MSDN article on enabling MSI logging. These two articles on stackoverflow.com also really helped out.
Wednesday, May 08, 2013
Journey to robust web services: installing a WCF 4.0 application on IIS 6.0
Due to budget and other constraints, I'm unable to get my hands on the latest and greatest software for running a WCF application I've been working on, so I'm forced to use what my company's got: Windows Server 2003 and IIS 6.0. Suffice it to say that working with these old bits of software are less than ideal. However, I'm stuck with it. So, moving forward, here's some of the things I found while working on the application:
- There's no easy way to set certain items in the registry for the Network Service user. (Sorry, for various reasons, I can't elaborate on that statement.)
- Due to (1), I've decided to run my application as a custom normal (non-Administrator) user that I've created. However in order to use this user with IIS and its applications, certain steps must be taken.
Using a custom user to run an IIS 6.0 application
The following are pre-requisites in order to be able to use a custom user to run an IIS 6.0 application:
- The user must have already been created and should have absolutely the least number of privileges possible.
- Thanks to this question on Stack Overflow, the following must also have the following:
- The "Log on as a service" right (Start -> Control Panel -> Administrative Tools -> Local Security Policy -> Local Policies -> User Rights Assignment -> Log on as a service)
- "Access this computer from the network" (similar location as in the step above)
- "Deny logon locally"
- "Log on as a batch job"
- "Read & Execute", "List Folder Contents" and "Read" access to the file system that underpins the web site/application
- Thanks to this troubleshooting article on MSDN, I also found out that the user must be part of the "IIS_WPG" group.
Monday, May 06, 2013
Journey to robust web services: apparently we shouldn't use 'using'
I recently stumbled across an article stating why we shouldn't use the 'using' keyword with WCF services, and I found it rather interesting. I'd have to re-read it, and re-evaluate it, before I use it but you can read the blog post on the original site.
Journey to robust webservices: kickstarting use of certificates phase II: using certificates for client authentication
There are a number of means of authenticating users, and one of the most secure is via a certificate. This article on CodeProject provides a start. Unfortunately, the article doesn't really mention a few things:
- Depending on how you ran the tools, you may have inadvertently run the commands it gives you as an administrator. I ran them in a console that I already had open that was running as administrator, so they were installed as administrator, and I also happened to have been running in Visual Studio as an administrator at the time, so everything happily worked. Then when I rebooted my machine this morning and was running as a normal user, nothing worked, and I wasted over an hour trying to figure out why. That was why. Regardless of how you generated and installed the keys, you should go and explicitly grant permissions on the key to the users you want to have access to them. On the Microsoft website, there is a bundle of WCF samples (which you can find here). Included in the samples is a tool called FindPrivateKey. Download the samples, compile the program, and use it to find the key that you just generated. You'll need a command similar to the following : "C:\Samples\WCFWFCardSpace\WCF\Tools\FindPrivateKey\CS\bin\FindPrivateKey.exe My LocalMachine -t "28 ce e3 2c 7e 05 3a 97 a0 b4 92 fd d5 b0 f9 de 0e 4c 2e 4b"" where the value in quotes is the thumbprint of the non-signing (client) key you generated in the instructions from the article. Once it spits out the location of the file, you'll need to go and alter its permissions to allow whatever user your server / client application is running under access to the file.
- Depending on the binding you're using with WCF on the server side, you may need to have a certificate with full chain trust on the IIS server (or other?) in order to use the binding (*cough* basicHttpBinding and any other transport-only security bindings *cough*). With that in mind, after you've generated the certificates in the article, while you're in the certificate manager MMC snap-in, you'll also need to copy (not move) the IIS developer certificate used in IIS to the "Trusted Root Certification Authorities" store.
Journey to robust web services: kick starting use of credentials and certificates for message security, phase I
As any sensible developer of a large scale system knows, security is paramount. Therefore, encryption of sensitive data is an absolute must, encryption of all data is recommended, depending on the field in which you're working. Encryption with WCF is baked in, and is relatively straight forward to setup, though there are a number of important details to which attention must be paid. The steps are somewhat different depending on whether you're using IIS or a self-hosted service (e.g. in a Windows Service).
If you're using a Windows Service, you'll need to perform the following steps to get started:
If you're using a Windows Service, you'll need to perform the following steps to get started:
- Generate a self-signed certificate (which can be done in the Windows Control Panel)
- Configure the port to which you're binding the service with the certificate you've just generated, according to this MSDN article.
- [to be continued]
If you're using IIS, getting started in a development environment is somewhat simpler.
- Generate a self signed certificate with IIS. In most cases, IIS will have a developer certificate already installed that you can use.
- Retrieve the thumbprint of the certificate. You'll need this in order for your application to be able to find it at runtime. WARNING: Don't just copy the thumbprint out of the certificate properties window in IIS, because there are non-printing characters in the text control that will cause you problems when you try to paste the thumbprint into your Web.config file. Write them out by hand.
- There are two methods you can take for making the certificate available to your WCF service:
- Follow the guide here if you want to make the certificate available to your application by code.
- Use the information on this page to create a
element underneath a configuration/system.serviceModel/behaviors/behavior/serviceCredentials element.
Journey to robust web services: debugging services and logging messages
One of the quickest and best ways to debug issues with the services you're developing is to log and trace all activity with WCF along with the messages being sent back and forth. This page on MSDN will provide you with the instructions required to setup logging and tracking for WCF.
Sunday, May 05, 2013
Journey to robust web services: my clients are unable to connect!
I've been testing out some web services I've been working on extensively on my own machine, but the time has finally come where I want to start making clients that aren't running on the same machine. In one case, I have a WCF service running on Windows 7, but the client I want to connect to that service is running on Windows 8 on a separate machine. When I tried to connect, I would get a variety of errors, the most common of which being that the socket on the server was forcibly closed. I Googled around a bit, and the most common cause of this problem that I found was that the server's quota's were being reached and therefore the client was being rejected, however this shouldn't have been the case for me since there was no way my quota's could have been reached. After further research, I found that since I don't want security (yet), I had to apply some settings in order for clients that weren't on my localhost to connect. In order to allow external clients to connect, I had to change the following :
- In my
, I had to change my base address to use the network name of my computer (rather than localhost) in the base address URL. - In the net.tcp and ws2007HttpBindings for my services, I had to go to the the
child element of the elements, and explicitly set mode="None" on those elements, otherwise they may assume some form of security by default depending on the type of the binding.
Now, I did mention above that I don't want to add security (*YET*) being the important qualifier of that statement. Security is of course always paramount, and should always be baked into a product as early as possible. As soon as I get to it, I'll add a post about all the steps required to add security to your WCF clients and services, along with links to the relevant MSDN articles (and any other useful ones that I may find.
Friday, May 03, 2013
Mono.Options installation, and getting StyleCop to ignore a file
I've recently discovered the Mono.Options library (available via NuGet) that lets you easily parse arguments passed into a program. Unfortunately, the ease with which a package is typically installed via NuGet does not apply to Mono.Options because it's a single .cs file that gets included in your project, rather than a signed assembly. This becomes an annoyance in projects where StyleCop is used to enforce coding standards. Fortunately, there is a way to get StyleCop to ignore specific files (rather than forcing me to tweak my StyleCop settings for the project) which I found out about here. The TL;DR for that article: edit your project file, and underneath the element for the offending file, insert a <ExcludeFromStyleCop>true</ExcludeFromStyleCop> element.
Tuesday, April 30, 2013
Creating a logging service using the Microsoft Enterprise Library Logging Application Block
As part of my recent foray into creating various Windows services, I've come across the need for logging (like all serious apps do) and decided to use the Microsoft Enterprise Library Logging Application Block. We used it at a previous company and it got very good reviews from the developers there who used it. Unfortunately, all of the tutorials out there are a bit useless when it comes to doing anything real with the Logging Application Block, like using custom configuration. Fortunately, it was easy enough to figure out how to get customized configuration of logging working just by looking in the assembly and writing some unit tests to experiment.
For my needs, I like to keep all of my configuration as compartmentalized as possible. To that end, I usually end up using .NET Configuration files on a per-assembly basis. Fortunately, this works very well with the Logging Application Block because you can configure logging with arbitrary Configuration files. To get custom logging working easily in Visual Studio, do the following:
- Open Visual Studio (I'm using 2010)
- Install NuGet from the Extension Manager, if you haven't already.
- Install EnterpriseLibrary.Config from the Extension Manager if you haven't already.
- Create your solution and project that requires logging.
- If your project (web or application) comes with a .config file already (i.e. Web.config or App.config respectively) you can use that, otherwise, you can create an app.config file for the assembly in which you're creating your logging service.
- Once you've figured out which app.config (or Web.config) file you're going to be using (i.e. the same assembly where you're placing your logging class, right click on the .config file. You should see an 'Edit configuration file' entry with an orange logo (provided by the add-in installed in Step 3 above).
- Follow any other tutorial out there on the internet for configuring the Logging Application Block. (repeating such information here would be redundant and pointless). There's one such article here.
- Now that you've got your configuration, create a class to be your logging service wrapper.
- Figure out where your application config file is going to end up after your application is built.
- In your logging service wrapper, create a Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource, giving the configuration file path as the sole parameter to the constructor.
- Create a new Microsoft.Practices.EnterpriseLibrary.Logging.LogWriterFactory, providing the FileConfigurationSource you just created as the sole parameter. You'll probably want to store this as a static object, because we only need a single factory.
- For each instance of your logging service, use this static factory that you've created to create a LogWriter.
- Implement whatever methods you need to wrap the logging service.
- You're done.
Your code should now look something like the following :
using System;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Text;
using Interfaces;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using Support.Extensions;
///
/// A logging services that uses the Microsoft Enterprise Patterns and
/// Practices library to provide logging support.
///
public class MicrosoftPracticesLoggingService : ILoggingService
{
///
/// The log writer factory
///
private static readonly LogWriterFactory LogWriterFactory;
///
/// Initializes the class.
///
static MicrosoftPracticesLoggingService()
{
string configFilePath = typeof(MicrosoftPracticesLoggingService).Assembly.GetCodeBaseFile().FullName + ".config";
if (File.Exists(configFilePath) == false)
{
throw new InvalidOperationException(String.Format("Configuration file could not be found at '{0}'", configFilePath));
}
FileConfigurationSource configSource = new FileConfigurationSource(configFilePath);
LogWriterFactory = new LogWriterFactory(configSource);
}
///
/// The log writer used by this service to write to logs.
///
private readonly LogWriter logWriter;
///
/// Initializes a new instance of the class.
///
public MicrosoftPracticesLoggingService()
{
this.logWriter = LogWriterFactory.Create();
}
#region Implementation of ILoggingService
///
[SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1604:ElementDocumentationMustHaveSummary", Justification = "InheritDoc")]
[SuppressMessage("Microsoft.StyleCop.CSharp.DocumentationRules", "SA1611:ElementParametersMustBeDocumented", Justification = "InheritDoc")]
public void LogException(Exception ex, string messageFormat, params object[] parameters)
{
if (ex == null)
{
throw new ArgumentNullException("ex");
}
if (messageFormat == null)
{
throw new ArgumentNullException("messageFormat");
}
StringBuilder messageBuilder = new StringBuilder();
messageBuilder.AppendFormat(messageFormat, parameters).AppendLine();
messageBuilder.AppendLine(ex.StackTrace);
if (ex.InnerException != null)
{
Exception root = ex;
while (root.InnerException != null)
{
root = root.InnerException;
}
messageBuilder.AppendLine("Caused by:");
messageBuilder.AppendLine(root.StackTrace);
}
LogEntry logEntry = new LogEntry
{
Message = messageBuilder.ToString(),
Severity = TraceEventType.Error
};
this.logWriter.Write(logEntry);
}
#endregion
}
Sunday, April 28, 2013
Journey to robust web services: debugging a net.tcp service
I'm creating a net.tcp-based WCF web service for use with my current project, and so far the learning curve hasn't been very shallow. I've just recently learned, thanks to this post on Stack Overflow, that the default ASP.NET application doesn't support the net.tcp protocol, so IIS must be used instead. With that in mind, I've decided to move on to just using the Web Service I'm creating through a Windows Service via a ServiceHost. However, I've now encountered some problems debugging the Windows Service startup. This page on MSDN contains links and instructions on how to debug the startup of a Windows Service. While attempting to install the Debugging tools, I encountered a failure trying to install them as part of the Windows 7 SDK. This page on Stack Overflow had a solution, but it wasn't quite complete. This page had the missing parts.
Saturday, April 27, 2013
Journey to robust web services: configuring your WCF web service
WCF comes with a bunch of handy configuration tools. You can find an introduction to them on the WCF configuration tools page on MSDN. Once you've created your WCF service project in Visual Studio, you'll need to use these tools to configure the service beyond a simple and basic test environment (which uses a Basic HTTP binding by default).
The specific tool mentioned on this page that you'll want to use is the Service Configuration Editor (svcconfigeditor.exe). This tool is used to edit Web.config files for WCF services. It comes with a handy wizard for adding a new service. When using this wizard, I ran into an error message similar to the following when trying to select the assembly I built containing my service: "Could not load assembly. This assembly is built by a newer runtime than the currently loaded runtime and cannot be loaded.". To solve this, I had to go and change the application configuration file for the program ("svcconfigeditor.exe.config" in the same directory as the program). I added the following under the root 'configuration' element:
The specific tool mentioned on this page that you'll want to use is the Service Configuration Editor (svcconfigeditor.exe). This tool is used to edit Web.config files for WCF services. It comes with a handy wizard for adding a new service. When using this wizard, I ran into an error message similar to the following when trying to select the assembly I built containing my service: "Could not load assembly. This assembly is built by a newer runtime than the currently loaded runtime and cannot be loaded.". To solve this, I had to go and change the application configuration file for the program ("svcconfigeditor.exe.config" in the same directory as the program). I added the following under the root 'configuration' element:
<startup useLegacyV2RuntimeActivationPolicy="true"> <supportedRuntime version="v2.0" /> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup>
This will allow the program to run using your currently installed framework (mine happened to be 4.0).Friday, April 12, 2013
Finally understand the purpose of event accessors in .NET
As most people who deal with .NET are aware, C# (and also VB.NET) have Properties and Events. In the case of properties, there are property accessors (get and set) which you can leave to the compiler to define, or you can define your own custom accessors. Similarly, there are event accessors (e.g. add and remove) so that you can customize subscriptions to your event handlers. Until today, I never understood why, until I read the MSDN article on Advanced C#. The reason is explained near the end of the section called "Standard Event Pattern", and it's pretty simple and common sense: in classes where you have a significant number of events (e.g. WPF / Forms Controls) and only a few of them are likely to be subscribed to, you can achieve a smaller memory footprint by overriding the event accessors and placing the event subscribers in an internal IDictionary, rather than using compiler-generated event accessors. In the former case, you'll have to store only the subscribers + the dictionary, whereas in the latter case, you'll have to store the subscribers + n events, and the latter is likely to be far larger than the former.
Tuesday, March 05, 2013
Getting error message with XSD MSBuild task
Lately I've been getting the error message :
error MSB4018: Microsoft.Build.Shared.InternalErrorException: MSB0001: Internal MSBuild Error: xsd.exe unexpectedly not a rooted path
... while I've been building a project that uses that task in a pre-build step to generate code from XSDs. After googling around a little bit, I found the solution on this page. The gist of it was that xsd.exe wasn't in the PATH variable, and therefore Visual Studio couldn't find it. If anybody else has this problem, add this folder to your PATH:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
... or your system's equivalent, wherever the XSD.exe tool is stored on your system.
error MSB4018: Microsoft.Build.Shared.InternalErrorException: MSB0001: Internal MSBuild Error: xsd.exe unexpectedly not a rooted path
... while I've been building a project that uses that task in a pre-build step to generate code from XSDs. After googling around a little bit, I found the solution on this page. The gist of it was that xsd.exe wasn't in the PATH variable, and therefore Visual Studio couldn't find it. If anybody else has this problem, add this folder to your PATH:
C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\NETFX 4.0 Tools
... or your system's equivalent, wherever the XSD.exe tool is stored on your system.
Monday, February 11, 2013
Debugging multiple processes and following the children in Eclipse Juno
I guess Eclipse has made it much easier in recent versions of Eclipse and CDT to debug multiple processes and have the debugger follow children. It was actually easier than I had thought it would be to get this functionality in Eclipse Juno. To do so, follow these steps:
- Create your debug configuration, pointing to the project and program you require.
- Ensure that you setup your LD_LIBRARY_PATH in your environment variables as necessary.
- (and here's the really important part) In the Debug Configuration, go to the 'Debugger' tab. You should see a groupbox called 'Debugger Options' containing (at least) two tabs: 'Main' and 'Shared Libraries'. On the 'Main' tab, ensure that you have 'Non-stop mode' and 'Automatically debug forked processes'. In order to get these abilities, you'll need to have both non-stop gdb and multi-process gdb
- As a side note, you may need to also have your debug configuration pointed to a custom gdbinit command file with the following line:
- set follow-fork-mode child
Labels:
cdt,
children,
debbugger,
debug,
debugging,
eclipse,
fork,
gdb,
juno,
multi-process,
multiprocess,
parent
Wednesday, February 06, 2013
Using key gestures with parameterized Commands in WPF is "broken"
Ok, it's not actually broken, it just doesn't work the way I wanted (or expected). Apparently, there's a very good article on why they don't work the way I expected. To be clear, the way I expected them to work was:
- Define the command as a static RoutedUICommand and set the keyboard / mouse gestures I wanted on the command's InputGestures collection.
- Use said command in MenuItems, Buttons etc.
- Automatically have keyboard / mouse bindings setup everywhere (including the nice shortcut text on menu items in context menus / menu bar menus)
Friday, February 01, 2013
Getting the proper Includes to show up in the project explorer in Eclipse with CDT with a cross-compiling project
I finally learned how, and it's thanks to an awesome question posted on stackoverflow.com .
Thursday, January 24, 2013
"Network is unreachable" on an embedded box
We've been working extensively with embedded boxes lately trying to migrate our platform over. One of the programs we've been trying to migrate today was a simple announcer program that sends out a UDP broadcast. On our first go, the program wouldn't work, saying that the "Network is unreachable" when doing a 'perror' after the call to 'sendto'. After much experimentation with various network binding flags, etc, which took the whole day, I went into overtime trying to figure out the problem. Eventually, I got to the point where I inspected the routing tables of the embedded system and was shocked to find .... there was no routing table entry for the default gateway, i.e. 0.0.0.0 destination IP. I'm actually kind of ashamed of how long it took me to find this, but in my defense, I was dealing with a wild mixture of systems and had done a lot of network reconfiguration with the systems and some of the stuff was handled automatically for me by my Ubuntu box, which gave me some inconsistent results at times when experimenting. For my own future reference, here's how I solved the problem:
- Run 'route -n'
- Ensure there's an entry that looks like the following :
- Destination: 0.0.0.0 Gateway: [the desired gateway, e.g. 192.168.10.1] Genmask: 0.0.0.0 Flags: UG, Metric: 0, Ref: 0, Use: 0, Iface: eth0 (or eth2, or whatever you may have)
- If the above entry doesn't exist, add it with the following command:
- sudo route add -net 0.0.0.0 netmask 0.0.0.0 gw 192.168.10.1 dev eth0
Friday, January 18, 2013
Synchronizing with a remote SVN repository
We recently had a double hard-drive failure on our RAID 5 on our main server at work, and we lost our stuff. Our primary backup method of that system had completely failed due to the incompetence of some of the staff in our parent company that was completely beyond our control. It's only by the grace of the fact that our IT guy had an extra weekly backup that we were able to recover as much as we were. That said, it brought to light the need to have our own extra backups of our source code because we can't rely on the people we're supposed to be able to rely on to do the backups for us. We're now going to be creating our own copies of the SVN server on a semi-daily basis, and I've found instructions on how to do it on this awesome StackOverflow post. I'm just sorry I didn't know about this sooner.
Cross-compiling libexpat (and other libraries)
So, lately I've been trying to cross-compile libexpat for a new board with a different architecture from what we typically use at work, and I've been having one heck of a time, until I finally got help online from my question at stackoverflow. Turns out, I just needed to be more specific about my host architecture in the configure command:
./configure --host=arm-none-linux --enable-shared CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ AR=arm-none-linux-gnueabi-ar RANLIB=arm-none-linux-gnueabi-ranlib STRIP=arm-none-linux-gnueabi-strip
I'm going to try similar recompilation with other libraries so that I can improve the functionality of our older systems as well.
./configure --host=arm-none-linux --enable-shared CC=arm-none-linux-gnueabi-gcc CXX=arm-none-linux-gnueabi-g++ AR=arm-none-linux-gnueabi-ar RANLIB=arm-none-linux-gnueabi-ranlib STRIP=arm-none-linux-gnueabi-strip
I'm going to try similar recompilation with other libraries so that I can improve the functionality of our older systems as well.
Tuesday, January 15, 2013
Journey to robust Windows Services
Because I have the need for it in several projects, I'm going to be working with Windows Services implemented with .NET quite a bit in the next little while. That said, I'd like to refer to some resources for working with Windows Services:
- The MSDN page on creating windows services
- The MSDN page on debugging a Windows Service
- The MSDN page on installing and uninstalling Windows Services
Also, there are some issues that I ran into while working on my first service. I had originally planned to expose a WCF endpoint through WS-HTTP, however, I can into an unpleasant exception when I tried to do so: AddressAccessDeniedException. Apparently, the cause of this is the fact that http bindings are reserved for processes run as administrators. Fool me once, shame on me. In light of that fact, I'm switching over to using net.tcp for my local Windows Service-hosted WCF service. I'll post more here as I learn it.
Adding the Network Service account to the permissions for a file/folder/registry key etc
I'm currently developing a Windows Service that's to be run under the Network Service account (owing to the fact that it requires substantial network access). I'm just starting to learn how to program Windows Services, so this is very new to me. I just started developing a simple service to start, and when I followed the instructions on this MSDN page, I was surprised when, after trying to start my service, I got the error 005: Permission denied. I later found out that I needed to give the network service account to the folder from which the service was running, i.e. the debug output folder of my project. Doing this isn't as simple as setting the permissions for other users. To add the network service account to the permissions list in Windows 7, do the following :
- Right click on the folder containing the service you want to debug, and go to Properties
- Go to the Security tab, and under the box marked "Group or user names", click on Edit ...
- Under the window that pops up, you'll see another box marked "Group or user names". Underneath that box, click on Add ...
- In the "Select Users or Groups" dialog that pops up, click on the Advanced... button at the bottom left.
- In the advance "Select Users or Groups" dialog that pops up, click on Find Now to find all the users, groups and built in security principals.
- Once the search results are populated, scroll down and select "NETWORK SERVICE" (not "NETWORK") and click on Ok, then Ok again in the Select Users or Groups dialog.
- One you're back to the Permissions window, ensure that you give the Network Service account Full Control over the folder in the Permissions box, then click Ok.
- Click Ok one last time to close the properties for your folder, and you're done.
Sunday, January 06, 2013
Wpf2WinRT: Bindings are not the same!
I've just learned something new about the bindings system in WinRT: they're not the same as Bindings in WPF. Check out the MSDN page for WinRT BindingMode, and you'll see that they're missing a value from WPF: OneWayToSource.
Migrating from WPF to Windows 8
As part of the ongoing development efforts at my company, I'm always researching the latest technologies and developments. My latest endeavour is researching Windows 8 and doing technical feasibility work to find out if it's right for us. On that front, I'm learning how to develop for the Windows 8 runtime in C#. I've got a lot of experience in WPF, and our current Line-Of-Business application is written in WPF, so I'm used to certain things, things which I'm finding no longer hold true in WinRT programming. For example, how resources such as strings are accessed in XAML. For WPF, if I wanted the internationalized string for a label, I'd do something like this :
<Label Text="{x:Static resources:Messages.UserName}"/>
However, the x:Static XAML extension no longer exists. Instead, you have to follow the *very different* ways of accessing string resources on this MSDN document, because the means of accessing resources for a WinRT application are both simpler (in some ways) and more robust, if a little bit confusing at first.
For string (and even other resources, such as images) internationalization in WinRT, what you do is this:
1. Create a folder path for your strings: \Strings\en-US
2. Under the aforementioned folder, create a resources file named Resources.resw (not that it's not .resx, as with previous .NET applications written in Windows Forms, WPF and ASP.NET)
3. Add a new string with the Name "ApplicationName.Text". The ".Text" suffix is very important; you'll see why in a minute.
4. In your XAML, create a TextBox like this:
<TextBlock x:Uid="ApplicationName" Text="" />
The Uid attribute is used for associating controls with resources, according to the MSDN link provided above, and the .Text suffix in the resource Name column, specifies the property to which the resource is linked.
Honestly, I'm not sure I like the way this is going, but if it reduces code clutter, I'm willing to at least give this a try. We'll see how this pans out.
Wednesday, December 19, 2012
Finding the public key and public key token of an assembly for use with InternalsVisibleTo
It seems like one of the most common problems out there when it comes to testing and dealing with strongly-named assemblies is getting the public key and the public key token of a CLR assembly when you want to create test projects for that assembly. The quick and easy way:
1. Ensure that 'sn.exe' is in your path. If it's not, it's usually in the Windows SDK directory, typically in a folder like : C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\sn.exe
2. Open up a command window, and navigate to the directory containing the snk you're signing your assemblies with.
3. sn -p my.snk Public.snk
4. sn -tp Public.snk
...and voila, the program will print out the public key and public key token to the screen for you. The reminder I found this at was here. After you've found the public key, you'll want to paste a line similar to the following in the AssemblyInfo.cs file of the project whose internals you wish to expose:
[assembly: InternalsVisibleTo("MyCompany.ProjectName.Tests,
PublicKey=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX")]
Changing the default URI of a WCF web service
I recently returned to one of my previous employers since they lured me away with a better employment offer than I was currently receiving. I'm now placed on a large scale project to revamp our equipment and our software, and improve our software services to the point where we have absolute control and communication with our software out in the field. To that end, I'm presently writing a service that our field personnel's laptops will use to communicate with our home office. I've decided to implement the service in WCF since I've got experience with it and it will be the quickest route to getting a working service deployed. There are other reasons for the choice, but we won't go into those at the moment. One of the things I had forgotten about was the best practice of changing the default namespace of the service away from tempuri.org. I found an article here to remind me of how to do it, so hopefully others will be able to find it as well.
Sunday, September 16, 2012
Previews with a DataContext in WPF
Both the company I currently work for and the previous company I worked for use WPF extensively in some of their products. I recently ran across an incredibly helpful bit of functionality that aids in designing controls and forms on this blog. The TL;DR is that it lets you specify the data context that's supposed to be associated with a window / control, and lets you preview the control at design time using design data. This is useful because it lets you get an idea of what the control is going to look like with real data, and can be especially helpful when trying to size controls on a form, or seeing what lists are going to look like, and will be a real time saver because it means you no longer have to compile and start the application in order to view styles on things like DataTemplates.
Sunday, June 26, 2011
Deleting more Subversion folders
Further to my previous post on deleting subversion folders with powershell, I recently had the need to do the same in bash on linux. Here's a useful little command :
find . -name .svn -exec rm -rf {} \;
Wednesday, October 13, 2010
Determining what ports Tomcat is running on
I've recently had problems connecting to a Tomcat server setup by another developer. In order to troubleshoot these problems, I wanted to use netstat to see what ports were being bound to, but apparently server sockets don't come up by default. If you really want to see what server sockets are in use on your machine, use the following :
The undocumented 't' option will cause netstat to show server sockets.
netstat -lntp
The undocumented 't' option will cause netstat to show server sockets.
Friday, October 01, 2010
Event models in Silverlight vs WPF
To really understand the event model in Microsoft's Silverlight / WPF frameworks, you need to start off with a proper mental model. You can think of the root XML element in a XAML object as being at ground level. Each successive child XML element goes deeper into the ground. With that in mind, there's two terms that are used in both of these frameworks to describe how event handlers propagate between objects : Bubbling and Tunneling. With Tunneling, event handlers start at the root XML element, and "tunnel" deeper into the "earth" (your control stack) until they get to the original source of the element, which is your controls. With Bubbling, event handlers start at the original source of the element (your control which initiated the event), and then "bubble up" to the root control. We use the earth analogy because the terminology goes hand in hand with gravity : tunnelling follows gravity, like digging into the earth, and bubbling goes against gravity, like a bubble coming up to the surface from the bottom of the ocean. I never really had a clear mental model of the Silverlight / WPF event models until right now.
With all that said, there are some differences between Silverlight and WPF that turn out to be very important when it comes to implementing your event handlers, and maintaining compatibility between the two. The biggest difference is that WPF supports both Bubbling and Tunneling events, whereas Silverlights supports only Bubbling events. Keep this in mind if you're designing desktop applications that you might want to port over to web applications at some point
With all that said, there are some differences between Silverlight and WPF that turn out to be very important when it comes to implementing your event handlers, and maintaining compatibility between the two. The biggest difference is that WPF supports both Bubbling and Tunneling events, whereas Silverlights supports only Bubbling events. Keep this in mind if you're designing desktop applications that you might want to port over to web applications at some point
Thursday, September 30, 2010
Holy crap, a Windows ramdisk program that works
In the past, I've had a bit of experience trying to install and run ramdisks in Windows XP, but I never found anything really good. Microsoft provided a ramdisk driver for Windows 2000 that one could get working in XP, but it wasn't really useful because it only provided a maximum of 32 MB of storage (Why ?!). I decided to revisit the issue of ramdisks at work today for Windows 7 because I wanted a way to speed up Visual Studio's caching and other operations (and Eclipse, but that's another matter). After searching around some more, I found a program called ImDisk. The installation is dead easy (if a little lacking in the notification department to tell you it's successfully installed). What's even better, you can make disks of arbitrary size, have it simulate various kinds of devices, and you can setup multiple ramdisks. The only catch is that you have to start the service in Administrator mode, and it's a bit more than trivial, though it is easy using the following steps :
1. Start -> All Programs -> Accessories -> Command Prompt -> Right-click -> Run as administrator
2. sc config imdisk start= auto (note the space between start= and auto, this got me the first time)
3. net start imdisk
4. Open up Control Panel -> ImDisk Virtual Disk Driver
... and have at it!
1. Start -> All Programs -> Accessories -> Command Prompt -> Right-click -> Run as administrator
2. sc config imdisk start= auto (note the space between start= and auto, this got me the first time)
3. net start imdisk
4. Open up Control Panel -> ImDisk Virtual Disk Driver
... and have at it!
Friday, September 17, 2010
Editing your file system mappings for TFS paths
So, as you may or may not know, when using Microsoft Team Foundation Server for version control, TFS maps remote project paths into local file system patmhs for checkout, etc. As I learned today, there are times when you check out the wrong path, and/or map it to the wrong path in the file system. If you ever need to modify or just nuke your file system mappings in TFS, here's how you go about doing it :
Once you've selected your workspace in the dialog that comes up (you'll likely only have one anyway), click on :
... and then select the folder to file system mappings that you want to remove, or create whatever new file system mappings you want right there.
Team Explorer -> Source Control (double click) -> Workspaces (dropdown) -> Workspaces ...
Once you've selected your workspace in the dialog that comes up (you'll likely only have one anyway), click on :
Edit ... -> Working Folders
... and then select the folder to file system mappings that you want to remove, or create whatever new file system mappings you want right there.
Starting a new job ... and a new philosophy
Ok, so I've left my previous employer and started at a new job. This means new domains of knowledge, new tools, and new people. My new employer is a Microsoft-exclusive shop, for almost every aspect of their software. If you've read this blog in any significant amount in the past, you'll know that I'm really not a Microsoft fan. In fact, I hate almost everything that's ever come out of Redmond, because for the most part it's deficient in how it's been engineered, and not as usable as other products out on the market (or even a lot of open source products). Therefore, the tone of this blog is probably going to change somewhat, and I'll be ranting and raving like a lunatic on things I'm learning about dealing with Microsoft products more often. It's going to be interesting.
Thursday, September 02, 2010
Finally ... MySQL workbench sucks less
MySQL workbench has been out for quite a while, under the guise of the people at MySQL. For the longest time, I stuck to using just the individual MySQL Query Browser and Administrator because they weren't too bad, and there really wasn't anything out there that I liked much better for query browsing alternatives. I tried out the old Workbench back when MySQL was standalone, but it really wasn't a very positive experience, so I just dropped it.
However, lately, something drove me to search for better alternatives to the MySQL query browser again, and I don't even know why. In my Google search, the MySQL Workbench came up, and I saw that it was a very recent version that was a good .2 versions up from the last one I had used, so I figured I'd give it a try. The difference was startling. Not only did they completely revamp the interface (at least for the Mac) but the workbench was just generally much more reliable and performant than the old query browser. If you get the chance, give it a shot. The new integrated interface is much more user friendly, and there's a bunch of new "Copy to clipboard" snippets that I personally find incredibly convenient and useful.
However, lately, something drove me to search for better alternatives to the MySQL query browser again, and I don't even know why. In my Google search, the MySQL Workbench came up, and I saw that it was a very recent version that was a good .2 versions up from the last one I had used, so I figured I'd give it a try. The difference was startling. Not only did they completely revamp the interface (at least for the Mac) but the workbench was just generally much more reliable and performant than the old query browser. If you get the chance, give it a shot. The new integrated interface is much more user friendly, and there's a bunch of new "Copy to clipboard" snippets that I personally find incredibly convenient and useful.
Monday, August 16, 2010
Running multiple Tomcat 6 instances in Ubuntu, the quick and dirty way
Here's a quick list for running multiple Tomcat 6 instances on Ubuntu 10.04 :
You should now have a running, fully functional instance of Tomcat on the server, using a different port.
- Copy the /etc/init.d/tomcat script with a new name in the same directory
- Update the NAME variable in the startup script with a name for the new instance that you want to run.
- Copy /usr/share/$(old)NAME to the (new) NAME you've just created, along with /var/lib/$(old)NAME and /etc/default/$(old)NAME
- Edit the server.xml file under /var/lib/$(new)NAME/conf/ and change all the ports (ie for shutdown, and all your Connectors) so that they don't conflict with the old instance
- Run /etc/init.d/$(new tomcat script name) start
You should now have a running, fully functional instance of Tomcat on the server, using a different port.
Wednesday, August 04, 2010
Quickly dropping all the tables in a MySQL database without dropping the database itself
I've recently come across a case where I need to drop all the tables in my database (ie effectively truncate the database) but MySQL has no built in command for doing so. This is where the magic of command lines becomes very useful. I found a great little trick here that will very quickly let you get rid of all that annoying data so you can load in new test data into your database :
If you've got GnuWin32 or another set of GNU programs installed on your Windows box, you can even do this in Windows without even changing the syntax !
mysqldump -u[USERNAME] -p[PASSWORD] --add-drop-table --no-data [DATABASE] | grep ^DROP | mysql -u[USERNAME] -p[PASSWORD] [DATABASE]
If you've got GnuWin32 or another set of GNU programs installed on your Windows box, you can even do this in Windows without even changing the syntax !
Tuesday, August 03, 2010
Quickly dumping a MySQL database out to a file
I've found that sometimes, I just need a quick and dirty copy of a database to test changes against, and it doesn't matter if the data is recent, or even consistent for that matter. That's where mysqldump comes in handy with the --single-transaction option. It can be used on a live database because it doesn't lock the tables and prevent your web application from continuing to insert, modify and delete new records. One example would be :
This can be made even quicker by combining this dumping into an SSH transfer to copy the output data to another machine.
mysqldump -u myusername -h myhost -p --single-transaction mydbname | gzip > mybackupfile.20100803.sql.gz &
This can be made even quicker by combining this dumping into an SSH transfer to copy the output data to another machine.
Piping a MySQL database from one server to another
I know that there's a lot of great, wonderful things that can be done on-the-fly through SSH. It's one of the greatest tools out there for moving data or communicating between two machines. So I thought "Why not try to move my database in the fastest way possible via SSH?", and here's the command I found :
This is of course a very basic, stripped down version of the command, which I haven't tested yet, but it's a good start to what seems to be a very common problem among developers.
mysqldump -ux -px database | ssh me@newhost "mysql -ux -px database"
This is of course a very basic, stripped down version of the command, which I haven't tested yet, but it's a good start to what seems to be a very common problem among developers.
Subscribe to:
Posts (Atom)