Search This Blog

Thursday, December 24, 2009

The Cure - Tegan and Sara



Lyrics | Tegan and Sara Lyrics | The Cure Lyrics

Changing Table Layout panel control dynamically at runtime

Change Column span and Row Span for a control in a tablelayoutpanel at runtime...
TableLayoutPanel1.SetRowSpan(TextBox1, 2)
TableLayoutPanel1.SetColumnSpan(TextBox1, 2)
Change Column and row position of a control in a tablelayoutpanel at runtime...
TableLayoutPanel1.SetRow(TextBox1, 2)
TableLayoutPanel1.SetColumn(TextBox1, 2)

Monday, October 26, 2009

Show Stats and Execute plan in query window

The results of these commands are displayed after a query is executed from Query Analyzer, generally after the results of the query are displayed. They include:
  • SET SHOWPLAN_TEXT ON: Returns estimated (not actual, as the query is not run) detailed information on how the query will run.
  • SET SHOWPLAN_ALL ON: Returns estimated (not actual, as the query is not run) detailed information on how the query will run, plus additional information, such as the estimated number of rows, I/O, CPU, and the average size of a the query.
  • SET STATISTICS IO ON: Shows the number of scans, logical reads, and physical reads performed during the query. Returns actual data based on a query that has run.
  • SET STATISTICS TIME ON: Shows the amount of time (in milliseconds) needed to parse, compile, and execute a query. Returns actual data based on a query that has run.
  • SET STATISTICS PROFILE ON: Shows a recordset that represents a profile of the query execution. Returns actual data based on a query that has run.
You will not want to run the first two commands listed above at the same time as the others because the first two commands are based on estimated data, while the last three are based on real data.
If you are using SQL Server 2000, using these commands are less needed as you can get all of the same type of data other ways from within Query Analyzer.

Tuesday, October 6, 2009

Deserialization Problem solved!

I have been working on COM interop project to allow access to Google Blogger and Picasa API from a Visual Basic 6.0 App. I know I know, why let go of the past and write a modern app perhaps in WPF..., I have my reasons.

Blogger Solution
COM Interop Project
Google API Project
Test UI Project

VB6 Project
Referencing COM Interop type Library

My solution is written in C#, 2.0 Framework (trying to still support Windows 2000, again I know I know let go of the past...) Added a Test windform project to the solution so I can run UI tests without COM. Worked great!

Created my COM interop project, something I had not done before. It seemed to work fine.

Then I decided I needed to serialize objects to cache downloaded album and images to spend up locating an online image. Worked well in C# except, when deserializing objects kept throwing errors when run from COM from my VB6 project. Two errors, Unable to find file (Assembly DLL) and unable to load type. Puzzled, I googled for a solution, WOW what a fine mess binary deserialization can be!

After several failed attempts, I found the solution:
1) Could not run my VB6 project and get the deserialization to work. Compiled the exe and...
2) Created an App.Config and renamed after my VB6 project exe: MyProject.exe.Config
3) In the App.Config, In the runtime section, I added for each of assemblies.

Now I can run my COM Interop project from VB6 and deserialization does not throw errors. At some point I am going to try to actually understand why this works but right now my goal is simply a working pattern that I can successfully produce.

Key my solution came when I enabled Fusion logging so I could see why was happening as my code loaded or tried to load assemblies needed for deserialization.

How to use App.Config with COM interop

From Beth Massi's blog:

Using My.Settings and WCF Configuration with the Interop Forms Toolkit

Setting Up Fusion Logging for .net

Need 2.0+ framework installed
In the Registry:
Add the following values to
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Fusion
Add:
DWORD ForceLog set value to 1
DWORD LogFailures set value to 1
DWORD LogResourceBinds set value to 1
String LogPath set value to folder for logs ie) C:\FusionLog\

Make sure you include the backslash after the folder name.

Invaluable logging to debug Assembly and type loading issues!

Saturday, October 3, 2009

Determine object type at runtime

from: http://en.csharp-online.net/CSharp_FAQ:_How_check_the_object_type_at_runtime
static bool isInteger (object o)

if (o is int || o is long)
{
return true;
}
else
{
return false;
}

Friday, October 2, 2009

View TOP 20 expense queries on SQL server


SELECT TOP 20 SUBSTRING(qt.text, (qs.statement_start_offset/2)+1,
((CASE qs.statement_end_offset
WHEN -1 THEN DATALENGTH(qt.text)
ELSE qs.statement_end_offset
END - qs.statement_start_offset)/2)+1),
qs.execution_count,
qs.total_logical_reads, qs.last_logical_reads,
qs.min_logical_reads, qs.max_logical_reads,
qs.total_elapsed_time, qs.last_elapsed_time,
qs.min_elapsed_time, qs.max_elapsed_time,
qs.last_execution_time,
qp.query_plan
FROM sys.dm_exec_query_stats qs
CROSS APPLY sys.dm_exec_sql_text(qs.sql_handle) qt
CROSS APPLY sys.dm_exec_query_plan(qs.plan_handle) qp
WHERE qt.encrypted=0
ORDER BY qs.total_logical_reads DESC

Optimizing Stored Procedures To Avoid Recompiles

Reposted from http://www.sqlservercentral.com/articles/Performance+Tuning/ospr/666/    

By Randy Dyess, 2002/02/26


One of the most overlooked areas in optimizing SQL Server and Transact-SQL is the recompilations of stored
procedures. Recently started looking at this issue where I worked and stored procedures gathered from other clients and
I noticed that there is an issue with SQL developers not taking recompiles into account when they create new code. When
a stored procedure recompiles it will place a compile lock on the objects referenced by the stored procedure and if there
are enough stored procedure recompiles the database may experience blocking. While all databases will experience stored
procedure recompiles as a normal matter of database operations, it is when a stored procedure recompiles with every run
that a database administrator or Transact-SQL developer needs to look out for and determine a remedy. A database getting
thousands of recompiles an hour will suffer in performance and show short term blocking that will affect the database
users. Will the query optimizer in SQL Server 2000 seems to have been greatly enhanced in its ability to reuse cached
procedure plans, a few of the following problems will still show up in SQL Server 2000.

Reasons stored procedures recompile
Stored procedures will normally recompile before execution for a number of reasons. Dropping and recreating the stored
procedure, using the WITH RECOMPILE clause in the CREATE PROCEDURE or the EXECUTE statement, change the schema of any
referenced objects, running the sp_recompile system stored procedure against a table referenced by the stored procedure,
restoring the database containing the stored procedure or any object referenced by the stored procedure, or the stored
procedures plan dropping from the cache. While these recompilations are normal and cannot be helped, DBAs and developers
should not assume that all stored procedure recompiles are for normal reasons and should take a proactive approach to
determine if they have a recompile problem.

Using Profiler to capture recompiles
With the use of SQL Profiler it is very easy for a DBA or developer to determine if a stored procedure abnormally
recompiles before it is ever put into a test or production environment. It is also very easy for production DBAs to
determine if they have a problem with stored procedures already in production.

To determine if you have a problem with existing stored procedures or a specific stored procedure:
1. Start Profiler
2. Start a new trace
3. Connect to your server
4. On the General Tab, give the trace a name
5. On the Events Tab remove all default events and add SP:Recompile, SP:Starting, and SP:Completed under Stored
Procedure events. If you want to determine the statement that causes the recompile also add SP:StmtStarting and
SP:StmtCompleted to the selection.
6. You can leave the data columns as is or change them as you see fit. You can also leave the trace without filters,
but stored procedures run by replication may tend to clutter your trace. If you tracing only one stored procedure,
you can filter by the stored procedure name under the Text-Like filter.

Example of a stored procedure which will recompile on every run (7.0 and 2000)
USE pubs
GO

IF OBJECT_ID('dbo.spShowRecompile') IS NOT NULL
DROP PROCEDURE dbo.spShowRecompile
GO

CREATE PROCEDURE dbo.spShowRecompile
AS
SET NOCOUNT ON

DECLARE @lngCounter INTEGER
SET @lngCounter = 1

--create temp table
CREATE TABLE #tTemp
(a INTEGER, b INTEGER)

SELECT count(*) FROM #tTemp

--add large amount of rows to table
WHILE @lngCounter < 2000
BEGIN
INSERT INTO #tTemp(a) VALUES(@lngCounter)
SET @lngCounter = @lngCounter + 1
END

--Create index on temp table
CREATE CLUSTERED INDEX ind_temp ON #tTemp(a)

SELECT count(*) FROM #tTemp
GO

EXEC dbo.spShowRecompile

Let the trace run and look for stored procedures that recompile multiple times in a row or that recompile after they have
started. To determine the statement causing the recompile look at the statement immediately before and after the recompile
if you included SP:StmtStarting and SP:StmtCompleted in your trace. Now that you have determined which stored procedures
are recompiling abnormally and which statements are causing the recompiles, we can look at ways to change the stored
procedure code to stop the recompiles.

Reducing COMPILE locks
It is considered a good practice to reference all objects in stored procedure code with the owner's name. While this will
not stop recompiles, it will stop SQL Server from placing a COMPILE lock on the procedure will it determines if all objects
referenced in the code have the same owners as the objects in the current cached procedure plan.

Example to show qualifying objects with their owners (7.0 and 2000)
USE pubs
GO

IF OBJECT_ID('dbo.spShowOwnersName') IS NOT NULL
DROP PROCEDURE dbo.spShowOwnersName
GO

CREATE PROCEDURE dbo.spShowOwnersName
AS
SELECT * FROM dbo.authors
GO

EXEC dbo.spShowOwnersName

Recompiles due to row modifications
Stored procedure will recompile is that a sufficient number of rows in a table referenced by the stored procedure has
changed. SQL Server will recompile the stored procedure to be sure that the execution plan has the up-to-date statistics
for the table. You will notice this problem quite often when you are working with temporary tables in SQL Server 7.0 as
SQL Server will determine that after 6 modifications to a temporary table any stored procedure referencing that table will
need to be recompiled.

Example of row modifications causing recompile (7.0)
IF OBJECT_ID('dbo.spShowRecompile') IS NOT NULL
DROP PROCEDURE dbo.spShowRecompile
GO

CREATE PROCEDURE dbo.spShowRecompile
AS
SET NOCOUNT ON

DECLARE @lngCounter INTEGER
SET @lngCounter = 1

CREATE TABLE #Temp
(
lngID INTEGER
)

WHILE @lngCounter < 2000
BEGIN
INSERT INTO #Temp VALUES(@lngCounter)

SET @lngCounter = @lngCounter + 1
END

SELECT COUNT(*) FROM #Temp
GO.

There are several ways to avoid this specific recompile. Luckily you have two paths to take: using sp_executesql and
using the KEEPFIXED PLAN query hint that is found in SQL Server 7.0 SP3 and SQL Server 2000. You can find information
in BOL on sp_executesql and in case you don't have SQL Server 7.0 SP3 or SQL Server 2000 here is what BOL says about
KEEPFIXED PLAN: "KEEPFIXED PLAN Forces the query optimizer not to recompile a query due to changes in statistics or to
the indexed column (update, delete, or insert). Specifying KEEPFIXED PLAN ensures that a query will be recompiled only if
the schema of the underlying tables is changed or sp_recompile is executed against those tables." Books Online article on
the OPTION clause. The following examples will show you the difference both sp_executesql and KEEPFIXED PLAN will have
on avoiding stored procedure recompiles.

Example of using sp_executesql to avoid recompiles from row modifications (7.0)
IF OBJECT_ID('dbo.spShowRecompile') IS NOT NULL
DROP PROCEDURE dbo.spShowRecompile
GO

CREATE PROCEDURE dbo.spShowRecompile
AS
SET NOCOUNT ON

DECLARE @lngCounter INTEGER
SET @lngCounter = 1

CREATE TABLE #Temp
(
lngID INTEGER
)

WHILE @lngCounter < 2000
BEGIN
INSERT INTO #Temp VALUES(@lngCounter)

SET @lngCounter = @lngCounter + 1
END

EXEC dbo.sp_executesql N'SELECT COUNT(*) FROM #Temp'

GO

Example of using KEEPFIXED PLAN option to avoid recompiles (7.0 SP3)
IF OBJECT_ID('dbo.spShowRecompile') IS NOT NULL
DROP PROCEDURE dbo.spShowRecompile
GO

CREATE PROCEDURE dbo.spShowRecompile
AS
SET NOCOUNT ON

DECLARE @lngCounter INTEGER
SET @lngCounter = 1

CREATE TABLE #Temp
(
lngID INTEGER
)

WHILE @lngCounter < 2000
BEGIN
INSERT INTO #Temp VALUES(@lngCounter)

SET @lngCounter = @lngCounter + 1
END

SELECT COUNT(*) FROM #Temp OPTION (KEEPFIXED PLAN)
GO

Recompiles due to interleaving DDL and DML operations
Stored procedures will recompile is that the developer has place interleaving Data Definition Language operations with Data
Manipulation Language operations. This is usually caused when temporary objects are created and referenced throughout the
code. The reason this happens is that the temporary objects due not exist when the initial compilation of the code takes
place so SQL Server will have to recompile the stored procedure during execution. This recompilation will take place after
the temporary object is referenced for the first time. By placing all of your temporary table creation statements together,
SQL Server can create plans for those temporary tables when one of them is referenced for the first time. This recompile
will still take place during the execution of the stored procedure, but you have cut down of the recompiles from n to two
(one for the stored procedure and one when the first reference to a temporary table is made). SQL Server will also be able
to reuse the execution plan for the stored procedure the next time the procedure is called and your recompiles will go to
zero. Remember that like permanent objects, if you change the schema of a temporary table, that change will cause the
stored procedure to recompile as well. Make all schema changes (such as index creation) right after your create table
statements and before you reference any of the temporary tables. If you take the stored procedure created during the
section on using Profiler and modify it as written below you will stop the unnecessary recompiles.

Modifications to stop the recompile (7.0 and 2000)
USE pubs
GO

IF OBJECT_ID('dbo.spShowRecompile') IS NOT NULL
DROP PROCEDURE dbo.spShowRecompile
GO

CREATE PROCEDURE dbo.spShowRecompile
AS
SET NOCOUNT ON

DECLARE @lngCounter INTEGER
SET @lngCounter = 1

--create temp table
CREATE TABLE #tTemp
(a INTEGER, b INTEGER)

--Create index on temp table
CREATE CLUSTERED INDEX ind_temp ON #tTemp(a)

SELECT count(*) FROM #tTemp

--add large amount of rows to table
WHILE @lngCounter < 2000
BEGIN
INSERT INTO #tTemp(a) VALUES(@lngCounter)
SET @lngCounter = @lngCounter + 1
END

SELECT count(*) FROM #tTemp
GO

EXEC dbo.spShowRecompile

Recompiles due to operations against temporary objects
SQL Server will recompile a stored procedure every time it is ran if any of the following conditions apply in that stored
procedure: If statements that contain the name of a temporary table refer to a table created by a calling or called stored
procedure or in a string execute by using sp_executesql or the EXECUTE statement. If any statement that contains the
name of the temporary table appear syntactically before the temporary table is created in the stored procedure or trigger.
If there are any DECLARE CURSOR statements whose SELECT statement references a temporary table. If any statements
that contain the name of a temporary table appear syntactically after a DROP TABLE against the temporary table (you
might read that DROP TABLES for temporary tables are not needed since they are dropped at the conclusion of the stored
procedure execute, but it is a good idea to drop temporary tables as you are done with them to free up system resources).
Or if any statement that creates a temporary table appear in a control-of-flow statement. By avoiding these conditions
when you create your code you can avoid needless stored procedure recompiles.

The following SET options are ON by default in SQL Server and changing the state of these options in your stored procedure
will cause the stored procedure to recompile: SET ANSI_DEFAULTS, SET ANSI_NULLS, SET ANSI_PADDING,
SET ANSI_WARNINGS, and SET CONCAT_NULL_YIELDS_NULL. While there are not good workarounds for the first four
SET options, you can work around the last one: SET CONCAT_NULL_YIELDS_NULL by using the ISNULL function found
in Transact-SQL. By simply using the ISNULL function and setting any data that might contain a NULL to an empty string
you can avoid the setting of CONCAT_NULL_YIELDS_NULL in your stored procedure and avoid another unnecessary
stored procedure recompilation.

Example of SET CONCAT_NULL_YIELDS_NULL causing recompile (7.0 and 2000)
USE pubs
GO

IF OBJECT_ID('dbo.spShowRecompile') IS NOT NULL
DROP PROCEDURE dbo.spShowRecompile
GO

CREATE PROCEDURE dbo.spShowRecompile
AS
SET NOCOUNT ON
SET CONCAT_NULL_YIELDS_NULL OFF
SELECT 'Will not showup' + NULL
GO

EXEC dbo.spShowRecompile

Summary
While most of these problems occur on a larger scale in SQL Server 7.0, they can still be a problem in SQL Server 2000.
By checking for stored procedure recompiles during the development of new Transact-SQL code and running a health-check
on your existing stored procedures for recompilations, you can help to optimize your database performance by lowering the
risk of blocking while a stored procedure is being recompiled and by improving the overall performance of your stored
procedures by not having them constantly being recompiled. Keeping the above recommendations in mind as you create
your code or optimize existing code will go a long way on creating that trouble-free, lightening-fast database that all of
us would love to manage.

Knowledge Based Articles
Q243586 INF: Troubleshooting Stored Procedure Recompilation
Q276220 INF: How to Use KEEPFIXED PLAN to Disable Stored Procedure Recompilations
Q294942 PRB: SET CONCAT_NULL_YIELDS_NULL May Cause Stored Procedures to Recompile
Q250506 FIX: Concurrent Execution of Stored Procedure That Recompiles May Fail To Execute All Statements
Q263889 INF: SQL Blocking Due to [[COMPILE]] Locks


Copyright 2002 by Randy Dyess, All rights Reserved

Why stored procedures recompile

Some articles how to minimize stored proc recompiles:

Identifying Stored Procedure Recompilation Problems in SQL Server 2000

Minimizing Stored Procedure Recompilation Problems in SQL Server 2000

Optimizing SQL Server Stored Procedures to Avoid Recompiles

Thursday, October 1, 2009

Numeric formats using string.format()

"
"



























































Numeric Format Specifiers
Specifier Description Example C#
c Currency; specify the number of decimal places  $12,345.00 string.Format("Currency: {0:c}", iNbr)
d Whole numbers; specifies the minimum number of digits - zeroes will be used to pad the result  12345 string.Format("Whole: {0:d}", iNbr)
e Scientific notation; specifies the number of decimal places  1.2345e+004 string.Format("Exponential: {0:e}", iNbr)
f Fixed-point; specifies the number of decimal places  12345.00 string.Format("Fixed: {0:f3}", iNbr)
n Fixed-point with comma separators; specifies the number of decimal places  12,345.00 string.Format("Fixed formatted: {0:n3}", iNbr)
p percentage; specifies the number of decimal places  1,234,500.00% string.Format("Percentage: {0:p2}", iNbr)
x Hexadecimal  3039 string.Format("Hexadecimal: {0:x}", iNbr)

Wednesday, September 30, 2009

List constrainsts on a table

SELECT  sc.constid ConstraintID,
so.name TableName,
CASE WHEN sc.colid = 0 THEN '' ELSE s.name END ColumnName,
CASE
WHEN sc.Status & 32 > 0 then 'Table-level'
WHEN sc.Status & 16 > 0 then 'Column-level'
WHEN sc.Status & 5 > 0 then 'DEFAULT'
WHEN sc.Status & 4 > 0 then 'CHECK'
WHEN sc.Status & 3 > 0 then 'FOREIGN KEY'
WHEN sc.Status & 2 > 0 then 'UNIQUE KEY'
WHEN sc.Status & 1 > 0 then 'PRIMARY KEY'
END + ' constraint'
FROM sysconstraints sc
INNER JOIN sysobjects so ON so.id = sc.id AND so.xtype = 'u'
LEFT JOIN syscolumns s ON s.colid = sc.colid AND so.id = s.id

Saturday, September 26, 2009

Fun with Deserialization

More fun serialization, this time with deserialization.

Currently working on a .net project whose feature set will allow my to replace some older third party libraries used in a VB6 project that do not work properly under Vista 64bit edition.

Things that I have successfully completed:
  • Replaced Microsoft IE6 era Web browser control with a .net webbrowser control in a winform.
  • Replaced functionality of Microsoft Internet transfer control to download online files.
  • Successfully extended Google Picasa API and Blogger API to VB6 through COM interop type library
  • Successfully implemented binary serialization of Picasa and Blogger caching the data locally.
DRCWinformUI.DLL - COM Interop assembly exposing methods/events for use in VB6 project
PicasaBloggerUserControls.DLL - .net 2.0 framework

Now to the problem: Deserialization:

Implemented code to de-serialize objects, which works fine in .net test app, but fails over COM:
SerializationException: Cannot find assembly...

Found the following articles:
Excellent article from http://spazzarama.wordpress.com/ describing the exact same problem:

C# – BinaryFormatter.Deserialize is “Unable to find assembly”


Documentation for SerializationBinder Class

I must give props to a co-worker Tom G. who pointed me in the correct direction of properly resolving the assembly by name. A problem that was solved at work on another project.

Sunday, September 20, 2009

Query for Blog posts by date


FeedQuery query = new FeedQuery();
query.Uri = new Uri("http://www.blogger.com/feeds/" + blogId + "/posts/default");
query.MinPublication = new DateTime(2006, 1, 1);
query.MaxPublication = new DateTime(2007, 4, 12);
AtomFeed feed = service.Query(query);
foreach (AtomEntry entry in feed.Entries)
{
Console.WriteLine(" Entry Title: " + entry.Title.Text);
}

Saturday, September 5, 2009

Creating ActiveX control using C#

Get the VSS.net templates from http://www.codeproject.com/KB/vb-interop/VB6InteropToolkit2.aspx

Copy the project template zip file into your project templates folder (the default location is ...\My Documents\Visual Studio 2005\Templates\ProjectTemplates\Visual C#) and the item template zip file into your item templates folder (...\My Documents\Visual Studio 2005\Templates\ItemTemplates\Visual C#).


A backup of the files on skydrive

Wednesday, September 2, 2009

Fun with Binary Serialization

Articles to read...
How to serialize an object which is NOT marked as 'Serializable' using a surrogate.
C# Tutorial - Serialize Objects to a File
Serialization in C#
Object Serialization using C#

Sample code - will serialize class with child classes that are not explicitly serializable. (Work in progress though).

SurrogateSelector ss = new SurrogateSelector();
PicasaAlbumAccessorSurrogate aass = new PicasaAlbumAccessorSurrogate();
PicasaEntrySurrogate pess = new PicasaEntrySurrogate();
PicasaFeedSurrogate pfss = new PicasaFeedSurrogate();

ss.AddSurrogate(typeof(AlbumAccessor),
new StreamingContext(StreamingContextStates.All), aass);
ss.AddSurrogate(typeof(PicasaEntry),
new StreamingContext(StreamingContextStates.All), pess);
ss.AddSurrogate(typeof(PicasaFeed),
new StreamingContext(StreamingContextStates.All), pfss);

BinaryFormatter formatter = new BinaryFormatter();
string filename = string.Format("{0}\\album_{1}_{2}_{3}.dat",
System.Environment.CurrentDirectory, _accessor.AlbumAuthor,
_accessor.Name, _accessor.Id);
FileStream fs = new FileStream(filename, FileMode.Create);
formatter.SurrogateSelector = ss;
formatter.Serialize(fs, this);
fs.Close();

Tuesday, September 1, 2009

Load bcp with Bulk Insert

This is impossible using Google:

BULK INSERT database.dbo.table
FROM 'full_path_name.bcp'
WITH (
DATAFILETYPE = 'native',
KEEPIDENTITY
)

Make sure Full path name is in single quotes.
http://msdn.microsoft.com/en-us/library/ms188365.aspx

Thursday, August 27, 2009

Friday, August 21, 2009

Tift Merritt - My Heart is free



Lyrics | Tift Merritt Lyrics | My Heart Is Free Lyrics

Learning more about Blogger and CSS

How to add a custom CSS to a blog's template.

Description of a Blogger Template

Added the following CSS style Sheet:


/*
Custom CSS class to display code snippets.
http://bguide.blogspot.com/
2008 Feb 03
*/
.mycode
{
border:1px dashed #aaaaaa;
background:#eeeeee;
white-space:pre;
font-family:monospace;
font-size:9pt;
line-height: 10pt;
height:auto;
width:auto;
padding:5px;
margin-left:10px;
overflow:auto;
}

To implement:
<div class="mycode">

/* Paste the code snippet here */

</div>

My code....

public static void UnregisterControl(Type t)
{
try
{
GuardNullType(t, "t");
GuardTypeIsControl(t);

//CLSID
string key = @"CLSID\" + t.GUID.ToString("B");
Registry.ClassesRoot.DeleteSubKeyTree(key);
}
catch (Exception ex)
{
LogAndRethrowException("ComUnregisterFunction failed.", t, ex);
}

}

Wednesday, August 12, 2009

Code to display Lego Model files

Source code to display MLCad / LeoCad model file using C#
Code posted by Chris Lomont.

Lomont's Lego CAD Viewer:
The program loads LDRAW files for viewing and deconstruction. Sourcecode and exe and a sample image file are included for your spastic enjoyment. See my Lego page for a the DAT file for the Technic kits 853 and 854 (pictured). Click the picture for a larger image.


Lego Screensaver (from Chris Lomont)
This is a screensave that assembles and disassembled many Lego models. Renaming the *.SCR to an EXE allows you to add your own LDRAW models to the mix.

Included is C# sourcecode and a VS 2008 project to compile the code.

Click the image to see a larger version of an assembled Technic set from the screensaver.



Requires LDraw.

Thursday, July 30, 2009

Drag and Drop Picturebox on FlowLayoutPanel

Here is code example of re-order picture boxes within a FlowLayoutPanel at runtime.

// add FlowLayoutPanel on a Winform - named flowLayoutPanel1
public partial class TestForm: Form
{
       public TestForm()
        {
            InitializeComponent();
            this.flowLayoutPanel1.AllowDrop = true
        }
        private void AddImageToBlog(System.Drawing.Image image)
        {
            PictureBox pbox = new PictureBox();
            pbox.SizeMode = PictureBoxSizeMode.Zoom;            
            pbox.Height = (_picturebox_height * _ScaleFactor);
            pbox.Width = (_picturebox_width * _ScaleFactor);
            pbox.Visible = true;
            pbox.Image = image;

            pbox.MouseDown += new MouseEventHandler(pbox_MouseDown);
            pbox.DragOver += new DragEventHandler(pbox_DragOver);            
            pbox.AllowDrop = true;
            flpNewBlog.Controls.Add(pbox);
        }
       void pbox_DragOver(object sender, DragEventArgs e)
        {
            base.OnDragOver(e);
            // is another dragable
            if (e.Data.GetData(typeof(PictureBox)) != null)
            {
                FlowLayoutPanel p = (FlowLayoutPanel)(sender as PictureBox).Parent;                 
                //Current Position             
                int myIndex = p.Controls.GetChildIndex((sender as PictureBox));

                //Dragged to control to location of next picturebox
                PictureBox q = (PictureBox) e.Data.GetData(typeof(PictureBox));                
                p.Controls.SetChildIndex(q, myIndex);
            }           
        }
        void pbox_MouseDown(object sender, MouseEventArgs e)
        {
            base.OnMouseDown(e);
            DoDragDrop(sender, DragDropEffects.All);
        }
         void pbox_DragEnter(object sender, DragEventArgs e)
        {
            e.Effect = DragDropEffects.Move;
        }


}

Wednesday, July 22, 2009

Tuesday, July 21, 2009

Clear SQL caches

From Devx.com

When tuning SQL Server applications, a certain degree of hands-on experimenting must occur. Index options, table design, and locking options are items that can be modified to increase performance. When running a test, be sure to have SQL Server start from the same state each time. The cache (sometimes referred to as the buffer) needs to be cleared out. This prevents the data and/or execution plans from being cached, thus corrupting the next test. To clear SQL Server’s cache, run DBCC DROPCLEANBUFFERS, which clears all data from the cache. Then run DBCC FREEPROCCACHE, which clears the stored procedure cache

DBCC FREEPROCCACHE
DBCC DROPCLEANBUFFERS

Saturday, July 18, 2009

C# code to register Assembly into Global Cache (GAC)

You can make use of System.EnterpriseServices assembly. Follow the following steps:

1) Add Reference >> System.EnterpriseServices
2) In case of C#:
using System.EnterpriseServices.Internal;

3) below in the code, for example on click of a button

Publish objPub=new Publish();

//to add the assembly - use full path with file name
objPub.GacInstall("AssamblyPath");

//to remove the assembly - use full path with the file name
objPub.GacRemove("AssemblyPath");

Moreove make sure, your assembly should be signed using:
sn.exe -k assemblyname //either it is .dll or .exe

Another Code Example:
using System.Text;
using System.Windows.Forms;
using System.EnterpriseServices.Internal;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
Publish p = new Publish();
p.GacInstall(@"c:\myassmebly.dll");
}
}
}


Other GAC related links:

- A proper way to install Assemblies to the GAC is documented by Microsoft here http://support.microsoft.com/kb/317540/en-us

- For NSIS and .net - Register a managed .NET DLL in the GAC

Friday, July 17, 2009

VB6 App with C# COM object

VB6 project using C# COM Assembly
-2147024896 (80070002) Automation error The System cannot find file specified

I get this very thing...

from MSDN forum

Question:
i'm having problems running the vb6 app, and the error occurs when i make the form show. i've followed the instructions from the help file and still the problem arises everytime.

here's another weird thing, when i added the interop form to an existing vb6 application, it was ok when run inside the ide. when i compiled this to an .exe file, the error happened. i also tried creating fresh vb6 app and it worked, so any ideas on this issue? thanks.


Answer:
1) Strongly name Assemblies.
   sn -k TestKeyPair.snk
2) Add TestKeyPair.snk to project(s).
3) Edit AssemblyInfo.cs
A) Make assembly is versioned
[assembly: AssemblyVersion("1.0.0.0")]
b) Add [assembly: AssemblyKeyFile("TestKeyPair.snk")]
4) Add Assembly to GAC
gacutil /i MyInterop.dll
- Make sure all Assembly DLLS has been
5) Regasm Assembly and expose COM use /codebase
REGASM MyInterop.dll /tlb:com.MyInterop.tlb /codebase
Better Answer:
1) Strongly name Assemblies.
   sn -k TestKeyPair.snk
2) Add TestKeyPair.snk to project(s).
3) Edit AssemblyInfo.cs
A) Make assembly is versioned
[assembly: AssemblyVersion("1.0.0.0")]
b) Add [assembly: AssemblyKeyFile("TestKeyPair.snk")]
4) Copied all related assemblies local to folder containing VB6 project
5) Run from this folder: tlbexp sampleDLL.dll /out:sampleDLL.tlb
6) run from this folder: regasm sampleDLL.dll /tlb:sampleDLL.tlb
7) Open VB6 project and reference to sampleDLL.tlb is local to project.

Proper Useage related Indexed Views

Hidden Gotcha with Indexed Views NoExpand vs Expand See microsoft article

The NOEXPAND view hint forces the query optimizer to treat the view like an ordinary table with a clustered index - basically I thought this was the main purpose for an indexed View...

Using the NOEXPAND view hint

When SQL Server processes queries that refer to views by name, the definitions of the views normally are expanded until they refer only to base tables. This process is called view expansion. It's a form of macro expansion.

The NOEXPAND view hint forces the query optimizer to treat the view like an ordinary table with a clustered index. It prevents view expansion. The NOEXPAND hint can only be applied if the indexed view is referenced directly in the FROM clause. For example,

SELECT Column1, Column2, ... FROM Table1, View1 WITH (NOEXPAND) WHERE ...

Use NOEXPAND if you want to be sure to have SQL Server process a query by reading the view itself instead of reading data from the base tables. If for some reason SQL Server chooses a query plan that processes the query against base tables when you'd prefer that it use the view, consider using NOEXPAND. You must use NOEXPAND in all versions of SQL Server other than Developer and Enterprise editions to have SQL Server process a query against an indexed view directly. You can see a graphical representation of the plan SQL Server chooses for a statement using the SQL Server Management Studio tool Display Estimated Execution Plan feature. Alternatively, you can see different non-graphical representations using SHOWPLAN_ALL, SHOWPLAN_TEXT, or SHOWPLAN_XML. See SQL Sever books online for a discussion of the different versions of SHOWPLAN.

Using the EXPAND VIEWS query hint

When processing a query that refers to a view by name, SQL Server always expands the views, unless you add the NOEXPAND hint to the view reference. It attempts to match indexed views to the expanded query, unless you specify the EXPAND VIEWS query hint in an OPTION clause at the end of the query. For example, suppose there is an indexed view View1 in the database. In the following query, View1 is expanded based on its logical definition (its CREATE VIEW statement), and then the EXPAND VIEWS option prevents the indexed view for View1 from being used in the plan to solve the query.

SELECT Column1, Column2, ... FROM Table1, View1 WHERE ...
OPTION (EXPAND VIEWS)
Use EXPAND VIEWS if you want to be sure to have SQL Server process a query by accessing data directly from the base tables referenced by the query, instead of possibly accessing indexed views. EXPAND views may in some cases help eliminate lock contention that could be experienced with an indexed view. Both NOEXPAND a

Saturday, July 11, 2009

Detect an Internet Connection

Simple Code to make sure there is an active internet connection.
 using System.Net.Sockets;

private bool ConnectionExists()
{
try
{
TcpClient clnt = new TcpClient("www.google.com", 80);
clnt.Close();
return true;
}
catch (System.Exception)
{
return false;
}
}

Friday, July 10, 2009

Create COM object using C# for VB6 Application

Here is a C# example: Create a COM object with events using C# and implement in a VB6 Application.

Step #1: Define COM interfaces
Need to create two interfaces - 1 class interface and a events interface

Public Class Interface: IMyClass
using System;
using System.Drawing;
using PicasaBloggerUserControls;
using System.Runtime.InteropServices;

namespace MyApp
{
[Guid("xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb")]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface
IMyClass
{
void GetDRCUpdate(string url, int majorVer, int minorVer, int RevisionVer, bool GetLatest);
}
}


Public Interface defining the events: IMyClassEvents

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace MyApp
{
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb")]
public interface
IMyClassEvents
{
void DownloadComplete();
void DownloadCancel(bool downloadfailed);
}
}
Step #2
Define Public class using class interface: winformUI

using System.Drawing;
using System.Windows.Forms;
using PicasaBloggerUserControls;
using System.Runtime.InteropServices;

namespace PicasaBloggerUI
{
[Guid(
"xxxxxxxx-yyyy-zzzz-aaaa-bbbbbbbbbbbb")]
[
ComSourceInterfaces("MyApp.PicasaBloggerEventsInterface"),
ClassInterface(ClassInterfaceType.None)
]
[ProgId("winformUI")]


public class winformUI :
IMyClass
{
public event FileDownloadDelegate DRCDownloadComplete;
public delegate void FileDownloadDelegate();

public event FileDownloadCancelDelegate DRCDownloadCancel;
public delegate void FileDownloadCancelDelegate(bool downloadfailed);

private frmDRCUpdate _DRCUpdater;

//ctor
public winformUI()
{
_DRCUpdater = new frmDRCUpdate();
_DRCUpdater.OnFileDownload += new frmDRCUpdate.FileDownloadDelegate(_DRCUpdater_OnFileDownload);
_DRCUpdater.OnFileDownloadCancel += new frmDRCUpdate.FileDownloadCancelDelegate(_DRCUpdater_OnFileDownloadCancel);
}

void _DRCUpdater_OnFileDownloadCancel()
{
if (null != DRCDownloadCancel)
{
DRCDownloadCancel(!_DRCUpdater.Successful);
}
}

void _DRCUpdater_OnFileDownload()
{
try
{
//MessageBox.Show("Download Successful");
DRCDownloadComplete();
}
catch
{
}

}

void IPicasaBlogger.GetDRCUpdate(string url, int majorVer, int minorVer, int RevisionVer, bool GetLatest)
{
_DRCUpdater = new frmDRCUpdate();
_DRCUpdater.OnFileDownload += new frmDRCUpdate.FileDownloadDelegate(_DRCUpdater_OnFileDownload);
_DRCUpdater.OnFileDownloadCancel += new frmDRCUpdate.FileDownloadCancelDelegate(_DRCUpdater_OnFileDownloadCancel);
_DRCUpdater.Show();
_DRCUpdater.GetDRCUpdate(url, majorVer, minorVer, RevisionVer, GetLatest);
}

}
}

Step #3 Compile C# code and register the assembly:
REGASM MyApp.dll /tlb:com.MyApp.tlb
Now you are ready to add the COM object as a reference to a VB project.
1) Open VB6 project, select references and browse to locate of MyApp.tlb and add as a reference.

In a VB6 form Module
Private WithEvents oMyAppUI As MyApp.winformUI

Private Sub Form_Load()
Set oMyAppUI = New MyApp.winformUI
End Sub

Private Sub oMyAppUI_DownloadCancel(ByVal downloadfailed As Boolean)
If downloadfailed Then
MsgBox "Update Failed, please try again. If the failure persists, contact me at Gary.Kindel@gmail.com for assistance.", vbOKOnly
Else
MsgBox "You have the current version, no updates are available.", vbExclamation
End If
End Sub
Private Sub oMyAppUI_DownloadComplete()
If MsgBox("Do you want to exit and install the update?", vbYesNoCancel, "Exit DRC and run Update file") = vbYes Then
mApplyUpdate = True
Unload Me
End If
End Sub





Monday, July 6, 2009

C# Download File with Progress Bar

From devtoolshed.com

C# Download File with Progress Bar

Need a Winform with
TextBox - hold URL
Button - Start Download
Progressbar -
BackGroundWorker - Perform the work

Add Using System.IO to module
Set BackGroundWorker to reportProgress=true

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace CodeExamples
{
public partial class frmDownload : Form
{
public frmDownload()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
string urlstring = this.txtURL.Text;
string filename = string.Format("{0}\\DRC_Update.exe",Environment.CurrentDirectory);

if (urlstring.Length > 0)
{
Uri url = new Uri(urlstring);
System.Net.HttpWebRequest request = (System.Net.HttpWebRequest)System.Net.WebRequest.Create(url);
System.Net.HttpWebResponse response = (System.Net.HttpWebResponse)request.GetResponse();
response.Close();

Int64 iSize = response.ContentLength;
Int64 iRunningByteTotal = 0;

using (System.Net.WebClient client = new System.Net.WebClient())
{
using (System.IO.Stream streamRemote = client.OpenRead(new Uri(urlstring)))
{
using (FileStream streamLocal = new FileStream(filename, FileMode.Create, FileAccess.Write, FileShare.None))
{
int iByteSize = 0;
byte[] byteBuffer = new byte[iSize];
while ((iByteSize = streamRemote.Read(byteBuffer, 0, byteBuffer.Length)) > 0)
{

// write the bytes to the file system at the file path specified
streamLocal.Write(byteBuffer, 0, iByteSize);
iRunningByteTotal += iByteSize;


// calculate the progress out of a base "100"
double dIndex = (double)(iRunningByteTotal);
double dTotal = (double)byteBuffer.Length;
double dProgressPercentage = (dIndex / dTotal);
int iProgressPercentage = (int)(dProgressPercentage * 100);


// update the progress bar
backgroundWorker1.ReportProgress(iProgressPercentage);
}
streamLocal.Close();
}
streamRemote.Close();
}

}

}
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("File download complete");
}
}
}

Tuesday, June 30, 2009

Supporting .Net with NSIS installer

Creating a .NET bootstrapped installer using NSIS - Article on boot strapping .net framework installer using NSIS.

Get .NET Version retrieves the latest version of the .NET runtime library installed on the user's computer

How to Automatically download and install a particular version of .NET if it is not already installed.

Annotating Images in C#

C# Snippet Tutorial - How to Draw Text on an Image

Example:

Bitmap myBitmap = new Bitmap("C:\\myImage.jpg");

Now that we have a Bitmap object we can get a Graphics object from it. The Graphics object will be doing all of our text drawing.

Bitmap myBitmap = new Bitmap("C:\\myImage.jpg");
Graphics g = Graphics.FromImage(myBitmap);

We can now use this Graphics object to perform all of our drawing. Let's start by simply placing some text in the upper left corner.

g.DrawString("My\nText", new Font("Tahoma", 40), Brushes.White, new PointF(0, 0));


My sample code:
PictureBox image = sender as PictureBox;
Graphics g = Graphics.FromImage(image.Image as Bitmap);
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
g.DrawString("1", new Font("Tahoma", 50), Brushes.Yellow, new PointF(0,0);



Tuesday, June 23, 2009

SkyDrive .Net API Client

CodePlex:SkyDrive .Net API Client

Project Description

SkyDrive .Net API Client allows developers to easily integrate Microsoft's Windows Live SkyDrive online storage and sharing services into their own applications. It's developed in C# using .Net 2.0.

What is this?

This project is an open source client for Windows Live SkyDrive written for the Microsoft .NET Framework. This is NOT an offical, Microsoft API (and to be honest, it's not a true API)! However, this library will greatly facilitate the development of 3rd party applications for developers already familiar with the Microsoft .NET technology stack.

How does it work?

At the time of this writing, as far as I know, there is no official API to use for SkyDrive. SkyDrive Client uses the same communication protocols as a web browser: it's requesting HTML pages, parsing them (thanks Html Agility Pack project) and posting back HTML forms filled appropriately. Consequently, SkyDrive WebClient heavily depends on the design of SkyDrive's HTML pages, even small design or structural changes could easily break partially or completely this library - please keep this in mind when you are about to use it in critical/billable projects!.

How to use it?

Check the samples delivered by the source code for examples.
Additionally, you can check related project Total Commander SkyDrive File System Plugin.

SkyDrive API

From Micrsoft's site:

These Community Technology (CTP) APIs have been deprecated. For the latest information on Live Service APIs, please see http://dev.live.com.

Community Technology Previews are designed to shape our technology by giving developers early access, allowing them to “kick the tires,” and provide us valuable feedback. CTP releases explicitly do not allow for use in production-style environments (see terms). This allows us to get our offering right before we have customers bet their businesses on us. We apologize for any inconvenience deprecating these specific CTP APIs has caused.

Saturday, June 13, 2009

Delete Orpaned Network Share

Found this link- Unmap Disconnected Network Drive

Under the key
[HKEY_CURRENT_USER\Software\Microsoft\Windows\Curre ntVersion\Explorer\MountPoints2]look for an entry like this ##SRV02#C which is the way \\SRV02\C is shown.Delete that key. Then log off and on again or reboot.

Friday, May 29, 2009

Attach to a running process

Attach to a Process

(Professional only)

Instead of having the profiler launch the process to profile, it is also possible to attach the profiler to an already running .NET Process.

In order to attach to a process, Debugging Tools for Windows must be installed on the computer. These tools can be downloaded from http://www.microsoft.com/whdc/devtools/debugging.

NOTE! On a 64-bit operating system, you will need to download the 32-bit debugging tools to attach to a 32-bit process and the 64-bit debugging tools to attach to a 64-bit process.

After the debugging tools have been installed, the following steps should be performed to attach the profiler to a running process:

1. Select the Attach to Process command from the File menu or Attach Profiler to Process from the Profiler menu if running under Visual Studio.

2. The “Attach to” wizard appears.

3. Select the process you want to attach to from the list of .NET processes.

4. If you want to profile using the default settings, click Start to start the application.

5. If you want to modify settings, you can use the Next button to modify some common settings.

6. When you have decided on the settings, click Start to attach to the process.

7. If Debugging Tools for Windows is not installed, the dialog below will appear, instructing you to install the debugging tools.

Friday, May 15, 2009

Script to Randomly create names and SSN

Script to Randomly create names and SSN from RIS database


DECLARE @Firstnames TABLE(ID int identity(1,1), Firstname varchar(12))
DECLARE @LastNames TABLE(ID int identity(1,1), LastName varchar(20))
DECLARE @FirstNameCount int
DECLARE @LastNameCount int
DECLARE @PatientCount int
DECLARE @PatientID int

DECLARE @FirstNameRandom INT
DECLARE @LastNameRandom INT

DECLARE @Upper INT
DECLARE @Lower INT

INSERT INTO @Firstnames (Firstname)
SELECT FirstName FROM tbPatients GROUP BY FirstName

SELECT @FirstNameCount= Count(*) FROM @Firstnames

INSERT INTO @LastNames (LastName)
SELECT LastName FROM tbPatients GROUP BY LastName

SELECT @LastNameCount= Count(*) FROM @LastNames

SELECT @PatientCount=COUNT(*) FROM tbPatients

SELECT @FirstNameCount, @LastNameCount,@PatientCount

UPDATE tbPatients SET SSN=null


DECLARE cursor_Patients CURSOR FOR
SELECT PatientID FROM tbPatients
OPEN cursor_Patients
FETCH NEXT FROM cursor_Patients INTO @PatientID
WHILE (@@FETCH_STATUS = 0)
BEGIN

SET @Lower=1
SET @Upper=@FirstNameCount
SELECT @FirstNameRandom = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

SET @Upper=@LastNameCount
SELECT @LastNameRandom = ROUND(((@Upper - @Lower -1) * RAND() + @Lower), 0)

UPDATE tbPatients
SET FirstName = (SELECT Firstname FROM @Firstnames WHERE ID=@FirstNameRandom),
LastName = (SELECT LastName FROM @LastNames WHERE ID=@LastNameRandom)
WHERE PatientID=@PatientID

UPDATE tbPatients
SET SSN = (SELECT CONVERT(varchar(9),CONVERT(int,ROUND(((999999999 - 110000000 -1) * RAND() + 110000000), 0))))
WHERE PatientID=@PatientID

FETCH NEXT FROM cursor_Patients INTO @PatientID
END
CLOSE cursor_Patients
DEALLOCATE cursor_Patients


SELECT FirstName, LastName, SSN FROM tbPatients

SQL Cursor example

Good cursor example here

DECLARE cursor_Patients CURSOR FOR
SELECT PatientID FROM tbPatients
OPEN cursor_Patients
FETCH NEXT FROM cursor_Patients INTO @PatientID
WHILE (@@FETCH_STATUS = 0)
BEGIN
SELECT @PatientID
FETCH NEXT FROM cursor_Patients INTO @PatientID
END
CLOSE cursor_Patients
DEALLOCATE cursor_Patients

Wednesday, May 6, 2009

ALTER DATABASE replaces sp_dbcmptlevel

ALTER DATABASE Compatibility Level (Transact-SQL)

Sets certain database behaviors to be compatible with the specified version of SQL Server. New in SQL Server 2008, the following ALTER DATABASE syntax replaces the sp_dbcmptlevel procedure for setting the database compatibility level. For other ALTER DATABASE options, see ALTER DATABASE (Transact-SQL).

ALTER DATABASE AdventureWorks
SET COMPATIBILITY_LEVEL = 100;
GO
vs
sp_dbcmptlevel AdventureWorks 100

Getting this error when trying to create an assembly from a DLL.

Determine current database compatibility level
DBCC CHECKDB

Checks the logical and physical integrity of all the objects in the specified database by performing the following operations:

  • Runs DBCC CHECKALLOC on the database.
  • Runs DBCC CHECKTABLE on every table and view in the database.
  • Runs DBCC CHECKCATALOG on the database.
  • Validates the contents of every indexed view in the database.
  • Validates link-level consistency between table metadata and file system directories and files when storing varbinary(max) data in the file system using FILESTREAM.
  • Validates the Service Broker data in the database.

This means that the DBCC CHECKALLOC, DBCC CHECKTABLE, or DBCC CHECKCATALOG commands do not have to be run separately from DBCC CHECKDB. For more detailed information about the checks that these commands perform, see the descriptions of these commands.

Friday, April 17, 2009

UI for SandCastle

Great Walk through using SandCastle on CodeProject

Several Important Steps:
1) Install SandCastle from MS.
2) Install this UI - UI for SandCastle
3) Add XMl document for output on each project
4) Add all reference DLL that would appear in the Bin\Debug folder of the solution.
5) Select htmlDoc1 for a CHM style distributable help format.
6) Run help generator.

Welcome to the Sandcastle Help File Builder

Sandcastle, created by Microsoft, is a tool used for creating MSDN-style documentation from .NET assemblies and their associated XML comments files. The current version is the May 2008 release. It is command line based and has no GUI front-end, project management features, or an automated build process like those that you can find in NDoc. The Sandcastle Help File Builder was created to fill in the gaps, provide the missing NDoc-like features that are used most often, and provide graphical and command line based tools to build a help file in an automated fashion.

Tip: See the Installation Instructions for information about the required set of additional tools that need to be installed, where to get them, and how to make sure everything is configured correctly.

Tip: If you are new to Sandcastle and the help file builder, see the topics in the Getting Started section to get familiar with it, set up your projects to produce XML comments, and create a help file project.

Microsoft's Documentation tool

It is a full-time job to keep up with everything I should be doing as a professional software engineer using .Net

Download details: Sandcastle - Version 2.4.10520

Jun 12, 2008 ... Enabling managed class library developers throughout the world to easily create accurate, informative documentation with a common look and ...

Wednesday, April 8, 2009

I love stackoverflow.com

Stackoverflow is a great source of answered tech problems but this is outright funny:

what-code-would-you-have-on-your-wedding-cake

Thursday, April 2, 2009

missing AxSHDocVw project reference

AxSHDocVw is a com wrapper for the unmanaged webBrowser.
To fix, I added ShDocVw.dll to the project and added the WebBrowser control to a form in the project.

This was needed for Project: DeliveryStatus in Merge.DeliveryService solution.
DeliveryStatus is a project not distributed as part of the DeliveryService.

Thursday, March 26, 2009

Convert classes to XML and back

From http://www.jonasjohn.de/snippets/csharp/xmlserializer-example.htm

// This is the test class we want to
// serialize:
[Serializable()]
public class TestClass
{
private string someString;
public string SomeString
{
get { return someString; }
set { someString = value; }
}

private List settings = new List();
public List Settings
{
get { return settings; }
set { settings = value; }
}

// These will be ignored
[NonSerialized()]
private int willBeIgnored1 = 1;
private int willBeIgnored2 = 1;

}

// Example code

// This example requires:
// using System.Xml.Serialization;
// using System.IO;

// Create a new instance of the test class
TestClass TestObj = new TestClass();

// Set some dummy values
TestObj.SomeString = "foo";

TestObj.Settings.Add("A");
TestObj.Settings.Add("B");
TestObj.Settings.Add("C");


#region Save the object

// Create a new XmlSerializer instance with the type of the test class
XmlSerializer SerializerObj = new XmlSerializer(typeof(TestClass));

// Create a new file stream to write the serialized object to a file
TextWriter WriteFileStream = new StreamWriter(@"C:\test.xml");
SerializerObj.Serialize(WriteFileStream, TestObj);

// Cleanup
WriteFileStream.Close();

#endregion


/*
The test.xml file will look like this:



foo

A
B
C


*/

#region Load the object

// Create a new file stream for reading the XML file
FileStream ReadFileStream = new FileStream(@"C:\test.xml", FileMode.Open, FileAccess.Read, FileShare.Read);

// Load the object saved above by using the Deserialize function
TestClass LoadedObj = (TestClass)SerializerObj.Deserialize(ReadFileStream);

// Cleanup
ReadFileStream.Close();

#endregion


// Test the new loaded object:
MessageBox.Show(LoadedObj.SomeString);

foreach (string Setting in LoadedObj.Settings)
MessageBox.Show(Setting);

locking a table on insert statement

INSERT INTO [table name] WITH (TABLOCK)
()
SELECT FROM [table name] WHERE

Show locks on database server

run sp_lock

Get Database ID and name

SELECT DB_ID() DatabaseID, DB_NAME() DatabaseNM

Thursday, March 19, 2009

A Fine Frenzy - Rangers

The song writer obviously liked the move Watership down...


Lyrics | A Fine Frenzy Lyrics | Rangers Lyrics

Amy MacDonald - This is the life



Lyrics | Amy McDonald Lyrics | This Is The Life Lyrics

Monday, March 16, 2009

Formatting Dates

Because MS online help is often too slow...

Without century (yy) (1) With century (yyyy) Standard Input/Output (3)

-

0 or 100 (1, 2)

Default

mon dd yyyy hh:miAM (or PM)

1

101

U.S.

mm/dd/yyyy

2

102

ANSI

yy.mm.dd

3

103

British/French

dd/mm/yyyy

4

104

German

dd.mm.yy

5

105

Italian

dd-mm-yy

6

106 (1)

-

dd mon yy

7

107 (1)

-

Mon dd, yy

8

108

-

hh:mi:ss

-

9 or 109 (1, 2)

Default + milliseconds

mon dd yyyy hh:mi:ss:mmmAM (or PM)

10

110

USA

mm-dd-yy

11

111

JAPAN

yy/mm/dd

12

112

ISO

yymmdd

yyyymmdd

-

13 or 113 (1, 2)

Europe default + milliseconds

dd mon yyyy hh:mi:ss:mmm(24h)

14

114

-

hh:mi:ss:mmm(24h)

-

20 or 120 (2)

ODBC canonical

yyyy-mm-dd hh:mi:ss(24h)

-

21 or 121 (2)

ODBC canonical (with milliseconds)

yyyy-mm-dd hh:mi:ss.mmm(24h)

-

126 (4)

ISO8601

yyyy-mm-ddThh:mi:ss.mmm (no spaces)

-

127(6, 7)

ISO8601 with time zone Z.

yyyy-mm-ddThh:mi:ss.mmmZ

(no spaces)

-

130 (1, 2)

Hijri (5)

dd mon yyyy hh:mi:ss:mmmAM

-

131 (2)

Hijri (5)

dd/mm/yy hh:mi:ss:mmmAM

1 These style values return nondeterministic results. Includes all (yy) (without century) styles and a subset of (yyyy) (with century) styles.

2 The default values (style 0 or 100, 9 or 109, 13 or 113, 20 or 120, and 21 or 121) always return the century (yyyy).

3 Input when you convert to datetime; output when you convert to character data.

4 Designed for XML use. For conversion from datetime or smalldatetime to character data, the output format is as described in the previous table.

5 Hijri is a calendar system with several variations. SQL Server uses the Kuwaiti algorithm.

Saturday, March 14, 2009

Tricks to extend primary Disk partiton

Just learned this trick from a friend at work.
Still learning Vista. Not sure why people do not like it. There is alot to like...
How To Mount and Access New Partition, Volume or Drive As Folder Path In Windows




When adding a new hard disk or create a new partition in Microsoft Windows operating system
, typically users will normally assign a drive letter such as Local Disk (E:) to the new partition or volume. Beside normal way of allocating a drive letter, it’s also possible to assign a folder or directory (on partitions formated as NTFS) to represent the hard disk drive, partition or volume too, eliminating eliminating the use of drive letter and enabling browsing the volume and partition contents as in folder, or path.Mounting a partition or drive as a folder also provides a workaround way or trick to allow a partition to appear as part of C:\ root system drive. This hack is particular useful to expand the hard disk space size of C:\ or other system drive without having to use a new disk drive letter or switching drive to accommodate older program or application that must store and save data on installed drive, typically at system drive.
To mount partition or volume as a folder, users must first have or create a empty folder on a NTFS formatted file system that users want to assign or associate with the partition or volume. And it’s also possible to mount a partition, a volume or a hard disk drive which already assigned with a disk drive letter as folder too, allowing two ways to access the volume or partition via different drive or different folder. And it’s not necessary that only a hard disk (which whole hard disk been allocated as single partition) can be mounted as an empty NTFS folder, unused partition or empty space on existing disk can be mounted as NTFS folder too as long as users can create a new partition on it.
How to Mount a New Volume/Partition as Folder
Click on Start Menu, then select Run. In Vista, press Win+R key to open Run command.
Type DiskMgmt.msc to open Disk Management.
Right click on the new hard disk or remaining unallocated space, and then select New Partition or New Simple Volume (in Vista). If the partition has been created, delete the partition and re-create it.
For partition that has been allocated with drive letter and path, right click on the partition and select Change Drive Letter and Paths.
In the “New Simple Volume Wizard” or “New Partition Wizard”, follow the instructions on screen such as selecting the size of the new partition, until the the Assign Drive Letter or Path screen.
For existing volume/partition, click on Add button to add a new path instead.
Select Mount in the following empty NTFS folder radio button, and then select Browse… button.
For existing volume/partition, the “Mount in the following empty NTFS folder” is automatically selected. Users cannot assign more than one drive letter to a partition, but can assign many paths (folders) to a partition.
Select an empty folder that you want to mount this new partition. Click on New Folder to create a new directory if needed. Once selected the mounting folder, click OK button.
For existing partition already with drive letter, process is completed and users can now open Windows Explorer to browse the partition content in the mounted folder.
Else, back in the wizard, continue to follow instructions on screen to complete the wizard by selecting file system, allocation unit size, volume label, decide whether to perform quick format or whether to enable file and folder compression. Wait for the disk formatting to complete too. After process completed, a folder is linked to the partition/volume.
As mentioned, users can assigned many folder path to a single volume or partition. Users can also remove the relationship of folder mount point with volume at any time, or change back to a drive letter. Even already mounted on a folder path, a drive letter can still be assigned to the partition too. All these administrative operations can be done on the Disk Management. Best of all, changing drive letter or folder paths of a volume will not delete the data on the drive.
window.google_render_ad();

Monday, March 9, 2009

Open folder to location of a file

I cannot seem to remember this even though I wrote code at least twice to do it!

In dlgUpgrade From in DRC

'WIN32 API
Private Declare Function SetActiveWindow Lib "user32.dll" (ByVal hwnd As Long) As Long
Private Declare Function ShellExecute Lib "shell32.dll" Alias "ShellExecuteA" (ByVal hwnd As Long, ByVal lpOperation As String, ByVal lpFile As String, ByVal lpParameters As String, ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)


'Add functions
Public Function StartDoc(ByVal fileName As String, Optional CommandLine As String = "") As Long
StartDoc = ShellExecute(0&, "Open", fileName, CommandLine, vbNullString, 1)
End Function
Private Function GetParentDir(ByVal myFile As String, Optional RemoveSeparator As Boolean = True, Optional IgnoreDirValidation As Boolean = False) As String
On Error Resume Next
Dim i As Long, j As Integer
If RemoveSeparator = True Then
j = 1
Else
j = 0
End If
If IgnoreDirValidation = True Then
i = InStr(1, StrReverse(myFile), "\")
If i = 0 Then
GetParentDir = ""
Else
GetParentDir = StrReverse(Mid$(StrReverse(myFile), i + j))
End If
Else
If Dir$(myFile) = "" Then
GetParentDir = ""
Else
i = InStr(1, StrReverse(myFile), "\")
If i = 0 Then
GetParentDir = ""
Else
GetParentDir = StrReverse(Mid$(StrReverse(myFile), i + j))
End If
End If
End If
End Function

Private Function getFileName(filePath As String, Optional separator As String = "\", Optional removeExtension As Boolean = False) As String
Dim tmp As String
tmp = Mid$(filePath, InStrRev(filePath, separator) + 1)
If tmp = filePath Then
getFileName = ""
Else
If removeExtension Then
If InStrRev(tmp, ".") > 0 Then
getFileName = Left$(tmp, InStrRev(tmp, ".") - 1)
Else
getFileName = tmp
End If
Else
getFileName = tmp
End If
End If
End Function


'Call to OpenFileFolder
Private Sub OpenFileFolder(filePath As String)
Dim i As Long, j As Long, fileName As String
If isFileExist(filePath) Then
i = StartDoc("explorer.exe ", GetParentDir(filePath))
j = SetActiveWindow(i)
Sleep 1000 '<< 1 second
DoEvents

fileName = getFileName(filePath)
For i = 1 To Len(fileName)
SendKeys Mid$(fileName, i, 1)
DoEvents
Next i
End If
End Sub