tag:blogger.com,1999:blog-44985446023735440562024-02-20T23:33:31.487-08:00Software Product Development & SEOThoughts and jottings on the whole process of developing and selling software products with an emphasis on selling online via a website.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.comBlogger68125tag:blogger.com,1999:blog-4498544602373544056.post-62345559192731889002012-07-09T04:05:00.001-07:002012-07-09T04:05:47.744-07:00Opening a SQL Server 2012 database in Visual Studio 2010After installing SQL Server Express 2012 and using the SQL Server Management Studio to create a database, I found that I couldn't integrate SQL Express 2012 into the Visual Studio Server Explorer in a way that VS listed all my 2012 databases. VS would show databases from an earlier 2008 SQL Server I had installed on my PC but not the 2012 version.<br />
<br />
The only way I could show the DB was to add a connection to a database file. To do this I had to:-<br />
<br />
1. Right-click the <b>Data Connections</b> node in Server Explorer and choose <b>Add Connection...</b><br />
<br />
2. Make sure the Data Source field was set to SQL Server Client as shown in this pic.:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizsnJsNZB8sNJHjHjen_XJ7LUCLG0Is79Ccvl7LUN9j-QpGf8vCI2wXfI5fwzMeCCeiOYjZClZIgDHh319v4LGdkCmi_ZT4Vu6k3A4UTARnax3FKgJYdCayatIwcgmu4X9p3tgpxV3-8jc/s1600/sql-server-add-database-file.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAw2Ch2Vh5o8rvelKRgveHqyufMHJkeEQk92zbOYFpjLx537_rZzwyLTX5-ZM-AL5ACfE1sJb-TZTBPnUHy_GH1pzjPvwnduZS-qb__TGbM7Lpgv3oYo0R9Z7WYOkxbQP9KMqP2qbjZKh6/s1600/sql-server-add-database-file.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAw2Ch2Vh5o8rvelKRgveHqyufMHJkeEQk92zbOYFpjLx537_rZzwyLTX5-ZM-AL5ACfE1sJb-TZTBPnUHy_GH1pzjPvwnduZS-qb__TGbM7Lpgv3oYo0R9Z7WYOkxbQP9KMqP2qbjZKh6/s1600/sql-server-add-database-file.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizsnJsNZB8sNJHjHjen_XJ7LUCLG0Is79Ccvl7LUN9j-QpGf8vCI2wXfI5fwzMeCCeiOYjZClZIgDHh319v4LGdkCmi_ZT4Vu6k3A4UTARnax3FKgJYdCayatIwcgmu4X9p3tgpxV3-8jc/s1600/sql-server-add-database-file.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><br /></a></div>
<br />
3. Then in Server name field type in the name of the new SQL Server Express 2012 instance. In the pic. above, the name of my server is SLIQSQL but for a default installation of SQL Server Express, the server name is likely to be SQLEXPRESS (I just chose a different name during the installation process).<br />
<br />
4. Then press the <b>Test Connection</b> button. If all is well you should get a Connection Succeeded message.<br />
<br />
5. Finally, choose the database you want to add in the <b>Select or enter a database name</b> field and press OK to close the dialog.<br />
<br />
The chosen database should now show in the Server Explorer.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-31127724211924241532012-07-09T02:08:00.003-07:002012-07-09T02:08:34.804-07:00Where does SQL Server 2012 store database files by default?If you're playing around with SQL Server 2012 and you've created a couple of databases, e.g. in SQL Server Management Studio, you may not actually know where the databases are stored as during the whole database creation process you don't get asked to specify a file path.<br />
<br />
To find out where your database files are stored do the following:-<br />
<br />
1. Open SQL Server Management Studio<br />
2. Right click the server name in the Object Explorer pane on the left and choose Properties.<br />
3. In the Properties dialog, choose Database Settings in the Select a Page pane on the left.<br />
<br />
The database file locations are then shown on the right.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvdLkwlr2MxnffGd2Grbc-43pEQzM2i-Y13LQ-a8KIenhowPGAzutHTbQfbofaFNJV0I5kvLQ2UmgHTNV24CcugnWsYUaBlrBAJOYOOlQLRpTMb9JiGwKgp_Y8bTinOLY_z6ClZM_ct8r0/s1600/sql-server-properties.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgvdLkwlr2MxnffGd2Grbc-43pEQzM2i-Y13LQ-a8KIenhowPGAzutHTbQfbofaFNJV0I5kvLQ2UmgHTNV24CcugnWsYUaBlrBAJOYOOlQLRpTMb9JiGwKgp_Y8bTinOLY_z6ClZM_ct8r0/s1600/sql-server-properties.jpg" /></a></div>
<br />Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-77800107150840549022012-06-30T09:23:00.005-07:002012-06-30T09:24:15.092-07:00VistaDB vs SQL Server Express for Multi-User appsFor the past 4 years I've been using VistaDB (version 3 or 4) in a number of development projects. For a SQL relational database with minimum dependencies, i.e. all it requires is the .Net framework, VistaDB is hard to beat and makes deployment as an embedded database real easy, adding little more than 1MB to an installer. Overall, as an embedded database in single user applications, I haven't found anything to compete with it.<br />
<br />
VistaDB however does have a few drawbacks that make it unsuitable for larger, multi-user applications which means I'm now looking at using SQL Server Express in some new applications. VistaDB will still be a part of some of my future apps but not part of apps where I want to offer true multi-user capability.<br />
<br />
In my experience, the key drawbacks of VistaDB for multi-user apps are:-<br />
<br />
1. The lack of a client/ server model. Instead, each VistaDB client directly access the database file and Windows itself manages file locks and such. The result is that when 2 or more users try to access a database file simultaneously access times go through the roof and the app crawls along.<br />
<br />
2. VistaDB's lack of paging support, e.g. something like MySQL's LIMIT, OFFSET commands, means that it is hard to avoid reading whole SQL tables of data from the DB to present in lists. Reading large amounts of data from a shared file can compound the Windows shared file performance drop from point 1. <br />
<br />
3. In a multi-user app with concurrent access, SQL transactions are essential to ensure consistent updates across tables. Unfortunately, VistaDB transactions are extremely slow causing application performance to drop.<br />
<br />
The points above aren't complaints about VistaDB - multi-user apps aren't what VistaDB is intended for. My only disappointment with VistaDB is that it's so good, I just wish there was a simple, easily deployable, client/ server version. <br />
<br />
As I gain more experience with SQL Server Express, I'll try and list more pros and cons. One good tool I've found so far for use with SQL Server is <a href="http://opendbiff.codeplex.com/" target="_blank">OpenDBDiff</a>. This is a free, open-source tool for comparing schemas of two different SQL Server databases and generating SQL scripts to make the schemas match. I can see this tool being essential to ease field upgrades of SQL Server DBs. With VistaDB today, I generate schema update code by hand, so it's a nice, early bonus to find an automatic way of doing this for SQL Server.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-88102545340106630992012-06-23T10:30:00.002-07:002012-06-23T10:30:54.241-07:00Article Marketing SoftwareArticle submission is still an efficient way to help boost the performance of a site in SERPs and is a good way of publicising information such as a new service or product you are offering. There are a number of good article submitters on the market including Article Marketing Robot and Article Demon. However, a new article submitter has recently been released - SliQ Article Submitter - by the developers of SliQ Submitter Plus.<br />
<br />
SliQ Article Submitter lets you submit as many articles as you like to as many directories as you can find. Although the package comes with a small list of article directories you can easily add your own. The software supports Wordpress, Article Dashboard, MS and Setup amongst other scripts.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj87HkfFMk1pauSbxoZAyqHlSob5EY55GmdOC6zJXnNzUBVsEPImThtxYuaFxCIEtSt4D6aVNmmAhC_M4hMfRU007BWmfekUn8bp81Qini0mrDv4SuJ0OAsT5efzfOqiS-slS3UjFrJxb_x/s1600/article-submitter.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj87HkfFMk1pauSbxoZAyqHlSob5EY55GmdOC6zJXnNzUBVsEPImThtxYuaFxCIEtSt4D6aVNmmAhC_M4hMfRU007BWmfekUn8bp81Qini0mrDv4SuJ0OAsT5efzfOqiS-slS3UjFrJxb_x/s1600/article-submitter.jpg" /></a></div>
<div align="left" class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
</div>
The new article marketing software follows a similar design to the familiar Microsft Office packages and with a clean, fresh layout the interface is designed to make article submission achievable even for those people who've never performed article marketing before. Even though the package is suitable for newcomers to SEO, the package still includes all the features a professional SEO will need including automatic account creation, automatic email verification and a live link checker allowing the user to build up a list or report of live articles. For the regular subumitter of articles there is also an in-built scheduler that lets the user queue up registration/ account creation, email confirmation, submission and even live link gathering tasks to be performed on a user-defined timescale or schedule. <br />
<br />
To find out more about SliQ Article Submitter, check out the <a href="http://www.sliqsubmitter.com/article-directory-submitter.php" target="_blank">article submitter</a> info at <a href="http://www.sliqsubmitter.com/">http://www.sliqsubmitter.com</a>.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-47056904461427803332009-11-11T04:58:00.000-08:002009-11-11T10:21:16.725-08:00Beyond Compare - File Comparison Tool<div>Sometimes it's the simplest activities that take the most time. If you're in the game of software development making changes in multiple versions of source files is a frequent and not very interesting activity. You'll often be working on your next major version then need to make a new minor version release either due to a problem in the current release or a need to support some new feature (like an unexpected tax rate change).<br /><br />I'm showing my age here but in the past I've always used Windiff (in my Visual C++ 6 days). Windiff used to let me find out what the differences were between files. I could then merge file contents using a text editor. This process works but it was sometimes difficult to get files to match exactly as there were often extra spaces of line breaks.<br /><br />Windiff disappeared from Visual Studio 2005 so more recently I've even restored to the old DOS FC command. I did have a quick play with Visual SourceSafe but the solution wasn't really flexible enough - often I want to compare and merge files without locking something down in a configuration management system.<br /><br />However, I recently came across a package called Beyond Compare from Scooter Software. This package is absolutely fantastic and is now my second favourite software tool (after Visual Studio).<br /><br /><img style="TEXT-ALIGN: center; MARGIN: 0px auto 10px; WIDTH: 202px; DISPLAY: block; HEIGHT: 144px; CURSOR: hand" id="BLOGGER_PHOTO_ID_5402912574254750978" border="0" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1oxwJ19J0kY4F9mxfXcgmq71JyNXQRDdk5HghhFCfnOEgDsNJJI7EJBuk5aWyLE0_w6P13cJsGqIJBPVMEdPWTx0GHHmgjZJa-EisCQ97ZPjOvDbvp2YVGPHnw-xlKhKUaT_vWyimEB8i/s400/Beyond+Compare+-+File+Comparison.jpg" /></div><br /><div>There are a number of good things about Beyond Compare.<br /><br />Firstly it remembers folders you've compared in the past. This means you can do a new comparison and merge more easily the second time.<br /><br />Secondly it lets you move updates from one file to another with a single mouse-click and shows you the results. Any extra/ missing whitespace differences are easily ignored. This makes merging versions take minutes rather than hours.<br /><br />Thirdly, the software tool itself presents a trustworthy user interface. As you're doing a compare and merge with Beyond Compare, you can refresh the file comparison on the fly and check that things are absolutely identical. Knowing things are the same - bar the differences you want to keep - is vital to ongoing software development.<br /><br />If merging files and versions of software is something you do regularly I'd recommend going to the <a href="http://www.scootersoftware.com/">Scooter Software</a> site and taking a look at Beyond Compare.</div>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-56934360912259508342009-07-11T06:26:00.000-07:002009-07-11T07:08:57.042-07:00PHP, MySQL date and time formatsPHP and MySQL have different formats for storing dates and times. This can cause confusion when trying to compare a date in PHP and a date stored in a MySQL database.<br /><br />PHP stores dates and times in Unix or UTC format. This format encodes a time as an integer count of the number of seconds since New Years Day began in 1970 (1st Jan 1970). MySQL on the other hand stores dates and times in string format. All three MySQL date/ time types DATETIME, DATE and TIMESTAMP store data in string format.<br /><br />MySQL DATETIME and TIMESTAMP columns store in the format:<br /><br /><br /><div align="center">YYYY-MM-DD HH:MM:SS</div><br />MySQL DATE columns store in the format:<br /><br /><br /><div align="center">YYYY-MM-DD</div><br /><strong>PHP and MySQL date/ time comparisons</strong><br /><br />Obviously, this difference in format causes problems when inserting dates and times into MySQL databases and especially when comparing MySQL and PHP dates for example trying to select entries from a table where a date value in the table is older than a PHP date. The easiest way to do this is to use the UNIX_TIMESTAMP MySQL function. For example:<br /><br /><span style="font-family:courier new;font-size:85%;">// You could get the date as three integer values from a querystring on the PHP page:</span><br /><span style="font-family:courier new;font-size:85%;">$day = $_GET['day'];</span><br /><span style="font-family:courier new;font-size:85%;">$month = $_GET['month'];</span><br /><span style="font-family:courier new;font-size:85%;">$year = $_GET['year'];</span><br /><span style="font-family:courier new;font-size:85%;"></span><br /><span style="font-family:courier new;font-size:85%;">// Then use the day, month and year to construct a PHP time (in seconds since</span><br /><span style="font-family:courier new;font-size:85%;">// 1st Jan 1970 format).<br />$datetime = strtotime($year.'-'.$month.'-'.$day.' 00:00:00');</span><br /><span style="font-family:courier new;font-size:85%;"></span><br /><span style="font-family:courier new;font-size:85%;">// Then find all entries newer than the date given by the querystring arguments.<br />$sql = "SELECT * FROM MyTable WHERE UNIX_TIMESTAMP(UpdateDate) >= '" . $datetime . "'";</span><br /><span style="font-family:courier new;font-size:85%;"></span><br /><span style="font-family:courier new;font-size:85%;">$result=mysql_query($sql);</span><br /><br />The above SQL query causes MySQL to convert the value of the DATETIME (or DATE or TIMESTAMP) value in the UpdateDate column in the hypothetical table into a PHP format date before doing the compare.<br /><br /><strong>Storing a PHP date/ time value in MySQL</strong><br /><br />To convert a PHP format date/ time into MySQL's format, the MySQL FROM_UNIXTIME function can be used. For example:<br /><br /><span style="font-family:courier new;font-size:85%;">$currenttime = strtotime("now");</span><br /><span style="font-family:courier new;font-size:85%;"></span><br /><span style="font-family:courier new;font-size:85%;">$sql = "UPDATE MyTable SET UpdateDate = FROM_UNIXTIME(" . $currenttime . ") WHERE ... ";</span><br /><span style="font-family:courier new;font-size:85%;"></span><br /><span style="font-family:courier new;font-size:85%;">$result=mysql_query($sql); </span><br /><span style="font-family:Courier New;font-size:85%;"></span><br /><strong>Don't use strings for PHP/ MySQL date > or <><br /><br /></strong>You might find some PHP code examples, trying to use the PHP date() function to format PP dates and times as strings in the correct format to match MySQL values. If you can remember the correct format strings for the conversions this will work as long as you are setting values in rows. For comparisons however, strings aren't any good as the comparison will be an alphabetic/ string comparion and not the required date comparison.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-83295882399215322152009-05-07T04:40:00.000-07:002009-05-07T04:52:27.851-07:00VistaDB, SQLite and Microsoft AccessRecently I've been carrying on my investigations into databases. SQLite originally looked promising as an alternative to Microsoft Access - read my <a href="http://software-product-development.blogspot.com/2009/04/sqlite-and-adonet-acting-as-access.html">SQLite investigation</a> post for more info. SQLite looked small, fast, robust and very easy to install. However, I eventually decided it wasn't going to work as an Access replacement for me.<br /><br />The main reason I decided not to replace Microsoft Access with SQLite was that I'd got too used to ease with which I could get when using the .Net datatypes seamlessly with Microsoft Access, e.g. I could read and write the .Net Decimal type straight to Access. With SQLite it seemed that I might have to convert to and from strings to preserve accuracy. This wasn't a big showstopper but I'm afraid I like my programming to be as easy as possible.<br /><br />I'd pretty much resigned myself to using Microsoft Access but then I came across a really neat database system called <a href="http://www.vistadb.net/">VistaDB</a>. VistaDB looks (I suspect) like it may have been originally based on SQLite but the great thing about it is that it has the rich data type support you get with Microsoft Access - plus extras like stored procedures - without losing the no hassle deployment of SQLite. I've spent a few hours evaluating VistaDB and so far it looks ace. For my particular application it solves all the downsides of both SQLite and Microsoft Access.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-37036604869956681862009-04-06T07:02:00.000-07:002009-07-11T06:26:07.658-07:00SQLite and ADO.Net: Acting as an Access replacement<p>I've had a bit of a play recently with <a href="http://sqlite.phxsoftware.com/">SQLite and ADO.Net</a> to see if I could slot in SQLite instead of MS Access in my desktop application. As yet I haven't made my mind up, but it's been a very interesting exercise. Here's a quick summary of my findings so far.</p><p><strong>DataType Support</strong></p><p>With my limited experience, SQLite seems to support fewer data types than MS Access. On the whole this isn't a problem apart from two areas - the .Net Decimal type and the .Net DateTime type. In both these cases I think you end up having to encode the data as strings and take care of any localisation issues yourself, e.g. making sure dates stored in France can be read in the UK and vice-versa. I haven't delved into Decimal storage too much but I think strings will need to be used instead of squeezing data into the Double data type and experiencing potential rounding errors.</p><p><strong>Complete ADO.Net Support</strong></p><p>The SQLite support is pretty comprehensive but misses out in one or two areas like the RowStatusUpdated event handling.</p><p><strong>Error Handling</strong></p><p>If you open a connection to a non-existent DB, SQLite seems to create an empty database at the specified path. This isn't a big issue but it means that the "DB doesn't exist" error turns into a "Table doesn't exist" error when you try to access a table in the DB. </p><p>Note: Since I wrote this post, I've found out that you can use connection strings to alter the default behaviour of creating an empty DB when the target DB can't be found. Read <a href="http://www.connectionstrings.com/sqlite">SQLite Connection Strings</a> for more info.</p><p><strong>Performance</strong></p><p>On first impressions, data access with SQLite is very quick and certainly quicker than MS Access. However, if you have to start encoding and decoding data into strings (DateTime for example), I'm not sure that the performance wouldn't start to degrade.</p><p><strong>Installation</strong></p><p>With SQLite there is essentially nothing to install. All you need to do is copy the assembly into your application folder and you are up and running. SQLite wins hands down here.</p><p><strong>Conclusions</strong></p><p>None for now, except to say that SQLite looks very tempting as an Access replacement especially as it's so easy to deploy. I'll post more info as I gain more experience.</p>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-91975007884980724202009-03-01T08:55:00.000-08:002009-03-01T09:05:54.055-08:00SliQ Invoicing 1.6 ReleasedSliQ Invoicing 1.6 has now been released. Although it's only 6 weeks since version 1.5.1 of SliQTools <a href="http://www.sliqtools.co.uk/">invoicing software</a> was released, 1.6 is quite a significant update. In 1.6, a number of options have been added to allow customers to modify the provided <a href="http://www.sliqtools.co.uk/invoice-templates.aspx">templates for invoices</a>, quotes and credit notes.<br /><div></div><br /><div>As of 1.6, templates can now optionally include a tax rate column. If desired, the tax value column can now be ommitted and users who are VAT/ tax registered can now choose whether the total column is the gross or net amount. One of the biggest additions to version 1.6 however is a label editor.</div><br /><div></div><img id="BLOGGER_PHOTO_ID_5308265459761279506" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 274px; CURSOR: hand; HEIGHT: 234px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSa4fGREWPmBVHvxMzVnc5NsBJcM2et7YgNSyp0Dt3Z5RgS6r0tY-wIMso3C9JOY4IOCLT-ZvWl3haoPhY-S7dCqwlSRWvVV-XwMhw6W0VoJrAIOKw1LNoA5d-OQqhagzzSTOr10Da_e-f/s400/sliq-label-editor.jpg" border="0" /><br /><div>The label editor is provided on the Template Setup tab. The editor lists all the fixed text labels on the selected template preview and lets the user enter their own value. For example, US customers might like to change the <strong>Delivery Address</strong> label to <strong>Shipping Address</strong>. Using the new label editor it is even possible to fully translate the standard templates into Spanish, French or German for example.</div><div> </div><div>For futher details of the modifications and additions in SliQ 1.6 and to download the latest copy, visit the <a href="http://www.sliqtools.co.uk/releasehistory.aspx">SliQ Release History</a> page.</div>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-1621225220367498302009-01-13T05:53:00.001-08:002009-01-13T06:07:05.637-08:00Free Software DownloadsIn the past couple of weeks, SofwareLode, a <a href="http://www.softwarelode.com/">shareware downloads</a> site has been growing in popularity. More and more pages are being pulled out of the supplemental index and the number of page views per day is now into the thousands.<br /><br />There are a number of reasons for the increase in traffic.<br /><br /><ul><li>Being a shareware directory, SoftwareLode naturally builds links over time as authors link either to the homepage or to the details page for their software packages. </li><li>As well as an increasing number of links, better internal linking has also helped. Each software details page now links to up to 10 related programs, i.e. programs with the same keywords. Getting more, relevant links to the program details pages helps pull pages out of the supplemental index.</li><li>Better linking from the homepage into the rest of the site spreads the homepage PR around more efficiently. The homepage now lists top selections in a number of categories. The details pages for the top selections then link to related programs and so improve the rank of lots of the inner pages.</li></ul>Breaking away from the usual <a href="http://www.softwarelode.com/">software downloads site</a> categories also seems to be showing some benefit. The <a href="http://www.softwarelode.com/antivirus-software.php">antivirus software</a> and <a href="http://www.softwarelode.com/free-dvd-software.php">free dvd software</a> pages seems to be attracting a decent amount of traffic these days.<br /><br />As SoftwareLode was <a href="http://software-product-development.blogspot.com/2008/06/new-software-directory-launched.html">launched</a> only 7 months old, I'm pretty pleased with its performance and hopeful of further increases in traffic in the months ahead.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-75604515977130887422009-01-08T14:34:00.000-08:002009-01-09T06:52:56.795-08:00ADO.Net, DataAdapters & DataSets: What are they?<div>ADO.Net is Microsoft's .Net interface to databases. Traditionally, to work with databases like Access, SQL Server and the like, you needed to know a fair bit about SQL. With ADO.Net you still need to know SQL commands but some pretty near classes are provided that allow you to hive off the SQL stuff and work with a much easier set of objects when adding, deleting or updating items in a database.</div><div></div><div><br /></div><div>The two major classes described in this post are the DataAdapter and DataSet classes. It wasn't until I'd actually coded some example that the ease of use of these classes became clear to me. I'll expand on the classes in later posts and give some code examples but for now I'm just going to give an overview of their purpose. This picture gives an idea of how the classes interact to allow you (the programmer/ user) to work with a database.</div><div><br /></div><img id="BLOGGER_PHOTO_ID_5289057226761251954" style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 400px; CURSOR: hand; HEIGHT: 110px; TEXT-ALIGN: center" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjn_dMQjHf6NENWe0ulwdGKtETfLm0X4elaaBDx3Omww7fmGatBqZy9blFfqS9N84MlwzlqXUL211h2VhFp5y5cv6FSHGiDq-rjMqF7UkeiJU31L6ZKRd2DNScKpfeUkc04FTzb2bZ3Cezr/s400/ADO_DataAdapter_DataSet.jpg" border="0" /> <div></div>The four items in the picture are:-<br /><br /><strong>The Database</strong><br /><br />This is something like an Access or SQL Server database. ADO.Net provides classes to handle many different types of database. All the classes inherit from a set of base classes so to a degree you can hide the details of the specific database type from your code.<br /><br /><strong>The DataAdapter</strong><br /><br />The DataAdapter class is the SQL workhorse. There are a number of different DataAdapter classes for different databases, e.g. OldDataAdapter for working with an Access database. It's the DataAdapter class that does all the work - reading, inserting, deleting and updating - in interacting with the database. All you have to do is build the SQL commands for the DataAdapter to do the work and then let it get on with it's job.<br /><br /><strong>The DataSet</strong><br /><br />The DataSet is the class you interact with when manipulating data values in the database. The data within a table in the actual database can be thought of as a collection of rows, with each row containing a number of named field values. The DataSet mirrors this view of the database. The DataSet is a collection of DataRow objects, with each DataRow begin a Dictionary of the values in the row where the dictionary keys are the field names.<br /><br /><strong>How do the classes interact?</strong><br /><br />To work with the data, you configure a DataAdapter instance with the SQL commands to read data, insert, update and delete data in the database. You then ask the DataAdapter to fill a DataSet. You can then change values in rows in the DataSet, add new rows or delete rows. When you've made the changes, you ask the DataSet to get the DataAdapter to reflect your changes into the actual database.<br /><br />In my next post, I'll give some code examples using the DataSet and DataAdapter classes.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-45004217398266643972009-01-07T03:41:00.000-08:002009-01-07T03:55:20.436-08:00Error reading setup initialization file: InstallShield ProblemYesterday I had a support mail from a user who was unable to install on Windows Vista Home Premium. I was rather worried about the report since we'd just release SliQ 1.5.1 the evening before and I always get a bit nervous when we make a new software release.<br /><br />The error the user was getting was "Error reading setup initialization file". Googling for info I found information saying that the error was sometimes reported if the <a href="http://software-product-development.blogspot.com/2008/07/installshield-115-and-net-20-runtime.html">InstallShield package</a> had been corrupted. I tried downloading the lastest installer from SliQTools and tested it successfully on Vista and XP machines here in the office so I knew the live release wasn't corrupt. More research on Google indicated that the problem sometimes occurred if the installer took a long time to download -it was taking over 20 minutes on the user's Vista machine. Luckily the user was very technically aware and was very helpful in trying out different things.<br /><br />I asked the user to download the installer to a Windows XP machine. This time the download took only 5 minutes over the same office broadband connection as with the Vista machine. The installation ran perfectly. The user then copied the installer on a flash drive and installed correctly on the original Vista machine. That evening the user download and installed correctly on his home Vista machine.<br /><br />I find it hard to believe but the finger is pointing at the installer package being corrupted during the download process. There's not a lot I can do about people's broadband connection but I may have to think up some strategies for reducing the size of the download.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-2143702840637799132009-01-06T01:21:00.000-08:002009-01-07T02:50:35.687-08:00Getting out of the supplemental index<p>Back in late summer I reevaluated the linking strategy between my websites. Up until then I'd used my main site to feed link juice into my newer sites - softwarelode and so on. I decided this was a bad thing to keep on doing, since my original intention was to feed link juice back into my main money-earning site and not do things the other way around.</p><p>It was interesting though to see how well sites like softwarelode responded to getting a few links from my main site. Basically within 3 weeks softwarelode started getting a few hundred visitors a day even though it was a new site. Predictably, when I removed the links the visitor numbers began to fall but at a much slower pace than the visitor numbers grew in the first place. Rather than the 3 weeks or so for the visitor numbers to peak, it took 2 to 3 months for the visitor numbers to fall away. During those 3 months, Google did some mini toolbar <a href="http://software-product-development.blogspot.com/2008/06/what-is-google-pagerank.html">PageRank</a> exports and some of the inner pages of softwarelode started showing PRs of 2 or 3. By early December though all pages apart from the homepage were showing PR N/A and visitor numbers were 20% of the peak.</p><p>As the visitors fell away, more of the softwarelode pages were falling into Google's supplemental index. When a page is in the supplemental index it's not going to turn up in SERPS execept for very specific/ obscure search phrases. The supplemental index is purgatory for web pages. I had a look around the web to see what advice I could find. As to be expected the advice was that old chestnut - build backlinks. So, before Christmas I did a spurt of backlink building and I'm pleased to say that since the New Year visitors are returning to softwarelode and the Adsense income is beginning to climb again. Since yesterday (5th Jan), an extra 350 pages are marked as being in the main index. I know of similar sites to softwarelode with about 2500 pages in the main index that make a decent amount of Adsense income (few hundred dollars a month) so hopefully I'm on target to making softwarelode an earning website by the middle of 2009.</p>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com2tag:blogger.com,1999:blog-4498544602373544056.post-32188252007032417672008-12-19T00:27:00.000-08:002008-12-19T00:31:41.295-08:00Measuring the competitiveness of keywordsWhen writing a new website and choosing keywords, it's easy to make the mistake of choosing ones which are far too competitive. For a new website, it will be difficult to rank well for competitive keywords unless you can get some very high quality links from high PR sites.<br /><br />Competitiveness is a difficult thing to measure and it has to be balanced against the search volume for any particular keywords. It might be worth optimising for competitive keywords if the search volume is very high and you don't mind taking a longer term view of ranking well. Taking the opposite view, it isn't worth optimising for uncompetitive keywords if the search volume is very low.<br /><br />One way of investigating the competitiveness of keywords is by using Google's own keyword research tool at <a href="https://adwords.google.com/select/KeywordToolExternal">https://adwords.google.com/select/KeywordToolExternal</a>. This tool shows monthly search volumes for keywords together with a rough gauge of the competition for the keywords.<br /><br />Another rough way of gauging the competition is by using the allintitle: operator when doing a search. Using the allintitle operator makes the SERPS only contain those pages which have the search words in their title. Since a page title is a key SEO factor, the number of results returned is a rough and ready gauge of competitiveness. For example, if you want to measure the competition for web design, do the following search on google.co.uk:<br /><br />allintitle:web design<br /><br />This returns 9,800,000 results. Trying:<br /><br />allintitle:seo<br /><br />returns 13,800,000 results.<br /><br />Contrast these numbers with a set of keywords that we can guess are pretty uncompetitive:<br /><br />allintitle:british vineyards<br /><br />This returns 639 results, or ...<br /><br />allintitle:web design worcester<br /><br />which returns 1050 results.<br /><br />Of course, the number of pages that include keywords in their title doesn't tell you the full story of how competitive a set of keywords are but it is a start. For one thing, allintitle doesn't tell you how well optimised the pages are, e.g. the first 50 pages in the results might have good links and content and be hard to beat without a lot of work. allintitle though is a useful tool to add to your SEO arsenal.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-58146039679822454412008-12-15T13:46:00.000-08:002008-12-15T14:01:02.077-08:00SliQ 1.5 ReleasedAfter a few months development SliQ 1.5 has been released and includes a new <a href="http://www.sliqtools.co.uk/recurring-invoices.aspx">recurring invoice </a>feature. The recurring/ automatic invoice feature has been in development for the last 3 months. During this time, feedback from a number of users/ potential users was used to guide the implementation. In line with earlier feature additions, the emphasis has been on making recurring invoices as easy to set up as possible.<br /><br />With two or three mouse-clicks you can now make SliQ Invoicing automatically raise repeat copies of invoices. All you need is select an invoice and check the Recurring? box in the toolbar.<br /><br /><a href="http://www.sliqtools.co.uk/images/recurringbillingsetup.jpg"><img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 332px; CURSOR: hand; HEIGHT: 228px; TEXT-ALIGN: center" alt="" src="http://www.sliqtools.co.uk/images/recurringbillingsetup.jpg" border="0" /></a> ... then confirm the frequency for raising the invoices ...<br /><br /><br /><br /><p><img style="DISPLAY: block; MARGIN: 0px auto 10px; WIDTH: 362px; CURSOR: hand; HEIGHT: 104px; TEXT-ALIGN: center" alt="" src="http://www.sliqtools.co.uk/images/recurringdetails.jpg" border="0" />This will save loads of time for anyone regularly raising repeat copies of invoices, e.g. website designers charging monthly for SEO or website maintenance. </p><p>SliQ 1.5 also includes a bulk printing facility. SliQ now tracks which invoices have been printed and allows the user to print all un-printed invoices with a single menu click. This should greatly speed up the monthly billing process for SliQ's users, especially if most of the user's invoces are automatically raised by SliQ using the recurring invoice feature.</p>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-13592120084857183322008-12-03T04:54:00.000-08:002009-01-07T02:49:37.836-08:00SEO: Doing it professionallyAfter helping out a few friends and acquaintances with website optimisation, I've been approached by a <a href="http://www.jmd.eu.com/">web designer</a> about doing SEO work for them on an ongoing basis. They would like me to propose a service or set of services I could offer together with a set of prices.<br /><br />The easiest and cheapest service I could offer is sets of directory submissions. To do these I could use my development version of professional <a href="http://www.sliqtools.co.uk/directory-submission-tool.aspx">directory submitter</a>, SliQ Submitter Pro. This should allow me to do a hundred or so submissions an hour.<br /><br />Of course there are a lot of other techniques I could use to do link-building. The more I think about it though, the more I feel a fixed price service won't do the job. SEO is a long-haul activity and needs to be spread over a number of months. Ideally I would spend 6 or so hours a month doing offsite optimisation for a website using directory submissions, articles where appropriate plus other link-building techniques I've become familiar with.<br /><br />Spreading the SEO work over a few months should give better value and satisfaction to the customer. With a one-off hit at link-building, there won't be time to see any results before the work is completed. It's also likely to be unsuccessful. To do optimisation, you have to be able to monitor the results and make changes over a period of weeks. with newer sites this is especially important as the sites tend to perform well for a period before dropping back.<br /><br />The other aspect I've got to price up is the on-page optimisation. Do I charge per page? Do I have a minimum charge that makes it worthwhile doing the job in the first place? If I think back to when I was looking for SEO help, I would often get quoted £350 a site or £100 per page. I never felt entirely comfortable with quotes like that since they didn't quantify what work was being done. Now, I've got more experience I can also see that it's pretty hard - or at least less optimal - to optimise a single page on a website.<br /><br />I'll also have to think through whether I offer any PPC, e.g. <a href="http://software-product-development.blogspot.com/2008/05/10-tips-for-using-google-adwords.html">Google Adwords advice</a>. My feeling right now is that I shouldn't since I don't think it's a good medium to long term way of getting traffic/ sales, or rather I think that organic SEO will be the most cost-effective after a 6 month to 1 year period.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-89841631029565036552008-11-30T06:32:00.000-08:002008-12-03T04:54:26.031-08:00Software Trial Periods: How long before customers buy?With the November releases of SliQ Invoicing and Quoting (Standard and MC), I made a change to the format of the product and unlock codes. The idea behind this was to simplify the process for users, making it easier to check if a product code was correct. The new format also makes it easier to generate an unlock code. The new unlock code format is also longer - meaning that people will be less likely to try and type the code in by hand. This should reduce the chances of the unlock code being mistakenly typed. On the advice of a fellow software vendor, I now use the customer’s identity - land and email addresses in the code making it easier to match codes to customers in the future.<br /><br />I've always wondered how long people use my software before purchasing. People have up to 30 days free use before they need to buy but until now I've had no way of gauging how long people try before buying on average. With the change in the code format, I've been able to tell whether someone download the software before or after the change. Previously, I’d read posts from other shareware authors or marketing people advising that people tend to buy more or less immediately - within hours - if they are going to buy. The longer people leave between trying and buying, the less chance of a purchase. Although not a scientific test, in the three or so weeks since the last release, 90% of purchasers still use the old format code. I'm taking this to mean that, at least with my products, most people take pretty much full advantage of the 30 day trial period.<br /><br />Of course, I could get worried by purchasers still registering with the old product codes. With the credit crunch I could assume that I’m not getting any new customers and I’m just exhausting the supply of people who downloaded a trial a month ago. However Google Analytics is actually showing an increase in traffic over the past 3 weeks and my download bandwidth has increased too. This means I'm probably getting proportionately more new trial users. The sales haven't dropped off either, which I was kind of expecting for business-related software in the run-up to Christmas.<br /><br />If all this means that most people take advantage of the trial period then I’m glad. I want people to use the full trial period to make sure they are happy to purchase. Hopefully it reduces the support overhead in the long-term since those people who do buy will be more happy with the features the software provides.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-22650006124181258302008-11-28T09:22:00.000-08:002008-11-28T09:25:53.885-08:00Remote Support Access<p>For a while, I've been looking for a way of improving support to customers. If a customer is confused by a feature or we can't understand the problem they are trying to describe things can be difficult. The only real way to move forward in such situations is to see what the customer is actually doing on their PC. Site visits are not really possible - for cost reasons if nothing else - so I've been looking for a way of sharing PC desktops remotely over the internet.</p><p>Discussions with friends raised a number of possibilities - Webex, Windows Invite a Friend and NetViewer were mentioned. The cheapest options is Windows Invite a Friend - it comes free with Windows XP and Windows Vista. I tried it our on a pair of PCs in our office but found that:</p><ol><li>You have to explain to the client/ customer how to get the service going and send an invite for support.</li><li>The help pages linked from XP's help are no longer present on Microsoft's website.</li></ol><p>Both of these points make me wary of using Invite a Friend - they wouldn't make SliQTools look professional.</p><p>So I took at NetViewer. This seems a reasonable service - the cost is good and the service works well. The support technician sends an invite to the customer, the customer downloads a small client program (linked from the support invite email) and gives access to his PC to the support person. </p><p>To see an alternative, I took a look at <a href="http://www.logmein.com/">LogMeIn Rescue</a>. This turned out to be the Rolls-Royce remote support service. It's a really good package, working more smoothly and with a more professional, friendly feel for the technician and customer. The only downside is the cost - 4 times that of NetViewer. Overall though, I think you get what you pay for and LogMeIn Rescue seems like a good choice.</p>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-12951901822983259612008-11-12T13:50:00.000-08:002009-01-07T13:30:40.055-08:00Free Directory Submission SoftwareIt's about 3 months since I made a new release of my <a href="http://software-product-development.blogspot.com/2008/07/new-directory-submission-tool.html">free directory submission tool</a>, SliQ Submitter. Since I made the release, I've been busy on other projects. One of those projects is a faster directory submitter that should make the whole submission process much quicker - perhaps as little as 1 or 2 seconds if the directory doesn't have a captcha.<br /><br />SliQ Submitter was my first attempt at writing <a href="http://www.sliqtools.co.uk/directory-submission-tool.aspx">directory submission software</a>. Initially I made 3 releases very soon after each other - first with a free web directory list containing 450 directories, quickly followed by 2 more releases until the package listed over 2000 web directories. I initially tested submissions to all the listed directories and was confident that all directories worked and would accept submissions.<br /><br />Soon after the last release though, I realised that web directories don't stand still. Before long the PR of the web directories changed, with a lot going to PR0. Whether this caused a number to give up I don't know, but quite a few of the 2000 went offline. As the months have passed, a number of the domains expired and a good percentage of the directories switched to paid.<br /><br />In the last few days, I've rechecked the directories, removing those which are dead or have switched to being paid. Of the original 2250, there are now about 1250 left. As of today though, all of these are free and if a submitted website gets accepted by a good proportion of the 1250 directories, the site should get a good boost in PR and performance in SERPs.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-43890495939462925402008-11-12T13:15:00.000-08:002008-11-12T13:53:16.590-08:00Getting more Visitors and Page ViewsI've been helping a friend optimise his <a href="http://www.softtester.com/">software archive</a> site SoftTester. The site is nearly 5 years old and has about 100,000 pages as well as being listed in DMOZ. Over the last couple of years his site had been slowly losing visitors. By June he was down to only a few hundred a day. Needless to say, his income from Adsense had fallen away to almost nothing.<br /><br />In June, we decided to do some SEO on the site. We mainly concentrated on on-page SEO and improved page titles and descriptions as well as adding good h1 and h2 tags. His site is database-driven, with most of the content coming from PAD files submitted by software authors.<br /><br />We changed some of the data used to display info as well as shuffling the position of some the displayed items. Whatever we did, it seems to have paid off. Within a couple of weeks, search engines started sending more traffic to the site. In particular traffic from Google began to grow steadily.<br /><br />As well as on-page optimisation, we set about getting new links to the site. One of the main ways <a href="http://www.softwarelode.com/">software download</a> sites get links is by reviewing and making awards to listed software packages. Software authors can then use a nice award graphic on their own websites and link back to the archive. The existing graphics were a bit tired, so I encouraged my friend to buy classy new ones and before long he began to get extra links to his site.<br /><br />After waiting 4 or 5 months, the number of visitors and page views had grown by a factor of nearly 5 and the income from Adsense had grown along with the traffic. Not a bad result for a few hours work spread over a few days.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-33848020988432553662008-11-10T10:40:00.000-08:002009-01-07T13:29:01.780-08:00SEO’ing webpages using precise Keywords<p>A friend of mine has been trying to optimize his webpages. His site is an online shop selling jewellery. On each webpage, he's added a set of links to each product page. These links aid the user in navigating around the site and also attempt to improve SERPs performance as the anchor text for each link includes the keywords for each product page. For example, on one page he's trying to sell some <a href="http://www.mcls4u.com/shop/choker-jewellery-turquoise-blue-wand-pendant/prod_38.php">Choker Jewellery</a>, so he made Choker Jewellery the anchor text of the link to the page.<br /><br />All the links and anchor text are chosen to reinforce the keywords used on the linked page. He's taken things one stage further and dynamically parsed the page description from the backend database and generated the anchor text for the links automatically. This will make it much easier to add product pages in the future and is a good example of using a database to make management of a website easier.</p><p>To give the links extra value he's added the navigation near the top of each webpage on the site. This should show google that these links are important. To make the placement of the links useful to visitors he's also added the text “Recent Searches” so the links look like phrases people have used to search for items on my site, but more importantly providing google with an important set of links.<br /><br />He wasn't sure whether to have these links at the top of the page as they do look odd. However his biggest problem was deciding what keywords to use for his home page. He finally decided on <a href="http://www.mcls4u.com/shop">Cheap Jewellery</a>. Having developed several websites in the past and getting little traffic, he was keen to better this time and used the Adwords keyword tool to find keywords with a good expected level of traffic. He then matched the best keywords against the products on his shop site. An example would be <a href="http://www.mcls4u.com/shop/jewelry-fun-hen-night-party-l-plate-pendant/prod_23.php”%3EJewelry%3C/a">Jewelry</a> which is a spelling mistake, but a good keyword from a volume point of view with a good, i.e. low, level of <a href="http://software-product-development.blogspot.com/2008/12/measuring-competitiveness-of-keywords.html">keyword competition</a>. This was a difficult process but he found that keywords with a good expected level of traffic aren’t necessarily the keywords people use when searching for things to buy from his site. Therefore the whole strategy is quite risky, but definitely worth trying.</p>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-3003813134156884442008-10-13T13:19:00.000-07:002008-10-13T13:59:29.537-07:00Capturing an image/ thumbnail of a webpage in C#<div align="justify">For a while I've been figuring out how to programmatically get an image of a web page using C# and .Net. This could have a number of uses such as displaying a thumbnail of a web page. I found a number of methods by Googling but on the whole they seemed a bit lengthy. Eventually, I combined bits of a number of methods and then simplified things by trying out an alternative approach myself. One key thing I wanted to do was to create a mini picture of a website for display in a new desktop app I'm developing.<br /><br />In the end I wrote a simple class with a single static method called<br />GrabImageOfWebPage. GrabImageOfWebPage takes a .Net WebBrowser control instance as an argument together with the required size for the captured image. The web page loaded in the WebBrowser control is captured (the entire client area of the control is captured) and shrunk/ enlarged into a bitmap of the required size. Here's the code:<br /><br /></div><div align="justify"><pre><br /><span style="font-family:courier new;font-size:85%;">using System;<br />using System.Collections.Generic;<br />using System.Text;<br />using System.Windows.Forms;<br />using Microsoft;<br />using mshtml;<br />using System.Runtime.InteropServices;<br />using System.Runtime.InteropServices.ComTypes;<br />using System.Drawing;<br /><br />namespace BrowserComponents<br />{<br /> /// <summary><br /> /// Class providing a static method to return a bitmap of a web page rendered in</span><br /> <span style="font-family:courier new;font-size:85%;">/// a .Net webbrowser control.<br /> /// </summary><br /> public class CBrowserImageGrabber<br /> {<br /><br /> [ComVisible(true), ComImport()]<br /> [GuidAttribute("0000010d-0000-0000-C000-000000000046")]<br /> [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]<br /><br /> private interface IViewObject<br /> {<br /> [return: MarshalAs(UnmanagedType.I4)]<br /> [PreserveSig]<br /> int Draw(<br /> //tagDVASPECT<br /> [MarshalAs(UnmanagedType.U4)] UInt32 dwDrawAspect,<br /> int lindex,<br /> IntPtr pvAspect,<br /> [In] IntPtr ptd,<br /> //[MarshalAs(UnmanagedType.Struct)] ref DVTARGETDEVICE ptd,<br /> IntPtr hdcTargetDev,<br /> IntPtr hdcDraw,<br /> [MarshalAs(UnmanagedType.Struct)] ref tagRECT lprcBounds,<br /> [MarshalAs(UnmanagedType.Struct)] ref tagRECT lprcWBounds,<br /> IntPtr pfnContinue,<br /> [MarshalAs(UnmanagedType.U4)] UInt32 dwContinue);<br /> }<br /><br /> public static Image GrabImageOfWebPage</span><br /> <span style="font-family:courier new;font-size:85%;">(WebBrowser Browser, Size ImageSize)<br /> {<br /> // Get the view object of the browser<br /> //<br /> IViewObject VObject = Browser.Document.DomDocument as IViewObject;<br /></span><br /><span style="font-family:courier new;font-size:85%;"><br /> if (VObject != null)<br /> {<br /> // Construct a bitmap as big as the required image.<br /> //<br /> Bitmap bmp = new Bitmap(ImageSize.Width, ImageSize.Height);<br /></span><br /><span style="font-family:courier new;font-size:85%;"><br /> // The size of the portion of the web page to be captured.<br /> //<br /> mshtml.tagRECT SourceRect = new tagRECT();<br /> SourceRect.left = 0;<br /> SourceRect.top = 0;<br /> SourceRect.right = Browser.Right;<br /> SourceRect.bottom = Browser.Bottom;<br /> </span><br /><span style="font-family:courier new;font-size:85%;"><br /><br /> // The size to render the target image. This can be used<br /> // to shrink the image to a thumbnail.<br /> //<br /> mshtml.tagRECT TargetRect = new tagRECT();<br /> TargetRect.left = 0;<br /> TargetRect.top = 0;<br /> TargetRect.right = ImageSize.Width;<br /> TargetRect.bottom = ImageSize.Height;<br /> </span><br /><span style="font-family:courier new;font-size:85%;"><br /><br /> // Draw the web page into the bitmap.<br /> //<br /> using (Graphics gr = Graphics.FromImage(bmp))<br /> {<br /> IntPtr hdc = gr.GetHdc();<br /> int hr =<br /> VObject.Draw((int)DVASPECT.DVASPECT_CONTENT,<br /> (int)-1, IntPtr.Zero, IntPtr.Zero,<br /> IntPtr.Zero, hdc, ref TargetRect, ref SourceRect,<br /> IntPtr.Zero, (uint)0);<br /> gr.ReleaseHdc();<br /> }<br /></span><br /><span style="font-family:courier new;font-size:85%;"><br /><br /> // Return the bitmap.<br /> //<br /> return bmp;<br /> }<br /> else<br /> {<br /> return null;<br /> }<br /> }<br /> }<br /> }</span><br /><span style="font-family:Courier New;font-size:85%;"><br />}</span></pre></div><div align="justify">To gain visibility of the types in this example, you have to include the following uses:</div><div align="justify"> </div><div align="justify"></div><div align="justify"><span style="font-family:courier new;font-size:85%;"></span></div><div align="justify"><span style="font-family:courier new;font-size:85%;">using mshtml;</span></div><div align="justify"><span style="font-family:courier new;font-size:85%;">using System.Runtime.InteropServices;</span></div><div align="justify"><span style="font-family:courier new;font-size:85%;">using System.Runtime.InteropServices.ComTypes;</span></div><div align="justify"><span style="font-family:courier new;font-size:85%;">using System.Drawing;</span></div><div align="justify"></div><div align="justify"></div><div align="justify"> </div><div align="justify">and you also need to add a .Net reference to your project for Microsoft.mshtml.</div><div align="justify"></div><div align="justify"><br />Using the method is then pretty easy. The example code below create a webbrowser control and loads a webpage. When the webpage is fully loaded, it grabs an image 10% the size of the original page and displays it in a picture box.<br /><pre><br /><span style="font-size:85%;">WebBrowser mWebBrowser;<br /> <br />public Form1()<br />{<br /> InitializeComponent();<br /><br /> mWebBrowser = new WebBrowser();<br /> mWebBrowser.Width = 1024;<br /> mWebBrowser.Height = 768;<br /> mWebBrowser.ScrollBarsEnabled = false;<br /><br /> mWebBrowser.DocumentCompleted +=<br /> new WebBrowserDocumentCompletedEventHandler<br /> (mWebBrowser_DocumentCompleted);<br /> mWebBrowser.Navigate<br /> (@"http://www.software-product-development.blogspot.com");<br />}<br /><br /><br />void mWebBrowser_DocumentCompleted(object sender,<br /> WebBrowserDocumentCompletedEventArgs e)<br />{<br /> if (mWebBrowser.ReadyState == WebBrowserReadyState.Complete)<br /> {<br /> Image Img =<br /> BrowserComponents.CBrowserImageGrabber.<br /> GrabImageOfWebPage(mWebBrowser, new Size(102, 77));<br /><br /> if (Img != null)<br /> {<br /> pictureBox1.Image = Img;<br /> }<br /> }<br />}</span><br /></pre></div>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com1tag:blogger.com,1999:blog-4498544602373544056.post-52070056069347555502008-10-06T07:33:00.000-07:002009-01-07T02:51:34.500-08:00Losing a PageRank ValueIn the mini-update toolbar export on Sept 26th this blog lost its <a href="http://software-product-development.blogspot.com/2008/06/what-is-google-pagerank.html">PR</a>, i.e the value went to N/A. Previously the PR had been 3. Why this has happened I don't know. I haven't linked to any silly sites or reduced the frequency of posting.<br /><br />Today I also noticed that a few inner pages on the blog have PR. I haven't noticed this before. It's strange that the older posts have PR but the blog home page is back to PR N/A. Google Analytics isn't showing any change in the level of traffic to the blog.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-37464105130151475182008-09-12T05:25:00.000-07:002009-01-07T02:58:12.930-08:00How to keep on the good side of GoogleWhen people are trying to improve their ranking in search engine results page, a lot of people will use any advice they can find in a struggle to improve rankings. People need to be wary which advice they follow though. Some advice will cause you to be penalised by Google.<br /><br />If a page on your website is penalised, it will not perform as well as it might in search results. Here are some tips to help avoid penalties. In the case of a new website, it may never get to perform well in the first place.<br /><br />Remember that outside Google, no-one really knows what counts as good or bad in terms of SEO. There is some general advice from Google about having good, unique content and quality backlinks. Other than that, people are justing using their experience and guesswork to find out what works and doesn't. A lot of SEO information online is copied and spread as online myths.<br /><br />With this proviso in mind, here's a fairly non-controversial list of things to avoid.<br /><br /><ul><li><strong>Avoid Exchanging Links<br /></strong>Excessive link exchanging should be avoided as Google may see this as an attempt to artifically improve rank. A few link exchanges will be OK but avoid large numbers. Link farms - where a large group of sites hyperlink to all other sites in the group should always be avoided.<br /></li><li><strong>Do not Sell links<br /></strong>Selling links is a no-no - unless the hrefs use the nofollow attribute. If your site sells dofollow links and Google becomes aware it may well be penalised. Google's WebMasters site allows people to report paid links. Rumour has it that Google may use this information to adjust its algorithms to improve detection of paid links.<br /></li><li><strong>Do not buy links<br /></strong>Recently, Google has threatened to penalise sites they discover have purchases dofollow links from another site. Logically thinking though, this does not seem possible - or at least it would be extremely unfair! If this were to be the case it would be easy to penalise a competitor by purchasing links to their site and then reporting them to Google.<br /></li><li><strong>Avoid duplicate content</strong><br />If possible, avoid duplicate content. For example, don't make the same post to two different blogs. Google will ignore copies of content. A few copies will make it into Google's index but lots of copies will be ignored. Even on different pages within a website, try to keep the textual content unique and avoid repeating whole paragraphs of text.<br /></li><li><strong>Don't stuff keywords<br /></strong>If you want to perform well for a certain keyword, stuffing your webpages full of the keyword will not help. Write you copy in a natural way so that it reads well. If you are writing a web page about Google penalties (for example), the keyword "Google Penalty" will naturally appear a number of times - you don't need to repeat the phrase scores or hundred of times.<br /></li><li><strong>Don't include hidden text</strong><br />Make the contents of the webpage visible to the user. For example, don't include extra content such as white text on a white background that the user cannot see.</li></ul>Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0tag:blogger.com,1999:blog-4498544602373544056.post-57385878141644343602008-09-07T23:37:00.000-07:002009-01-07T02:58:58.979-08:00Sitelinks updateToday, Google Webmasters shows an updates in my sitelinks but these don't seem to have made it to the SERPs yet. Three new links have been added to my sales, support and SliQ Submitter pages. When these links make it to the search results, the <a href="http://software-product-development.blogspot.com/2008/08/further-thoughts-on-google-sitelinks.html">sitelinks</a> will look much better than at present.Mikehttp://www.blogger.com/profile/09024718565669731258noreply@blogger.com0