Category Archives: programming

Getting Installed Browsers and Version C#

I ran into a few posts that solved the problem of getting the installed browsers on a Windows machine and getting the version that were very helpful.

Getting Chrome and Firefox version locally, C#

Finding All Installed Browsers in Windows XP and Vista – beware 64bit!

These snippets were very helpful. So now I will hand it combined to you on a silver platter as a downloadable Console App.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using Microsoft.Win32;


namespace GetAllInstalledBrowsers
{
class Program
{
static void Main(string[] args)
{
foreach (Browser browser in GetBrowsers())
{
Console.WriteLine(string.Format("{0}: \n\tPath: {1} \n\tVersion: {2} \n\tIcon: {3}", browser.Name, browser.Path, browser.Version, browser.IconPath));
}
Console.ReadKey();
}


public static List<Browser> GetBrowsers()
{
RegistryKey browserKeys;
//on 64bit the browsers are in a different location
browserKeys = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\WOW6432Node\Clients\StartMenuInternet");
if (browserKeys == null)
browserKeys = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Clients\StartMenuInternet");
string[] browserNames = browserKeys.GetSubKeyNames();
var browsers = new List<Browser>();
for (int i = 0; i < browserNames.Length; i++)
{
Browser browser = new Browser();
RegistryKey browserKey = browserKeys.OpenSubKey(browserNames[i]);
browser.Name = (string)browserKey.GetValue(null);
RegistryKey browserKeyPath = browserKey.OpenSubKey(@"shell\open\command");
browser.Path = (string)browserKeyPath.GetValue(null).ToString().StripQuotes();
RegistryKey browserIconPath = browserKey.OpenSubKey(@"DefaultIcon");
browser.IconPath = (string)browserIconPath.GetValue(null).ToString().StripQuotes();
browsers.Add(browser);
if (browser.Path != null)
browser.Version = FileVersionInfo.GetVersionInfo(browser.Path).FileVersion;
else
browser.Version = "unknown";
}
return browsers;
}
}


internal static class Extensions
{
///
/// if string begins and ends with quotes, they are removed
///
internal static String StripQuotes(this String s)
{
if (s.EndsWith("\"") && s.StartsWith("\""))
{
return s.Substring(1, s.Length - 2);
}
else
{
return s;
}
}
}


class Browser
{
public string Name { get; set; }
public string Path { get; set; }
public string IconPath { get; set; }
public string Version { get; set; }
}
}

If you run this code you will get results that resemble this:

Mozilla Firefox:
Path: C:\Program Files (x86)\Mozilla Firefox\firefox.exe
Version: 31.0
Icon: C:\Program Files (x86)\Mozilla Firefox\firefox.exe,0
Google Chrome:
Path: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe
Version: 37.0.2062.124
Icon: C:\Program Files (x86)\Google\Chrome\Application\chrome.exe,0
Internet Explorer:
Path: C:\Program Files\Internet Explorer\iexplore.exe
Version: 10.00.9200.16521 (win8_gdr_soc_ie.130216-2100)
Icon: C:\Program Files\Internet Explorer\iexplore.exe,-9

Happy coding!

Advertisements

This article: HowToConfigureXDebug – NetBeans Wiki  is helpful, but you may need a bit of help to get over the top, so I have put a few hints in here in hopes to save others some hours I already spent.

I have now installed WAMP (Windows / Apache / MySql / PHP) and Netbeans several times dues to several laptop and hard drive failures, and kept getting stuck on this issue, forgetting the solution. The web pages I could find mostly show the correct information, however, some are old, and refer to old configurations, and none I found were completely correct.

I have found the fastest way to get up and running if you are going to program PHP under apache on Windows is to use the WAMP stack, which goes in smoothly.

Getting debug running is another story. Once you have installed WAMP, you need to do several things in order to get XDebug running. I am going to take you through the process (let me know if I have missed something – I am not an expert, just sharing scars so other can avoid!).

(This tutorial assumes that you have already downloaded WAMP from Bitnami’s site and run the install.)

1. Change the port to the one you wish to use. Quite often in a windows environment you will want to use a port other than 80 for PHP debugging (I am using localhost 80 for .Net and Visual Studio debugging). If you open the Apache configuration (which the Bitnami WAMP management program will open for you with a click):

Bitnami1

you will find the port in this configuration in two places – here:

ApacheConf1

and here:

ApacheConf2

2. You then need to edit the php.ini file (for me, located at C:\BitNami\wampstack-5.4.21-0\php) to include the xdebug dll – there are lots of places out there that tell you things like there being a php.ini in the bin folder (which there isn’t), and old versions of the editing that are required – these have been taken care of since then and changed.

One great thing about WAMP is that the correct xdebug file is already installed and ready to enable.

You will also find a great little tool out there that helps you determine if XDebug is properly installed. But you do not need it if you use Bitnami WAMP. Setting the config as follows below (you have to match your install – I used the default which I highly recommend). If you are using the version of WAMP I am using, you will find this code near the bottom of the file commented out (using semicolons) and need to uncomment it and correct the dll file reference. The dll should already be in there ready to go. The full path and forward slashes are required.

[XDebug]
;; Only Zend OR (!) XDebug
zend_extension="C:/BitNami/wampstack-5.4.21-0/php/ext/php_xdebug.dll"
xdebug.remote_enable=true
xdebug.remote_host=127.0.0.1
xdebug.remote_port=9000
xdebug.remote_handler=dbgp

This will then activate XDebug. There are other helpful settings in this file for development purposes (like logging and caching), which are outside of the scope of this post, but are easily Googled.

3. Restart the Apache server:

Bitnami3

4. Verify that your website works by navigating to:

http://localhost:8888

You should get the default index.html file’s output saying

It Works!

in large type. This means Apache is serving up an html file from the htdocs directory (C:\BitNami\wampstack-5.4.21-0\apache2\htdocs by default).

5. Now create and edit an index.php file in the same apache htdocs directory and type

phpinfo();

and then save it in that same directory.

4. When you now navigate to:

http://localhost:8888/index.php

The php engine will echo out it configuration info. XDebug should show up in the output in two places.

here (near the top):

phpinfo1

and here (near the bottom):

phpinfo2

I decided to post after the fourth time of getting stuck on this because the information is not all in one place and the most complete info is not current.

Happy PHPing!

 

Master Page DataBind() will clear data on your page – remember!

I was working on a problem with a drop down list getting un-initialized and had run across this page:

c# – .Net Webform losing data – Stack Overflow.

This simple post is about a coder who was getting their ddl control reset every time a postback occurred. They had not yet learned about putting the initialization inside an if statement that only runs when the page is first loaded.

I had done this, and had not changed the code on this page for days and yet it stopped working.

Then I realized — I had been fighting with the links on the site.master.cs page that were causing the link to come up blank. I learned that when you have a reference in your head element on the master page like so:

<script src='<%# Helper.ResolveMyUrl(“/Scripts/libs/jquery-1.7.1.min.js”) %>’ type=”text/javascript”></script>

You need this:

Page.DataBind(); // (yes, but not quite…)

in your Page_Load so that the function call will be resolved. I added that line and my links all started working — and my drop down list started clearing on a postback. But there were enough hours between these discoveries, that I hadn’t made the connection.

What I really needed was:

if (! Page.IsPostBack)  // (better, but not yet done…)
Page.DataBind();

since the DataBind affects all of the data bound controls on all of the pages that use it as a master page.

But wait, there’s more!

I thought this had cleared up my issue, but then I found that another control that I initialized lost its value. It turns out that this DataBind on the entire page is not a good idea. Instead you need to be specific about the stuff on the master page. So I did this:

if (! Page.IsPostBack)
{
  Page.Header.DataBind(); // initializes the script references
  LoginView1.DataBind(); // initializes a link inside LoginView1
}

Ok, I think that does it. I feel better about a more qualified / constrained approach too.

With this qualification, I got the initialization on the links I needed, and didn’t interfere with the drop down lists that were initialized once and then needed to remain populated. I didn’t find this anywhere, and so I am hoping that it will save someone the couple hours I spent.

Happy coding!

Sql Server remote connection troubleshooting

Resolving could not open a connection to SQL Server errors.

Really helpful link for troubleshooting through the issues for why you may not be able to connect to a Sql Server remotely. It steps through several possible issues. I had to google how to fix them, once I identified them, but this was a great help in discovering some of the issues.

For me, in short it was the following:

1. Make sure you have only one firewall running (I had Norton and Windows firewalls running).

Go to Windows Firewall settings and select “Advanced settings”

WindowsFirewall

Then ensure that all of the firewalls are set to off (WARNING: don’t turn off Windows firewalls unless you have another firewall running, and don’t configure firewalls unless you know what you are doing or you could lose data, your identity information, etc. If you have any doubts, get someone to help you!)

WindowsFirewallAdvancedSettings

This is how it will look after those second, redundant firewalls have been turned off.

2. Make sure the SQL Server services are enabled (SQL Server, SQL Server Browser minimally in order to see the Server on another box).

3. Enable the communication protocol that you are using (typically TCP or Named Pipes)

4. Allow port 1433 and possibly port 1434 through the firewall and limit the connection to your local subnet, or the IPs that will be connecting to the server.

5. This was the kicker for me – go into the configuration for the TCP and enable the ip addresses that you need. For me, since this server is behind a firewall, I allowed all connections.

Hope this saves someone the extra hours I spent finding out the final steps.

This was a weird issue that a coworker had that I thought I would re-post so others (and I) could find it easily when it comes up again. We were adding a report via the report wizard. Visual Studio (apparently) attempts to load the data sources you may have sitting in your Bin folder. If it cannot load one of those (for some reason), it will fail to bring up the report wizard (where you may be creating a new data source anyway).

ReportWizardError

The solution feels a lot like a hack (but this is Microsoft, right – comes with the territory).

Rename your Bin folder, then run your wizard, then rename it back.

Just wow.

I got this solution from here.

LinqPad – Get Pdf from binary column

A friend asked me to share this technique (which rocks!) for a simple way to pull a pdf from a table without writing an application to do it. It has saved me a lot of time when I need to get to a stored pdf quickly.

LinqPad (which if you do any Linq, and in this case even if you just need to get to a binary object) is a must-have program that allows you to do this.

Here is the simple code snippet that pulls the pdf, saves it to a file, and opens it. You have to connect your database on the top right, and select “C# Statements” in the middle drop down list:

string id = "60821 003";
string dir = "C:\\TempDocs";

// create output directory
Directory.CreateDirectory(dir);

// create output filename
string outputPDFFile = Path.Combine(dir, id + ".pdf");

// find the record we want (you have to be connected 
// to the database you want to search, and
// PDFDocuments below must match the table you are pulling data from
var mypdf = (from q2 in PDFDocuments where q2.PrintBatchId == id select q2);

// above returns only one record, so below I use SingleOrDefault to get that record.
// otherwise here you could iterate through the records...
// the ".Pdf portion pf this is the column name of the pdf binary data in the table
File.WriteAllBytes(outputPDFFile, mypdf.SingleOrDefault().Pdf.ToArray());

// this part opens up the pdf for viewing / verifying I have the right one
System.Diagnostics.Process proc = new System.Diagnostics.Process();
proc.EnableRaisingEvents = false;
proc.StartInfo.FileName = outputPDFFile;
proc.Start();

Have fun!

LINQ to SQL and missing Many to Many EntityRefs – Rick Strahl’s Web Log

Just a quick note: If you are attempting to create a relationship between two tables using a foreign key and use it in Linq to SQL, it is not enough that there is a non-primary key defined in that table. The relationship will show up on the designer but not in the actual code. Linq to SQL requires that there be a primary key defined, even if it is not used in the relationship.

More info at link below:

LINQ to SQL and missing Many to Many EntityRefs – Rick Strahl’s Web Log.

WebMatrix Deployment

I have been noodling with MVC3 / cshtml / Razor, and I put together a web site and tried to deploy it. I was using the WebSecurity that was nicely integrated into the default web site that I started with, and was delighted about how easy it was to implement. With a few hours of work, I had a site that was performing registration, adding users to my database, emailing for confirmation and I didn’t write any of that code! Sweet. Let’s deploy. Then, ugh, an error.

Server Error in ‘/’ Application.


Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: The connection name ‘LocalSqlServer’ was not found in the applications configuration or the connection string is empty.

Source Error:

Line 238: <membership> Line 239: <providers> Line 240: <add name=”AspNetSqlMembershipProvider” type=”System.Web.Security.SqlMembershipProvider, System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” connectionStringName=”LocalSqlServer” enablePasswordRetrieval=”false” enablePasswordReset=”true” requiresQuestionAndAnswer=”true” applicationName=”/” requiresUniqueEmail=”false” passwordFormat=”Hashed” maxInvalidPasswordAttempts=”5″ minRequiredPasswordLength=”7″ minRequiredNonalphanumericCharacters=”1″ passwordAttemptWindow=”10″ passwordStrengthRegularExpression=”” />  Line 241: <add name=”MySQLMembershipProvider” type=”MySql.Web.Security.MySQLMembershipProvider, MySql.Web, Version=6.3.6.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d” connectionStringName=”LocalMySqlServer” enablePasswordRetrieval=”false” enablePasswordReset=”true” requiresQuestionAndAnswer=”true” applicationName=”/” requiresUniqueEmail=”false” passwordFormat=”Clear” maxInvalidPasswordAttempts=”5″ minRequiredPasswordLength=”7″ minRequiredNonalphanumericCharacters=”1″ passwordAttemptWindow=”10″ passwordStrengthRegularExpression=”” /> Line 242: </providers>


Source File: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\machine.config    Line: 240


Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.272

I started immediately looking for an entry possibly added by WebMatrix. But there was none referencing AspNetSqlMembershipProvider, or LocalSqlServer. Then I noticed that this reference was in the machine.config of the server. Well, this is not my server, so I contacted support to ask them about it. They promptly and courteously told me that they did not solve programming questions. OK, on my own – no big surprise there. But I thought it might be a normal “gotcha” that lots of people run into. Well, it is… Here is what needs to happen:

First the reference is partially right. You DO need to have this reference in place, however the machine config does not know where your site has put the Membership info. So you have to replace it. Use this:

<connectionStrings>
<clear />
<add name=”myDB” providerName=”System.Data.SqlClient”
connectionString=”Data Source=someserver.com;Initial Catalog=myDB;User ID=myDB_user;Password=’xxxxx’;Integrated Security=False;” />
<remove name=”LocalSqlServer” />
<add name=”LocalSqlServer” providerName=”System.Data.SqlClient”
connectionString=”Data Source=someserver.com;Initial Catalog=myDB;User ID=myDB_user;Password=’xxxxx’;Integrated Security=False;” />
</connectionStrings>

Of course replace the database details with your own.

Once this was in place, I ran it again and got the following error:

Server Error in ‘/’ Application.


The Role Manager feature has not been enabled.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Configuration.Provider.ProviderException: The Role Manager feature has not been enabled.

Source Error:

Line 3: var providerName = “System.Data.SqlClient”; Line 4: //var db = Database.OpenConnectionString(connectionString, providerName); Line 5: WebMatrix.WebData.WebSecurity.InitializeDatabaseConnection (connectionString, providerName, Line 6: “UserProfile”, “UserId”, “Email”, true); Line 7:


Source File: e:\web\myWeb\_AppStart.cshtml    Line: 

It is now looking at my (mind you WORKING LOCALLY 🙂 ) init and saying it is failing. To be honest, since this is new tech for me, I wasn’t sure if I should be enabling the role manager, or if I had enabled something that was adding a new / different security setting that would cause some conflict. With a bit more research (Googling WebSecurity and Role Manager), I saw that the WebSecurity uses the Role Manager in “SimpleMembership” mode. OK, so this is needed and probably ok.

But I don’t need the AspNetSqlMembershipProvider… So I removed it (with the <clear/> below):

Inside the System.Web section of my web.config:

<membership defaultProvider=”SimpleMembershipProvider”>
<providers >
<clear/>
<add name=”SimpleMembershipProvider” type=”WebMatrix.WebData.SimpleMembershipProvider,WebMatrix.WebData”/>
</providers>
</membership>

Then I got the error:

Server Error in ‘/’ Application.


Default Membership Provider must be specified.

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.Configuration.Provider.ProviderException: Default Membership Provider must be specified.

With a little more digging, I found that this entry in the appSettings section will take care of that issue.

<add key=”enableSimpleMembership” value=”true” />

I hope this helps someone make a few less round trips searching!

Peace…

Helpful Links for this issue:

http://stackoverflow.com/questions/3874279/the-role-manager-feature-has-not-been-enabled

http://forums.asp.net/t/1695156.aspx/1?WebSecurity+in+MVC

https://forums.iis.net/p/1188577/2018786.aspx

Windows Service testing

This is a handy way to test your windows service; something I have been doing for awhile. I was looking at it recently, and thought it might be handy for someone else:

public static class Program
{
///
/// The main entry point for the application. /// 

public static void Main()
{
#if (!DEBUG)
  ServiceBase[] ServicesToRun;
  ServicesToRun = new ServiceBase[] { new MyWinService() };
  ServiceBase.Run(ServicesToRun);
#else
  //Debug code: this allows the process to run 
  // as a non-service. It will kick off the
  // service start point, and then run the 
  // sleep loop below.
  MyWinService service = new MyWinService();
  service.Start();
  // Break execution and set done to true to run Stop()
  bool done = false;
  while (!done)
   Thread.Sleep(10000);
  service.Stop();
#endif
}

By using this approach, you can compile a release version of the service that runs like a service, and while debugging, you can run the loop in the debug section that allows you to break and set done and fully test your startup and shutdown code.

HTH,

Robb

Migrating to TFS 2010 from TFS 2008

This is a quick summary of our experiences moving from TFS 2008 to TFS 2010.

If you are like us (and many others) out there, you are building an msi to deploy your projects and you are using TFS to do it. We had to run DevEnv in our build script to accomplish this because MSBuild does not support the web deployment project and will give you a warning that it is skipped if you have it included in a solution that is sent to build.

In VS 2008, you can accomplish this in your build script, and it is a bit messy, but works (it also builds the entire solution twice, ugh!). I am not going to go into those details, but you can find more here and here.

So we created a new branch in TFS 2010 and brought over the code we are migrating and first I ran the build using the same TFS 2005 script that we have been using (in 2005 and 2008). This was a tfsbuild.proj file. To do this I used the 2010 build xaml file that reads in this tfsbuild.proj script called upgradetemplate.xaml.

This worked after a few config changes (we had shortened the names of some of the default configuration values in the build config because of the visual studio – MSBuild directory structure limit workarounds.

The build worked and then we migrated the solution to VS 2010.

This worked with only a few quirks where VS 2010 forced some projects to be upgraded and would not load them otherwise because of version mismatches. We also found out Test Projects in Visual Studio 2010 Must Target .NET Framework 4.

So I got the .Net framework versions all happy with one another and then the project built locally on my dev box.

We started out assuming that we could not use Web Deployment projects in VS 2010, and started looking at alternatives. There are mixed messages out there. But a coworker found this:

Download details: Visual Studio® 2010 Web Deployment Projects – RTW

This is a fix that adds the Web Deployment Project back into VS 2010 allowing us to still build our msi file from DevEnv. This allowed us to use the script that calls DevEnv pointing to the VS 2010 installation on the build server.

So I sent it off to the build server. Success! That wasn’t so bad… Now for conversion to the defaultTemplate.xaml that would allow us to use the nifty build workflow UI.

I followed the instructions for Building Visual Studio Setup Projects with TFS 2010 Team Build. This was very helpful in putting this together initially and I had a hard time finding it, so here is one more reference for you all.

When I started the build, it came back almost immediately with: The path … is already mapped in workspace VMLSBUILD_6_1.

This was an interesting one. It turns out that there are caches of the workspaces and while TFSBuild 2008 didn’t seem to mind, TFS2010 did. When I ran Team Foundation Sidekicks to see what the issue was, I found a lot of residual workspaces – some years old – that were just hanging out there. For some it is not as simple as my fix, but all I had to do was delete the workspaces and I was back in business.

You can also view your workspaces by running this from the Visual Studio Command Line on the box that contains the build workspaces:

tf workspaces /owner:* /computer:”BUILDCOMPUTERNAME” /s:”http://yourTFSServerURL&#8221;

OK, kicked the build off again…

Then I ran into the error: “Package ‘Microsoft.VisualStudio.TestTools.TestCaseManagement.QualityToolsPackage, Microsoft.VisualStudio.QualityTools.TestCaseManagement, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a’ failed to load.” This is a pain, but the workaround is not so bad:

Package Microsoft.VisualStudio.QualityTools.TestCaseManagement failed to load in Team Build 2010. | // TODO: name this blog

Thanks to Scott for that – it was a simple solution once you saw it, but I hadn’t thought of it.

One more time to the build, and we were successful.

Edit / Note: The above fix does not guarantee that this issue doesn’t come up, but instead is a symptom of other build issues in DevEnv.com. If this error is encountered, as the blog states, you have to dig  into the log  and see what the true issue is. I  have not found a good way to reflect the true error out to the build, but at least you have a way to get to it.

Hopefully this helps out someone who is doing the same as we are. Peace…

A few more links:

TFPT Error: Unable to determine the workspace – Ozzie Rules Blogging – Site Home – MSDN Blogs

Workspaces Command