<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Pearl Tech &#187; Geer</title>
	<atom:link href="http://blog.pearltechnology.com/author/geers/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.pearltechnology.com</link>
	<description></description>
	<lastBuildDate>Thu, 05 Jan 2012 14:47:55 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Improve Website Performance by Using a Single Background Image for Your Whole Website</title>
		<link>http://blog.pearltechnology.com/a-single-background-image-for-your-whole-website/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/a-single-background-image-for-your-whole-website/#comments</comments>
		<pubDate>Fri, 04 Nov 2011 13:38:15 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Background Image]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=1249</guid>
		<description><![CDATA[How to improve performance of your website by using a single background image...]]></description>
			<content:encoded><![CDATA[<p>Have you ever tried to learn or borrow design ideas from other good websites?  I have.  I happened to see an idea of using one background image for all background images that are needed for the entire website.  I thought it was a very clever idea, so wrote this post to share it.</p>
<p>Basically, you would integrate and organize all little background images that your website needs into one &#8220;big&#8221; (won&#8217;t be too big anyway) image file, like the one shown below.</p>
<p><img class="size-full wp-image-1251 aligncenter" title="Combined Background Image" src="http://blog.pearltechnology.com/wp-content/uploads/2011/11/background.png" alt="Combined Background Image" width="47" height="82" /><br />
It has got some corner images for cornered boxes and a few icons.  All images are combined into this one image file while each one of them is laid out nicely.  Well, it’s nice to look at and organize them that way, but how you can use them?  Suppose you want to use the contact icon in front of some text.  Normally, you could do something like:</p>
<pre name="code" language="XML">
<span style="background:url(images/background.png) no-repeat; padding-left:20px;">Contact Name</span>
</pre>
<p><img class="aligncenter size-full wp-image-1252" title="bg1" src="http://blog.pearltechnology.com/wp-content/uploads/2011/11/bg1.JPG" alt="bg1" width="153" height="39" /></p>
<p>However, with the combined image, it won’t show the background image as expected.</p>
<p>To make it work, you just need to do something like:</p>
<pre name="code" language="XML">
<span style="background:url(images/background.png) no-repeat -25px 0px; padding-left:20px;">Contact Name</span>
</pre>
<p><img class="aligncenter size-full wp-image-1254" title="bg2" src="http://blog.pearltechnology.com/wp-content/uploads/2011/11/bg2.JPG" alt="bg2" width="126" height="32" /></p>
<p>As you can see, it’s fairly easy – you just need to set the position of the background image instead of using the default position, so that only the appropriate background image shows up and rest of the image remains hidden.</p>
<p>Why are you doing this?  I don’t claim that I fully understand the purpose behind this idea, but here is one reason that I can think of: performance.</p>
<p>When you view a web page, everything you see on the screen needs to be downloaded, and each download is initiated by an HTTP request.  The more files you download, the more HTTP requests are needed, and the more load is put on the web server to handle these requests.  Usually, the time spent on processing an HTTP request is much less than the time spent on downloading, but if the file size is small, the processing time for the request will take a big portion of the whole processing time.  In the other words, it will be more efficient to send one request and download a big size file than to send a bunch of requests to download smaller files.  Although it still takes little time for the web server to process a request, it could use a noticeable amount of resources of the web server to handle them, if there are thousands of people hitting your web server.  Also, a web server can only process a certain number of requests at the same time.  If there are 50 background images that are used on most of the pages on your website, the web browser will probably need to send that many requests to download each one of them separately, unless they are already cached by the web browser.  So, if you can combine those 50 files and let the browser only request and download it once, you allow your web server to run more efficiently.  Previously, the web server has to process 50 requests to get those background images to the web browser, but now it only needs to process 1 request, and get the same content to the web browser.  Make sense?</p>
<p>There may be other practical reasons for this idea.  Please share your input below if you find any. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/a-single-background-image-for-your-whole-website/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Lessons Learned: XSS Security Scan</title>
		<link>http://blog.pearltechnology.com/lessons-learned-xss-security-scan/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/lessons-learned-xss-security-scan/#comments</comments>
		<pubDate>Mon, 25 Apr 2011 18:25:53 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Security]]></category>
		<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Security Scan]]></category>
		<category><![CDATA[XSS]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=1212</guid>
		<description><![CDATA[Lessons learned during cross-site scripting security scan...]]></description>
			<content:encoded><![CDATA[<p>During the code review process for an ASP.NET web application that we built for a client, a cross-site scripting (XSS) security scanner was used to check whether the application was secure enough to survive during XSS attacks.  Fortunately, the application was well designed and coded leaving no chance for the scanner to inject even a single line of script for XSS attack.  Alright, I will be honest with you &#8211; we did found a couple issues during the scan, but we were able to fix them before the application was delivered to our customer.  So, here are the two notes I would like to share:</p>
<ol>
<li><strong>Watch out for those non-ASP.NET components</strong>.  Actually, all ASP.NET components were designed very well and the scanner was not able to inject any script on any page.  The only problem we found was on the error page which accepts some parameters in the query string and displays part of the information on the error page which is a fairly common implementation.  Because it is simply an HTML page and does not contain server-side code, it was overlooked for XSS attack.  The scanner was able to embed scripts in the query string, and had them executed when the error page tried to render them on the page.  Although the error page cannot post any data back to the ASP.NET application itself or insert any data to the database, it is still a security risk.  You never know what hackers can do with this small hole in your site.</li>
<li><strong>DO NOT perform the scan on production database</strong>.  We performed the scan on our QA environment assuming it would not do any harm to our database because it was only for XSS scan.  However, we have found that it entered thousands of records in a table in our database through a page which only requires one field for data entering.  As a result, the scanner tried all possible injection scripts on that page, and entered them all into the table in the database.  Now, we have a list of scripts we can try on other sites to have some fun. : )  So, I guess we shouldn&#8217;t have done this in the QA environment which points to our production database.  Even if we had to do so for whatever reason, we probably should have pointed the application to a test database for the duration of the scan.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/lessons-learned-xss-security-scan/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Creating Entity Relationship Diagram in Visio</title>
		<link>http://blog.pearltechnology.com/creating-entity-relationship-diagram-in-visio/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/creating-entity-relationship-diagram-in-visio/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 20:23:18 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Access]]></category>
		<category><![CDATA[ER Diagram]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PostgreSQL]]></category>
		<category><![CDATA[Visio]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=1074</guid>
		<description><![CDATA[This article shows you how to use Visio to create database diagram (or ER diagram) for databases such as Access, PostgreSQL, MySQL...]]></description>
			<content:encoded><![CDATA[<p>It is a common task for a developer to build an Entity Relationship (ER) Diagram for an existing database.  If you are dealing with an MS SQL Server, this can be done easily within SQL Server Management Studio, but what if you are given a database in MS Access, PostgreSQL, or MySQL.  There are tools (such as ModelRight) to help you with this, but if you have got MS Visio Professional Edition, you have another option.</p>
<p>Since Visio 2003, a new feature, Reverse Engineer, has been made available in its Professional edition (and Premium edition in Visio 2010).  This feature allows you to connect to an existing database, extract database schema, and create an ER Diagram automatically.  You can also lay things out in the way that you want, and catch changes made to the database.</p>
<p>The key here is to create a connection to your database.  It does not have to be a Microsoft database.  Most likely, if there is an ODBC Data Source defined on your computer, you can connect to your database in Visio and generate the diagram.  In the rest of this article, I will show you how to generate an ER Diagram for an existing Access Database using Visio 2010 Professional Edition.  The process would be similar for connecting to other types of databases.</p>
<ol>
<li>Make sure you have an ODBC Data Source defined for MS Access Database.  Usually, you do not have to do this for Access Database.  It should have been created when Office or Visio is installed.  For other types of databases, you may need to first install an ODBC Driver which is often available from your database provider.</li>
<li>Start Visio, and choose <strong>Database Model Diagram</strong> Template under <strong>Software and Database</strong> Template Category.  It is important to choose the right template, or you will not see the feature we want to use.<img class="aligncenter size-full wp-image-1076" title="ChooseTemplate" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/ChooseTemplate.JPG" alt="ChooseTemplate" width="500" height="263" /></li>
<li>Once the file is created, you will see two new things that you normally do not see.  The <strong>Tables and Views</strong> window in the <strong>Task Pane</strong>, and the <strong>Database Tab </strong>in the Ribbon area.  Please note that you will not see them, if you did not choose the right template in step #2.<img class="aligncenter size-full wp-image-1079" title="NewThings" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/NewThings.JPG" alt="NewThings" width="500" height="396" /></li>
<li>Click on the <strong>Reverse Engineer</strong> button under the <strong>Database Tab</strong> to start the <strong>Reverse Engineer Wizard</strong>.<img class="aligncenter size-full wp-image-1083" title="ReverseEngineerWizard" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/ReverseEngineerWizard.JPG" alt="ReverseEngineerWizard" width="500" height="317" /></li>
<li>Select <strong>Microsoft Access</strong> in the <strong>Installed Visio drivers</strong> drop down list, and choose <strong>MS Access Database</strong> as the data source. (If you are connecting to another type of database, you may have to choose ODBC Generic Driver in this step.)<img class="aligncenter size-full wp-image-1084" title="SelectDataSource" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/SelectDataSource.JPG" alt="SelectDataSource" width="500" height="329" /></li>
<li>Then you will be asked for user credential.  Leave them blank if the database is not password protected. (This step may look different, if you are connecting to another type of database, but the wizard should lead you through the data source setup in a similar way.)  Select your Access Database file and click OK to continue.<img class="aligncenter size-full wp-image-1082" title="PickFile" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/PickFile.JPG" alt="PickFile" width="411" height="428" /></li>
<li>You will be given the chance to select types of objects you want to pull from your database.  Do all that and then click Next to continue.<img class="aligncenter size-full wp-image-1080" title="ObjectOptions" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/ObjectOptions.JPG" alt="ObjectOptions" width="500" height="329" /><img class="aligncenter size-full wp-image-1085" title="Tables" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/Tables.JPG" alt="Tables" width="500" height="329" /><img class="aligncenter size-full wp-image-1081" title="OtherOptions" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/OtherOptions.JPG" alt="OtherOptions" width="500" height="329" /></li>
<li>After everything is set, click Finish to close the wizard window.<img class="aligncenter size-full wp-image-1077" title="Confirmation" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/Confirmation.JPG" alt="Confirmation" width="500" height="329" /></li>
<li>Visio will then connect to your database, and pull desired information back.  Tables and Views will be placed in the <strong>Task Pane</strong>, and shapes and connections will be drawn on the current page (if you chose to do so in step #7).<img class="aligncenter size-full wp-image-1078" title="Diagram" src="http://blog.pearltechnology.com/wp-content/uploads/2011/03/Diagram.JPG" alt="Diagram" width="500" height="430" /></li>
<li>You can drag the entities around on the page without breaking the relationships, and click the Refresh button under the Database tab to get changes from the database.  During the update, new Tables or Views will be added to the <strong>Task Pane</strong>, changes may be applied to the diagram, and everything else should be kept unchanged.</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/creating-entity-relationship-diagram-in-visio/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Joke isn’t a joke any more… Just be creative!</title>
		<link>http://blog.pearltechnology.com/joke-isn%e2%80%99t-a-joke-any-more%e2%80%a6-just-be-creative/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/joke-isn%e2%80%99t-a-joke-any-more%e2%80%a6-just-be-creative/#comments</comments>
		<pubDate>Wed, 30 Mar 2011 21:00:23 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Cloud Storage]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=1090</guid>
		<description><![CDATA[Sometimes, we make fun of people with crazy ideas. But think about it, aren't their ideas pretty cool?]]></description>
			<content:encoded><![CDATA[<p>During a presentation given to all our team members (including IT and non-IT, and management and non-management), I was asked what we as application/software developers can actually do as far as development goes.  To answer the question, I gave two true/false questions back to the audiences.</p>
<p>The first question was “We can do anything you can think of”, and the second one was “We can do anything that makes sense”.  In my opinion, the first is a false statement, but the second is definitely true.  I was not trying to “insult” my colleagues by implying “what they can think of does not make sense”.  What I really meant by that was that not every idea or customer’s requirement that sounds good is feasible in the real world.  Hardware and software limitations do exist, and sometimes there are things we should not do due to considerations in certain aspects like security and performance.  Hopefully, they won’t tag me as some slaggy developers who always say things like “Oh, no… you can’t do this”, or “It’s impossible”, or just laugh at you and your “stupid” ideas, simply because they lack the knowledge and skills, or they are not creative enough.</p>
<p>Here is one of my favorite jokes.</p>
<p style="padding-left: 30px;"><em>Boss: Hey, why the Ctrl+C and Ctrl+V (the hotkeys in Windows to copy and paste content) doesn’t work for me as you just showed me the other day?</em></p>
<p style="padding-left: 30px;"><em>Me: What happened, boss?</em></p>
<p style="padding-left: 30px;"><em>After me doing some investigation, analysis, troubleshooting, testing, validation, and whatever that could be. </em></p>
<p style="padding-left: 30px;"><em>Basically, a few seconds later, I told my boss: “Boss, it’s not going to work, if you press Ctrl+C on your computer at home and press Ctrl+V on the computer in your office”.</em></p>
<p>By the way, my real boss is twice as smart as the boss in this joke.  What!?  Doesn’t sound like he is a smart guy either, does it?  How about 4 times smarter… maybe 8 or 16 times?  Wait, I was trying to praise him.  How do I do this?  All right, my real boss is 2^n times smarter than the boss in the joke above (where n represents a positive integer which equals to a magic number m which can be used to calculate how many times that my boss is smarter than the boss in the joke by using the formula 2^m).  Sounds much better now?  Anyway, my boss is a smart guy.</p>
<p>So, I thought about this joke and asked myself: is there a way to make it work?  I think there is.  With the convenience of the Internet and the power of technology, we as application/software developers can probably make it happen, regardless of whether it is cost-effective or not.  We can develop an application and install it on the boss’s home computer, so when he presses Ctrl+C on his home computer, the content he tries to copy is pushed into the Cloud for storage.  On his office computer, we can load a similar application which allows him to pull the content back from the Cloud.  In addition, if he has a smartphone, he may be able to get the content on his phone as well.  Actually, there are companies doing just this.  Online storage/backup solutions can back up your files and store them in the Cloud (at a secret and secure location or multiple locations).  Sometimes, it’s done automatically in the background which means you don’t need to press Ctrl+C or even notice its existence.  The files stored in the Cloud can be retrieved on-demand or automatically on the other endpoints which could be your laptops, computers or smartphones.</p>
<p>In the end, the joke wasn’t a joke any more.  The boss’s idea wasn’t stupid either.  Online storage service is now a billion-dollar business.  People always say there is no stupid idea.  I couldn’t agree more on that.  So, be creative.  Find a billion-dollar idea for yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/joke-isn%e2%80%99t-a-joke-any-more%e2%80%a6-just-be-creative/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to select unique data in asynchronous SQL queries</title>
		<link>http://blog.pearltechnology.com/how-to-select-unique-data-in-asynchronous-sql-queries/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/how-to-select-unique-data-in-asynchronous-sql-queries/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 13:01:05 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Asynchronous SQL Query]]></category>
		<category><![CDATA[Unique]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=1097</guid>
		<description><![CDATA[In this article, it talks about how to query data asynchronously and make sure the same record will only be selected once.]]></description>
			<content:encoded><![CDATA[<p>Before I move on, I should make my subject clear.  I am not talking about the DISTINCT in a regular SQL SELECT statement.  What I am trying to achieve is to fetch data repeatedly and asynchronously and make sure the same record will only be pulled once.</p>
<p>Think about the case where customers are continuously sending orders to you, and you are batch-processing these orders.  (Batch-processing would generally increase the processing efficiency in cases like this.)  The orders are stored in a SQL Server Database, and there is a service written to repeatedly pull order records back from the database for processing.</p>
<p>In synchronous operation, there is no problem.  The service could select all unprocessed orders from the database, process them, mark them as processed in the database, and repeat the same process over and over again.  The same order will only be processed once, and no order will be missed.</p>
<p>However, in asynchronous operation (or multi-threading), there may be a problem.  When one thread picks up some unprocessed orders from the database, it is not guaranteed that they are not being processed on another thread.</p>
<p>Well, you could let the service pick up the orders and then mark them as being processed, so other threads won’t pick them up again.  However, unless you can select and mark them at the same time, other threads can still squeeze in the small time interval between after you select them and before you mark them in the database.</p>
<p>Can we select and mark the orders at the same time?  Yes, we can use the OUTPUT statement in an SQL UPDATE and SQL transactions to achieve this.  Basically, we mark (update) orders and then select the ones we just marked (updated) within a single SQL transaction.  Here is a demonstration.</p>
<pre name="code" language="SQL">
CREATE TABLE [dbo].[Orders](
	[OrderId] [int] NOT NULL,
	[State] [varchar](50) NOT NULL
) ON [PRIMARY]

GO

INSERT INTO [TestDb].[dbo].[Orders] ([OrderId], [State])
     VALUES (1, 'Waiting for processing')
INSERT INTO [TestDb].[dbo].[Orders] ([OrderId], [State])
     VALUES (2, 'Waiting for processing')
INSERT INTO [TestDb].[dbo].[Orders] ([OrderId], [State])
     VALUES (3, 'Waiting for processing')
GO

UPDATE Orders
SET [State] = 'In processing'
OUTPUT inserted.*
WHERE [State] = 'Waiting for processing'
</pre>
<p>In the SQL statements above, we defined a simple table to store orders, and insert some order records.  In the UPDATE statement, we marked all orders in “waiting for processing” state as “In processing”, and output (return) the orders we just updated.  The keyword “inserted” is somewhat confusing, because we are not inserting new records.  To me, “updated” would make more sense.  Anyway, the result of the UPDATE SQL statement should look like:</p>
<p><code><br />
OrderId	State<br />
-------- --------<br />
1		In processing<br />
2		In processing<br />
3		In processing<br />
</code><br />
In real practice, we should put the UPDATE statement in a SQL transaction, no matter whether it is handled in a Stored Procedure or in the application layer.  By doing this, each order will only be picked up once, no matter how many threads are querying the database using the same SQL statement at the same time.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/how-to-select-unique-data-in-asynchronous-sql-queries/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to start Command Prompt at a designated directory</title>
		<link>http://blog.pearltechnology.com/how-to-start-command-prompt-at-a-designated-directory/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/how-to-start-command-prompt-at-a-designated-directory/#comments</comments>
		<pubDate>Tue, 01 Mar 2011 22:18:59 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[CMD]]></category>
		<category><![CDATA[Start-up Directory]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=988</guid>
		<description><![CDATA[This article shows you how to start CMD at a designated directory]]></description>
			<content:encoded><![CDATA[<p><strong>Problem:</strong></p>
<p>There are several utility programs that I need to run on a regular basis, but none of them are registered in GAC.  To run those utilities, I have to open a CMD window, and navigate to the directory where they are located.  It starts getting annoying when I have to type cd &#8220;C:\Program Files\ProgramName\Version\bin&#8221; (which is the path to the directory where those utilities are stored) every time that I need to run these utilities.  It would be nice if there is a way to set the start-up directory of CMD so that when I start the CMD it navigates to the desired directory automatically.</p>
<p><strong>Solution 1 (not recommended):</strong></p>
<p>One option to do this is to change windows registry.  Actually, I was searching on Google, and found many on-line resources about this.  Here is one talking about  <a title="How to change the default startup directory for Command Prompt" href="http://windowsxp.mvps.org/autoruncmd.htm">How to change the default startup directory for Command Prompt?</a></p>
<p>However, as the article has mentioned, there may be risks associated with this method, and it may cause problems when I need to run windows or other regular utility programs, so it is not my favorite solution.  I guess the option may be more suitable in other cases, but not in mine.</p>
<p><strong>Solution 2 (my favorite):</strong></p>
<p>After messing around with the CMD.exe and windows shortcut properties, I finally found a much easier way to do what I needed to do.  Windows shortcuts have an option for &#8220;Start in&#8221; location which sets the start-up directory of CMD when it is executed.  So, all I needed to do was to create a shortcut on my desktop to CMD.exe, and set its &#8220;Start in&#8221; location to &#8220;C:\Program Files\ProgramName\Version\bin&#8221;. (See the screen shot below)</p>
<p><img class="aligncenter size-full wp-image-991" title="CMD Shortcut Properties" src="http://blog.pearltechnology.com/wp-content/uploads/2011/02/CMD-Shortcut.JPG" alt="CMD Shortcut Properties" width="386" height="533" /></p>
<p>Now, when I launch the shortcut, it starts a regular CMD window and sets the current directory to the right directory (which is &#8220;C:\Program Files\ProgramName\Version\bin&#8221; in my case).  Easy enough?</p>
<p><img class="aligncenter size-full wp-image-992" title="CMD" src="http://blog.pearltechnology.com/wp-content/uploads/2011/02/CMD.JPG" alt="CMD" width="571" height="288" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/how-to-start-command-prompt-at-a-designated-directory/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile App for Feature Phones</title>
		<link>http://blog.pearltechnology.com/mobile-app-for-feature-phones/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/mobile-app-for-feature-phones/#comments</comments>
		<pubDate>Mon, 14 Feb 2011 15:32:43 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Feature Phones]]></category>
		<category><![CDATA[Mobile Applications]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=954</guid>
		<description><![CDATA[When talking about mobile applications, most people would assume that they are only for Smartphones.  I had the false impression too (or I have never questioned myself for that) until I encountered a practical case at work recently.
The requirement was to allow users to submit some information (mostly in a text format) from their [...]]]></description>
			<content:encoded><![CDATA[<p>When talking about mobile applications, most people would assume that they are only for Smartphones.  I had the false impression too (or I have never questioned myself for that) until I encountered a practical case at work recently.</p>
<p>The requirement was to allow users to submit some information (mostly in a text format) from their mobile devices to a central data repository for analysis and processing.  For data collection, of course, we can build a mobile web application for users who have phones with web browsing capability, or develop a mobile application for Smartphone users to submit the information.  However, what about users who only have a regular cell phone which does not have a web browser or internet access at all?  Actually, many people are still using “Dumbphones” despite the rapid growth in the Smartphone market.  So, we cannot ignore them yet.</p>
<p>So, how can we collect the data from a regular cell phone?  Well, since the information that needs to be submitted will be in a text format, can we use SMS (Short Message Services) which is supported by most modern cell phones?  Yeah, it would work perfectly as long as users can manually type the data in a text message in INI, CSV or XML format.  Well, how hard is that?  You have comma, equal sign, angled brackets and all other characters on your cell phone keyboard…  For this question, I would have to say that “human” would never do that!  Even if they were forced to do it under the pressure from their boss, the data would always be problematic and tricky to handle.  By the way, our primary users are kids from middle and high schools.  Wait, can’t we start Computer Programming 101 from 5th grade?  No, we cannot force students to do that.</p>
<p>So, what if we develop a mobile application which gives users a nice interface to construct the data and submit it through SMS on their regular cell phones?  Think about your old phones that you have abandoned for years – didn’t they have apps for calendar, alert, calculator, games and etc.  They are just apps that manufactures preloaded on your cell phones.  If they can do it, why can’t we?  Yeah&#8230;? But how?</p>
<p>So, I started googling and came across a company called Tricastmedia who developed TWUIK SDK for mobile app development on a wide range of regular cell phone platforms.  The TWUIK SDK would allow you to develop applications targeting non-smartphones. If this works, I can have my cell phone users covered.  However, I had no previous experience with their products, so can’t provide more information here at this moment, but  I am very interested in looking into this and will come back on this in my later posts. Ever done anything like this?</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/mobile-app-for-feature-phones/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Supporting personal smartphones for work?</title>
		<link>http://blog.pearltechnology.com/supporting-personal-smartphones-for-work/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/supporting-personal-smartphones-for-work/#comments</comments>
		<pubDate>Tue, 09 Nov 2010 17:25:21 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[Mobile Applications]]></category>
		<category><![CDATA[Mobile Platform]]></category>
		<category><![CDATA[Smartphone]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=875</guid>
		<description><![CDATA[Smartphones are getting smarter now. They have gone far beyond of just making phone calls or texting messages, and they are no longer limited to handling simple tasks such as Emailing, scheduling, or browsing the internet. They may allow you to deposit a check to your bank in seconds, to take over the control of your house security system, to [...]]]></description>
			<content:encoded><![CDATA[<p>Smartphones are getting smarter now. They have gone far beyond of just making phone calls or texting messages, and they are no longer limited to handling simple tasks such as Emailing, scheduling, or browsing the internet. They may allow you to deposit a check to your bank in seconds, to take over the control of your house security system, to sync files with your desktop remotely, to find you the best-rated restaurants around you and direct you there turn by turn, and to do a lot more. With the hardware and operating systems getting more powerful, the network getting faster and more reliable, and mobile applications getting more creative and useful, a smartphone is becoming such a small device that can serve so many of our needs in both business and personal aspects. It may soon become a part of your life as do computers to us.</p>
<p>More and more companies and individuals have seen the trend and like to take the advantage of it. It happened in a client company of mine too. The company’s IT team has been using BlackBerry’s for their needs at work, and now more people within the company start seeing the value of having a smartphone to support their daily work. So, a debate, that whether use of personal smartphones for work should be allowed and supported, was started. People were naturally divided into three groups based on their opinions:</p>
<ol>
<li>Yes, use of personal phones for work should be allowed and supported – for people who already have a smartphone other than BlackBerry (such as Android or iPhone) and who do not like (if not hate) BlackBerry’s.</li>
<li>No, we should only use company provided BlackBerry’s for work and other mobile device platforms should not be supported – for people who have a BlackBerry already and are OK with it so far.</li>
<li>Don’t care – for people who do not have a smartphone and are not planning to have one.</li>
</ol>
<p>We will ignore the third group for now, because their opinions won’t affect the result of the debate any way. (If you don’t vote, you don’t matter.) So, let’s take a closer look at the other two opinions.</p>
<p>For the 1st opinion, the benefits are:</p>
<ul>
<li>People finally get to use something they like at work – whether it’s Droid 2, iPhone 4, BlackBerry Storm, or Windows Phone 7 which just came out recently.</li>
<li>Only one phone is needed for both work and personal use. You don’t have to hang two phones on your belt (like a cowboy carrying two handguns in the old western movies) which many people hate to do. With two phones in your hands, you would have no third hand to do anything else.</li>
<li>Less restrictions on the apps you can get on your “work/personal” phone. Games, music, videos, Facebook – let’s get them all.</li>
<li>Might cost less on the phone and the plan. Again, one phone with one wireless plan would probably cost less comparing to having two phones with a different plan on each one. The actual cost on supporting personal phones at work may be much higher than it appears to be though.</li>
<li>All other benefits, if there are any, fall into this category.</li>
</ul>
<p>On the other side, the short comings for the 1st opinion are:</p>
<ul>
<li>Hard for IT team to support. (They all have BlackBerry&#8217;s, and now you want an iPhone&#8230; so don&#8217;t let them hate you.) Each smartphone platform works in different ways and even the same platform may have major differences between different versions. Imagine what would happen, if the company was going to allow personal laptops to be used for work. The company would probably need to establish two more IT departments, one for Mac and one for Linux, and plus the current one for Windows. The company’s IT team would be going crazy to deal with all sorts of hardware and software issues. The same for supporting personal smartphones – it would make those phones hard to support and impossible to control.</li>
<li>Security. Many mobile apps may allow smartphones to get access to company’s internal network. Whoever has access to the phone or whichever program installed on the phone may potentially be able to hack into the company’s network. Agreed that a company provided phone has the same kind of risks, but it is more likely that a “work/personal” phone would be accessible by more people and loaded with more miscellaneous mobile applications. In my opinion, smartphone and its OS are still at their baby age. Just like computers in 90’s, the security breaches might be seen very often on smartphones for years. With that concern, company would probably better take a more restrictive control on smartphone usage at work.</li>
<li>Cost of purchasing and/or developing mobile apps. It would cost much less and require much less development work for supporting a business mobile application on one platform. Because mobile platforms are so different, the same program on one platform usually won’t be able to run on the other. To support multiple platforms, different versions of application might have to be purchased or developed, and the cost would easily be doubled or tripled.</li>
<li>Responsibilities and accountabilities. Who would be accountable for damages on a “work/personal” phone, and who would be responsible for fixing or replacing it? Employees might complain that the business apps on their phone took too many resources and drained out the battery too quickly, and employers might start thinking how many percent employees would be using the phone for business purpose and how much reimbursement should be given back to each employee for a “work/personal” phone. Does the company has the right to examine these phones for their usage or track employees location with GPS enabled phones? Things like these would just come up whether you want them or not.</li>
<li>You may never be able to get away from your work. Because it&#8217;s the only cell phone you have, you would probably carry it with you all the time. Then you would see work-related messages and Emails popping up on your phone at night, during weekends, on your vacations, and even on the holidays. When the phone beeps, you can’t ignore it, because you would never know whether it’s from your boss at work or your “boss” at home. (You can’t ignore any of them, can you?) There would always be something in the back of your head thinking about it, if you did put it aside without looking at it. However, once you pick it up, you may text or Email with someone on the phone a few times, or remote in your office to do a couple things real quick. Then a few minutes have passed, and your wife and kids are staring at you. You can’t turn it off either, because it’s your personal phone too. You still need it in your personal life. The same would happen at work. The phone will just keep distracting you from your regular work for personal stuff. </li>
</ul>
<p>It’s pretty obvious that I’m with the ones supporting the 2nd opinion, and I don’t think it’s necessary to even start talking about the pros and cons of it, unless I want to drive people away from this post due to the length of it. So, be that cowboy hero with two pistols in hands shooting the bad guys – why not! (Especially during the Halloween season)</p>
<p>One more thing I do want to be clear is that I&#8217;m not saying that BlackBerry is the only platform a company should choose. All smartphone platforms and phones are pretty powerful, and any of them may do the work just fine.  However, each manufacture has its own design philosophy and market strategy. It may require one or multiple posts to talk about each one of those and choose the right one for the company.</p>
<p>I’m sure you have your own ideas on this topic, so please don’t hesitate to post your comments below.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/supporting-personal-smartphones-for-work/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Set account dynamically during Windows Service installation</title>
		<link>http://blog.pearltechnology.com/set-account-dynamically-during-windows-service-installation/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/set-account-dynamically-during-windows-service-installation/#comments</comments>
		<pubDate>Mon, 01 Nov 2010 13:12:21 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Account]]></category>
		<category><![CDATA[Installer]]></category>
		<category><![CDATA[Setup Project]]></category>
		<category><![CDATA[visual studio 2008]]></category>
		<category><![CDATA[Windows Service]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=846</guid>
		<description><![CDATA[In this article, it talks about how to set Windows Service account dynamically during installation using Visual Studio 2008 Setup Project.]]></description>
			<content:encoded><![CDATA[<p>In a recent project, we needed to build a setup project for a Windows service using Visual Studio 2008.  The setup project would generate the installer (*.msi and setup.exe) for us to install the Windows service on its designated server.  One particular thing we wanted to do during the installation was to choose the right account to run the service depending on where the service is being installed (development, test or production server).  We wanted to do this, so the person who installs the service doesn’t have to know the username and the password of the account running the service.  The account will be set automatically in the back scene during the installation.</p>
<p>To achieve this, we added an entry in the appSettings section in the machine.config file on all the servers where the service may be installed.  It will be used by the installer (and/or all other .NET applications) to identify the environment (development, test or production).  The entry for development server is like the following:</p>
<div style="border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt">
<div style="background: #ddd;overflow: auto">
<ol style="background: #ffffff;margin: 0 0 0 2em;padding: 0 0 0 5px">
<li><span style="color:#0000ff">&lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">Environment</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">Development</span>&#8220;<span style="color:#0000ff">/&gt;</span></li>
</ol>
</div>
</div>
<p>Then we added all the account settings in the appSettings section of the app.config of the Windows service project so that the installer can retrieve the account user name and password during the installation.  (The appSettings section should be encrypted before the installer is packed.  The steps for encryption are omitted in this post.)  These settings may be similar to the following:</p>
<div style="border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt">
<div style="background: #ddd;overflow: auto">
<ol style="background: #ffffff;margin: 0 0 0 2em;padding: 0 0 0 5px">
<li><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">UserNameDevelopment</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">***</span>&#8220;<span style="color:#0000ff"> /&gt;</span></li>
<li><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">UserNameTest</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">***</span>&#8220;<span style="color:#0000ff"> /&gt;</span></li>
<li><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">UserNameProduction</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">***</span>&#8220;<span style="color:#0000ff"> /&gt;</span></li>
<li><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">UserPasswordDevelopment</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;***&#8221;<span style="color:#0000ff"> /&gt;</span></li>
<li><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">UserPasswordTest</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">***</span>&#8220;<span style="color:#0000ff"> /&gt;</span></li>
<li><span style="color:#0000ff">    &lt;</span><span style="color:#a31515">add</span><span style="color:#0000ff"> </span><span style="color:#ff0000">key</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">UserPasswordProduction</span>&#8220;<span style="color:#0000ff"> </span><span style="color:#ff0000">value</span><span style="color:#0000ff">=</span>&#8220;<span style="color:#0000ff">***</span>&#8220;<span style="color:#0000ff"> /&gt;</span></li>
</ol>
</div>
</div>
<p>In our installer class, we tried to retrieve the account settings using the following lines of code:</p>
<div style="border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt">
<div style="background: #ddd;overflow: auto;color:#000000">
<ol style="background: #ffffff;margin: 0 0 0 2em;padding: 0 0 0 5px">
<li>        Configuration.ConfigurationManager.AppSettings( _</li>
<li>            <span style="color:#0000ff">String</span>.Concat( _</li>
<li>                <span style="color:#a31515">&#8220;UserName&#8221;</span>, _</li>
<li>                Configuration.ConfigurationManager.AppSettings(<span style="color:#a31515">&#8220;Environment&#8221;</span>)))</li>
</ol>
</div>
</div>
<p>However, when this line was executed during the installation, it kept returning nothing (or null in C#).  After debugging, we found that the Environment setting was returned correctly, but the username was not.  The problem here was that the installer wasn’t reading the app.config (or the *.exe.config) from the Windows service project.  The actual application runs the installer is msiexec.exe which only loads the config file in the directory where the installer is run.  It also loads machine.config and other config files in the CONFIG folder under Microsoft.NET Framework directory.  The config file for the Windows Service is copied to the installation directory (or the TARGETDIR), so it won’t be loaded by the installer by default when we use ConfigurationManager.  That explains why we couldn’t find the account settings during installation.</p>
<p>To address this problem, we should load the config file for the Windows Service manually in the installer.  Here is how it is done in code:</p>
<div style="border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt">
<div style="background: #ddd;overflow: auto">
<ol style="background: #ffffff;margin: 0 0 0 2em;padding: 0 0 0 5px">
<li>        <span style="color:#0000ff">Dim</span> config <span style="color:#0000ff">As</span> Configuration.Configuration = _</li>
<li>            Configuration.ConfigurationManager.OpenExeConfiguration( _</li>
<li>                IO.Path.Combine( _</li>
<li>                    <span style="color:#0000ff">Me</span>.Context.Parameters(<span style="color:#a31515">&#8220;TARGETDIR&#8221;</span>), _</li>
<li>                    <span style="color:#a31515">&#8220;[WindowsServicePrimaryOutputFileName].exe&#8221;</span>))</li>
</ol>
</div>
</div>
<p>The TARGETDIR is the parameter stored in the installer context.  There are plenty of on-line posts talking about how to set and retrieve it.  Here is one on MSDN:</p>
<p><a href="http://msdn.microsoft.com/en-us/library/2w2fhwzz%28v=VS.90%29.aspx">http://msdn.microsoft.com/en-us/library/2w2fhwzz%28v=VS.90%29.aspx</a></p>
<p>One more note here is that you will have to set CustomActionData for each CustomActions where the TARGETDIR will be retrieved.</p>
<p>Then we can retrieve the account settings by the following code:</p>
<div style="border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt">
<div style="background: #ddd;overflow: auto">
<ol style="background: #ffffff;margin: 0 0 0 2em;padding: 0 0 0 5px">
<li>        config.AppSettings.Settings( _</li>
<li>            <span style="color:#0000ff">String</span>.Concat( _</li>
<li>                <span style="color:#a31515">&#8220;UserName&#8221;</span>, _</li>
<li>                Configuration.ConfigurationManager.AppSettings(<span style="color:#a31515">&#8220;Environment&#8221;</span>))).Value()</li>
</ol>
</div>
</div>
<p>Finally, we set the service username and password by overriding the OnBeforeInstall event on the installer class.  The username and password must be set before the installation starts, otherwise, during installation, the installer would think the user name and password are missing and will prompt you asking for the account credential which will be used to run the Windows Service.  See the completed code below.  (To make the program more efficient, you may want to refactor the code a little bit, so the config file is loaded only once, but it’s not the main focus in this article.)</p>
<div style="border: #000080 1px solid;color: #000;font-family: 'Courier New', Courier, Monospace;font-size: 10pt">
<div style="background: #ddd;overflow: auto">
<ol style="background: #ffffff;margin: 0 0 0 2.5em;padding: 0 0 0 5px">
<li>    <span style="color:#0000ff">Protected</span> <span style="color:#0000ff">Overrides</span> <span style="color:#0000ff">Sub</span> OnBeforeInstall( _</li>
<li>        <span style="color:#0000ff">ByVal</span> savedState <span style="color:#0000ff">As</span> System.Collections.IDictionary)</li>
<li> </li>
<li>        <span style="color:#0000ff">MyBase</span>.OnBeforeInstall(savedState)</li>
<li> </li>
<li>        <span style="color:#0000ff">Me</span>.MyProcessInstaller.Username = <span style="color:#0000ff">Me</span>.GetUserName()</li>
<li>        <span style="color:#0000ff">Me</span>.MyProcessInstaller.Password = <span style="color:#0000ff">Me</span>.GetPassword()</li>
<li> </li>
<li>    <span style="color:#0000ff">End</span> <span style="color:#0000ff">Sub</span></li>
<li> </li>
<li>    <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Function</span> GetUserName() <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span></li>
<li>        <span style="color:#0000ff">Dim</span> config <span style="color:#0000ff">As</span> Configuration.Configuration = _</li>
<li>                Configuration.ConfigurationManager.OpenExeConfiguration( _</li>
<li>                    IO.Path.Combine( _</li>
<li>                        <span style="color:#0000ff">Me</span>.Context.Parameters(<span style="color:#a31515">&#8220;TARGETDIR&#8221;</span>), _</li>
<li>                        <span style="color:#a31515">&#8220;[WindowsServicePrimaryOutputFileName].exe&#8221;</span>))</li>
<li>        <span style="color:#0000ff">Return</span> config.AppSettings.Settings( _</li>
<li>            <span style="color:#0000ff">String</span>.Concat( _</li>
<li>                <span style="color:#a31515">&#8220;UserName&#8221;</span>, _</li>
<li>                Configuration.ConfigurationManager.AppSettings(<span style="color:#a31515">&#8220;Environment&#8221;</span>))).Value</li>
<li> </li>
<li>    <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span></li>
<li> </li>
<li>    <span style="color:#0000ff">Private</span> <span style="color:#0000ff">Function</span> GetPassword() <span style="color:#0000ff">As</span> <span style="color:#0000ff">String</span></li>
<li>        <span style="color:#0000ff">Dim</span> config <span style="color:#0000ff">As</span> Configuration.Configuration = _</li>
<li>                Configuration.ConfigurationManager.OpenExeConfiguration( _</li>
<li>                    IO.Path.Combine( _</li>
<li>                        <span style="color:#0000ff">Me</span>.Context.Parameters(<span style="color:#a31515">&#8220;TARGETDIR&#8221;</span>), _</li>
<li>                        <span style="color:#a31515">&#8220;[WindowsServicePrimaryOutputFileName].exe&#8221;</span>))</li>
<li>        <span style="color:#0000ff">Return</span> config.AppSettings.Settings( _</li>
<li>            <span style="color:#0000ff">String</span>.Concat( _</li>
<li>                <span style="color:#a31515">&#8220;UserPassword&#8221;</span>, _</li>
<li>                Configuration.ConfigurationManager.AppSettings(<span style="color:#a31515">&#8220;Environment&#8221;</span>))).Value</li>
<li> </li>
<li>    <span style="color:#0000ff">End</span> <span style="color:#0000ff">Function</span></li>
</ol>
</div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/set-account-dynamically-during-windows-service-installation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Enterprise Library Logger.Write Not Working?</title>
		<link>http://blog.pearltechnology.com/enterprise-library-logger-write-not-working/#utm_source=feed&amp;utm_medium=feed&amp;utm_campaign=feed</link>
		<comments>http://blog.pearltechnology.com/enterprise-library-logger-write-not-working/#comments</comments>
		<pubDate>Mon, 17 May 2010 21:29:50 +0000</pubDate>
		<dc:creator>Geer</dc:creator>
				<category><![CDATA[Application Development]]></category>
		<category><![CDATA[Microsoft]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Enterprise Library]]></category>
		<category><![CDATA[Logger]]></category>

		<guid isPermaLink="false">http://blog.pearltechnology.com/?p=697</guid>
		<description><![CDATA[Using Logging Application Block provided by Enterprise Library is a common way of logging exceptions in .NET applications.  It&#8217;s easy to setup and to use.  One problem I had a while ago was that it worked while on my development PC, but stopped working once it&#8217;s deployed.
What I was doing was to use it to [...]]]></description>
			<content:encoded><![CDATA[<p>Using Logging Application Block provided by Enterprise Library is a common way of logging exceptions in .NET applications.  It&#8217;s easy to setup and to use.  One problem I had a while ago was that it worked while on my development PC, but stopped working once it&#8217;s deployed.</p>
<p>What I was doing was to use it to write event entries in windows event log as part of the exception handling in an ASP.NET web application.  Nothing fancy.  It worked fine on my PC, but it didn&#8217;t write anything to the event log when Logger.Write is executed. No exception was thrown from that line of code either.  The program just went through as if that line of code was skipped.</p>
<p>It turned out to be a permission issue. When I debug the application in Visual Studio, it was running under my windows account credential which had permission to create Event Source in the system.  However, when the application was deployed to the server, it was running under the default account which was &#8220;NT Authority\Network Service&#8221; in my case.  By default, that account doesn&#8217;t have permission to create new Event Source in the system.  It does have permission to write event entries though.  So, when Logger.Write was executed, it couldn&#8217;t proceed because the Event Source wasn&#8217;t there, and the program didn&#8217;t have permission to create one.  Actually, it makes sense to not throw any exception on this line, because people like me usually use this to log exceptions, and if the logging process itself throws exceptions, there is probably nowhere else we can handle and/or log them.</p>
<p>Now, how this can be resolve?  The solution is quite simple.  As long as the Event Source is created ahead of time, it will be no problem.  What I did was to create required Event Source(s) on server through CMD.exe.  Here is a sample command:</p>
<p><span style="color: #0000ff"><code>eventcreate /ID 1 /L Application /T information /SO "My Event Source" /D "My Event Source is created."</code></span></p>
<p>This command will create an event entry in the Application log.  If the Event Source doesn&#8217;t exist, it will be created during the process.  This is only required when the application is deployed to the server first time.  So, I usually do it manually on server.  However, if that&#8217;s not the case, you can build it into the installation package, and when the application is installed, the Event Source is created as well.  Of course, you can use .NET to create Event Source in your installer too.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.pearltechnology.com/enterprise-library-logger-write-not-working/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

