Execute VBScript from C#

This can be done using, CScript.exe

Process scriptProc = new Process();
scriptProc.StartInfo.FileName = @"cscript"; 
scriptProc.StartInfo.WorkingDirectory = @"c:\scripts\";
scriptProc.StartInfo.Arguments ="//B //Nologo vbscript.vbs";
scriptProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; //prevents console window from popping out
scriptProc.Start();
scriptProc.WaitForExit(); //(Optional)
scriptProc.Close();
Advertisements

Show the Output Window During Build – Visual Studio

Developers, like me, can sometimes get very particular about their dev environment. ūüėČ

One such particular feature for me, in Visual Studio, is the automatic appearance of output window while debugging. While one can always view it by pressing,

CTRL + ALT + O

I wanted this behavior to be constant and automatic on every build. Turns out, there’s a setting for it! Go to

Tools -> Options -> Projects and Solutions -> General and select/deselect the “Show Output window when build starts”

Configure show hide on Visual Studio Output window

Cannot start the website because administrative privileges are required to bind to the hostname or port

This error was thrown when I ran the newly downloaded BlogEngine.NET code from Visual Studio 2015.
First thing first, this has got nothing to do with ‘Run as administrator‘ option. The error states that there is a permission issue on the port on which IISExpress was attempting to run the site. I hadn’t changed anything to the original code base. So it was apparent that the port setting must have got imported. My understanding was that Visual Studio auto manages this setting, i.e., if the attempted port is busy, then VS automatically finds the next available slot. As it turned out, this is not the case.

 
Anyways, the solution is to remove the old references of the url (IISUrl) and the port (DevelopmentServerPort) from the csproj file. Apparantly, if you don’t provide any specific url & port, Visual Studio will automatically look for an available port. Yes! automatic.

Following are the steps to accomplish the same:

  • First, ensure that, ‘Apply server settings to all users (store in project file)‘ is checked.
  • From the Solution Explorer in Visual Studio, right click the web project and select ‘Unload Project‘.
  • Next on the same project, right click and select ‘Edit‘.
  • Find the xml tags and and remove them.
  • Reload the project and run.
As you can see in the address bar, the site’s running and is doing so on a different port.

The primary reference could not be resolved because it has an indirect dependency on the framework assembly

I was migrating a SharePoint 2010 code base to SharePoint 2013. To do that, the targetFramework has to be changed to 4.0. So I moved the entire code base to a different VM which was running the latest .net framework, 4.5. I then changed the targetFramework of the solution to 4.0. Also, I accordingly modified the corresponding SharePoint dlls which now were being referenced from the folder 15. Finally, when I tried to build the solution, I received the following error:

The primary reference “Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL” could not be resolved because it has an indirect dependency on the framework assembly
A more detailed explanation was found in the OutPut window:
C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1819,5): warning MSB3268: The primary reference “Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL” could not be resolved because it has an indirect dependency on the framework assembly “System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” which could not be resolved in the currently targeted framework. “.NETFramework,Version=v4.0”. To resolve this problem, either remove the reference “Microsoft.SharePoint, Version=15.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL” or retarget your application to a framework version which contains “System.Net.Http, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”.
I know that for Microsoft.SharePoint version 15, the targetFramework has to be 4.0 (Full), which is exactly what I was using! So, what caused this issue?

Solution

The solution was to include the following tag
<SpecificVersion>True</SpecificVersion>

for all the assemblies which were causing this issue to the dependent projects. To do that, follow the below steps:

  • Identify the erroneous assemblies. In my case it was the Microsoft.SharePoint &¬†Microsoft.SharePoint.Portal¬†dlls. You can also¬†identify it from the output window of your VS.
  • Next, from the Solution Explorer, unload the corresponding project which are targeting the erroneous assemblies.
  • After unloading, right click the same project and click Edit.
  • Locate the reference of the erroneous assemblies, and append the tag, True. For ex, in my case, after the change, the assembly Reference looked like the following
  • In case you’re targeting a project output from the same solution, instead of a standalone assembly, the resolution will still be the same. The ProjectReference will then look like the following:
  • Finally, Re-Load the project and build. The build will be successful.

Explanation

Specific Version signifies that Visual Studio will only build if it has access to the specific version of the referenced assembly. This kind of error/check is enforced mostly when we implement .net assemblies targeting different versions of .net framework than the targetFramework of the current project. Please note, that the Specific Version property is only a build-time directive, and it has no effect on the run-time version resolution of the referenced assembly. So it’s not gonna affect the behavior or outcome of your program. It’s simply a check enforced while building the project.

Key Takeaways

  • The default value of¬†Specific Version is false.
  • Specific Version¬†is only a build-time directive, and it has no effect on the run-time version resolution of the referenced assembly.
  • Specific Version of a project can also be modified directly from the corresponding property window of the erroneous assembly. However, it is strongly recommended to modify this value only using the steps described above.

Makecab.exe

MakeCAB is a Lossless Data Compression tool that can be used for a wide variety of purposes. Although it was originally designed for use by setup programs, it can also be used in almost any situation where lossless data compression is required.MAKECAB.EXE is designed to produce the final distribution files and cabinets for an entire product in a single run. The most common way to use MAKECAB.EXE is to supply adirectives file that controls how files are compressed and stored into one or more cabinets.

You can run this command from the Visual Studio Command Prompt.

MAKECAB.EXE Syntax

There two primary forms of MAKECAB.EXE usage. The first is used for compressing a single file, while the second is used for compressing multiple files.
MAKECAB  [/Vn] [/D variable=value ...] [/L directory] source [destination]
MAKECAB  [/Vn] [/D variable=value ] /F directives_file [...]
The parameters are described below.
Parameter Description
source A file to be compressed.
destination The name of the file to receive the compressed version of the source file. If not supplied, a default destination name is constructed from the source file name according to the rules defined by the CompressedFileExtensionChar variable. You can use /D CompressedFileExtensionChar=c on the command line to change the appended character.
/Dvariable=value Set variable to be equal to value. Equivalent to using the .Set command in the directives file. For example, a single directive file could be used to produce layouts for different disk sizes by running MakeCAB once with different values of MaxDiskSize defined: /D MaxDiskSize=1.44M. Both standard MakeCAB variables and custom variables may be defined in this way. If .Option Explicit is specified in a directive file, then variable must be defined with a .Definecommand in a directive file.
/L directory Specifies an output directory where the compressed file will be placed (most useful when destination is not supplied).
/Fdirectives_file A file containing commands for MAKECAB.EXE to execute. If more than one directive file is specified (/F file1 /F file2 …), they are processed in the order (left to right) specified on the command line. Variable settings, open cabinets, open disks, etc. are all carried forward from one directive file to the next (just as if all of the files had been concatenated together and presented as a single file to MakeCAB). For example, this is intended to simplify the work for a product shipped in multiple languages. There would be a short, language-specific directives file, and then a single, large master directives file that covers the bulk of the product.
/Vn Set debugging verbosity level (0=none,…,3=full)

If there are more than file that one file that you’ll have to package them all together in a single .cab file, then you have to prepare a .ddf file (Diamond Directive File). This file will store a list of all the files to be included in a single package.¬†

MAKECAB.EXE Directive File Syntax

Following is a sample of a .ddf file format.

OPTION EXPLICIT ; Generate errors on variable typos

.Set CabinetNameTemplate=fileexport.cab ; The name of the file
.set DiskDirectoryTemplate=CDROM ; All cabinets go in a single directory
.Set CompressionType=MSZIP ;
.Set Cabinet=on ;
.Set Compress=on ;
.Set DiskDirectory1=directorypath\Directory.CAB 
.Set MaxDiskSize=51200               ; multiple of 512

;*** Files to zip ;
;
directorypath\manifest.xml
directorypath\ExportSettings.xml
directorypath\Requirements.xml
directorypath\RootObjectMap.xml
directorypath\SystemData.xml
directorypath\UserGroup.xml
directorypath\ViewFormsList.xml
directorypath\00000000.dat
directorypath\00000001.dat
directorypath\00000002.dat
directorypath\00000003.dat
;***

A special mention has to be made about the MaxDiskSize property. For some very strange reason you’ld not find this property in most of the online samples. The importance of this property is that it will include only those files in your .cab whose size is less than that specified here. For example, I had some 17 files where most of the files were larger than 25MB. When I executed the Makecab.exe command, I found that only smaller files were included in the .cab files. Larger files were silently ignored with no error message! This was very bad. Anyways, after doing some google, I came across the following post,

http://www.pseale.com/blog/strongopinionsaynotomakecabexe.aspx

which stressed on the importance of this property. Once included in my .ddf file with a value of about 5120000, I can see all my files in the resultant .cab file.

 

The custom tool ‘DataServiceClientGenerator’ failed. Data service client code-generation failed: The element ‘DataService’ has an attribute ‘DataServiceVersion’ with an unrecognized version ‘3.0’..

Recently, I received this error when I was trying to add a ServiceReference (WCF) to my application. To solve this issue upgrade your WCF to the latest version, WCF Data Services 5.0 for OData V3.

Once you have downloaded and installed the ‘exe’:-

  • Remove any existing references to existing assemblies the name of which start with System.Data.Services from all your projects.
  • Instead add the reference of Microsoft.Data.Services.Client.dll wherever System.Data.Services.dll was used.

Microsoft.Data.Services.Client.dll can be found at the location, %programfiles(x86)%\Microsoft WCF Data Services\5.0\bin

To get more details about this upgrade, kindly visit the following link,
http://blogs.msdn.com/b/writingdata_services/archive/2012/04/16/upgrading-wcf-data-services-projects-to-wcf-data-services-5-0.aspx

Create Your First RDLC (Local SSRS) Report in ASP.NET using DataSet C#

Following steps demonstrate how to create your first RDLC Report. This blog is divided into 2 parts:-

  1. Prepare the report from a single table and to solve the Report Viewer Configuration Error, if encountered.
  2. Prepare a single report from two different tables (Not-Related).

The database used here is Microsoft’s Northwind database.

Prepare a Report from a Single Table

# Add DataSet.

# Add DataTable
# Add Columns
# Add RDLC Report
# Choose DataSet
# Choose Fields 
# Choose Layout
# Choose Style
# Finish the Wizard. The report will be then displayed
# Add ReportViewer to the ASP.NET page
# Following is the designer code snippet after adding the ReportViewer control
<%@ Register Assembly="Microsoft.ReportViewer.WebForms, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" Namespace="Microsoft.Reporting.WebForms" TagPrefix="rsweb" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
	<head runat="server">
		<title></title>
	</head>
	<body>

<form id="form1" runat="server">
			<asp:ScriptManager ID="ScriptManager1" runat="server">
			</asp:ScriptManager>
			<rsweb:ReportViewer ID="ReportViewer1" runat="server" Width="600">
			</rsweb:ReportViewer>
		</form>

	</body>
</html>
# Modifying the Code Behind section
using System.Data;
using System.Configuration;
using System.Data.SqlClient;
using Microsoft.Reporting.WebForms;

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        ReportViewer1.ProcessingMode = ProcessingMode.Local;
        ReportViewer1.LocalReport.ReportPath = Server.MapPath("~/Report.rdlc");
        Customers dsCustomers = GetData("select top 20 * from customers");
        ReportDataSource datasource = new ReportDataSource("Customers", dsCustomers.Tables[0]);
        ReportViewer1.LocalReport.DataSources.Clear();
        ReportViewer1.LocalReport.DataSources.Add(datasource);
    }
}

private Customers GetData(string query)
{
    string conString = ConfigurationManager.ConnectionStrings["NorthWindConnectionString"]
                                              .ConnectionString;
    SqlCommand cmd = new SqlCommand(query);
    using (SqlConnection con = new SqlConnection(conString))
    {
        using (SqlDataAdapter sda = new SqlDataAdapter())
        {
            cmd.Connection = con;
            sda.SelectCommand = cmd;
            using (Customers dsCustomers = new Customers())
            {
                sda.Fill(dsCustomers, "DataTable1");
                return dsCustomers;
            }
        }
    }
}

# Next Compile the code. There’s a chance that you might encounter the following error

and then when you click Continue, you’ll be finally redirected to your page which will be displaying the following error message.

The error is pretty straight-forward. Just as the message suggests add the following code to the Web.Config file

<system.webServer>
	<validation validateIntegratedModeConfiguration="false" />
	<handlers>
		<add name="ReportViewerWebControlHandler" preCondition="integratedMode" verb="*" path="Reserved.ReportViewerWebControl.axd" type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=11.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" />
	</handlers>
</system.webServer>

 

Plz make sure that your PublicKeyToken is same as that of the Microsoft.ReportViewer.WebForms in the assemblies section of system.web.

# Next again run the code. You’ll be able to see the following result

You can see that field, Country, has appeared twice. This is because of the fact that I had done a GroupBy this field.

That’s it from this blog. Next as a continuation of it, I’ll be demonstrating how to display multiple tables(2) in a single report. You can find the link of that blog very shortly.
Thanks…

C# The calling thread cannot access this object because a different thread owns it.

One of the common problems encountered during multi-threading is when you try to set a Windows Control value from a different thread. I also faced this issue while implementing the following code:

private async void TestAsyncMethodVoid()
{
    System.Net.Http.HttpClient hClient = new System.Net.Http.HttpClient();
    string content = String.Empty;
    try
    {
        content = await hClient.GetStringAsync("http://www.microsoft.com").ConfigureAwait(false);
    }
    catch (Exception ex)
    {
        content = ex.Message;
    }
    btn00.Content = content;
}

btn00 is a button control whose value I was trying to set here using async/await as the value was coming over a network call. You may have some other case scenarios also where you’d want to set a control’s property directly from the thread. So to do that we’re gonna use,¬†Dispatcher.Invoke method.

It executes the specified delegate synchronously on the thread the Dispatcher is associated with. Look at the following code with correction:

private async void TestAsyncMethodVoid()
{
	System.Net.Http.HttpClient hClient = new System.Net.Http.HttpClient();
	string content = String.Empty;
	try    
	{
		content = await hClient.GetStringAsync("http://www.microsoft.com").ConfigureAwait(false);
	}
	catch (Exception ex)
	{
		content = ex.Message;
	}
	this.Dispatcher.Invoke(() =>
	{
		btn00.Content = content;
	});
}

This code now works without any glitches.

Extract all the Guids from a string C#

This is one of the rare requirement where I had to extract all the Guid from a string and then do the further processing. Now, to do that, I have used Regex.Matches. It will return a MatchCollection containing each Guid. For a string with no Guid, it will return a MatchCollection of length 0.

string strGuid = "5102d73a-1b0b-4461-93cd-0c024738c19e;#5102d73a-1b0b-4461-93cd-0c024733d52d";
string strNoGuid = "someTextButNoGuid";

string pattern = @"([a-z0-9]{8}[-][a-z0-9]{4}[-][a-z0-9]{4}[-][a-z0-9]{4}[-][a-z0-9]{12})";

MatchCollection mc;

//MatchCollection of length 2
mc = Regex.Matches(strGuid, pattern);

//MatchCollection of length 0
mc = Regex.Matches(strNoGuid, pattern);