Joseph Michael Pesch
VP Programming

Sharepoint 2010 Registry Entries

by 5. October 2011 12:38

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\LauncherSettings\LoadBalancerUrl
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Applications\c0e071e1-533e-457a-8a61-8a86a6b78dcd\Gather\Portal_Content\ContentSources\0\StartPages\0\URL
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Applications\c0e071e1-533e-457a-8a61-8a86a6b78dcd\Gather\Portal_Content\ContentSources\0\StartPages\1\URL
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Applications\c0e071e1-533e-457a-8a61-8a86a6b78dcd\ResourceManager\ (several entries)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Search\Applications\fd2e5092-25e3-46cf-8fc6-d62c85334b3d\Gather\Search\ContentSources\0\StartPages\0\URL
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Search\Applications\fd2e5092-25e3-46cf-8fc6-d62c85334b3d\ResourceManager\ (several entries)
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Secure\ConfigDB\dsn
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\WSS\CentralAdministrationURL

Tags:

Restart Machine via Remote Desktop Connection

by 5. October 2011 12:36

From Commandline: "shutdown /r /t 0"

Alternatively, CTRL+ALT+END on the keyboard to get the Windows screen where you have shutdown/restart options.

Tags:

Sharepoint 2010 Database Connection Strings in Registry

by 5. October 2011 08:28

I recently installed a new development environment on a virtual machine that was being used as the basis of a new virtual desktop pool for several developers.  My Sharepoint environment was broken once the virtual desktops were created because the installation put the machine name in the SQL connection strings and each of the virtual desktop instances has a unique machine name.  When I attempted to browse to the local sharepoint site I simply received the following error message: "Cannot connect to the configuration database.".  Researching the log file (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Logs\...) I saw the original machine name in the connection string of the failed connections.  Next I looked at the web.config of the root site as well as the C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\Config\web.config and was unable to find any connection information.  Finally, I found the following registry entries and changed them from the specific machine name to the "localhost" alias.  NOTE: The first entry is the database connection and the other entries are various URL's.

My Computer\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Secure\ConfigDB\

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\LauncherSettings\LoadBalancerUrl

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Applications\c0e071e1-533e-457a-8a61-8a86a6b78dcd\Gather\Portal_Content\ContentSources\0\StartPages\0\URL

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Applications\c0e071e1-533e-457a-8a61-8a86a6b78dcd\Gather\Portal_Content\ContentSources\0\StartPages\1\URL

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office Server\14.0\Search\Applications\c0e071e1-533e-457a-8a61-8a86a6b78dcd\ResourceManager\ (several urls are located in this section)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Search\Applications\fd2e5092-25e3-46cf-8fc6-d62c85334b3d\Gather\Search\ContentSources\0\StartPages\0\URL

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\Search\Applications\fd2e5092-25e3-46cf-8fc6-d62c85334b3d\ResourceManager\ (several urls are located in this section)

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Shared Tools\Web Server Extensions\14.0\WSS\CentralAdministrationURL

 

Tags:

Sharepoint

SQL Out of Log Space

by 3. October 2011 15:39

To recover allocated but unused space run this command:

dbcc shrinkdatabase ('DBNAME_HERE', TRUNCATEONLY)

Tags:

SQL Server

ASP.Net WCF Data Services Error Hosting on Multiple Environments

by 25. September 2011 16:25

I encountered an error when attempting to access a WCF Data Service from my hosted web site.  This error did not occur when running the service on my local development PC.  This is the error I received: "This collection already contains an address with scheme http.  There can be at most one address pr scheme in this collection. Parameter name: item"  To resolve this error my web.config required and additional entry to provide the host name as shown here.

<system.serviceModel>
  <serviceHostingEnvironment aspNetCompatibilityEnabled="true">
      <baseAddressPrefixFilters>
        <add prefix="http://mydomain.com" />
      </baseAddressPrefixFilters>
  </serviceHostingEnvironment>
</system.serviceModel>

Tags:

C#

Deploying SSAS Cube from Development to Test/Production

by 23. September 2011 08:47

The easiest way to deploy the cube is to generate a create database script from within SQL Management Studio.  When generating a database script of an Analysis Server database the resulting script file will be XMLA rather than SQL script (as when generating a normal SQL database script).  The resulting XMLA file will contain a DataSources section that contains connection information about the relational database (e.g. datawarehouse database) that the SSAS cube will be reading it's data from.  Below is an example of that section where I have put in variable placeholders to replace the original values of the following items:

  • $(DWServer) - Target database server where the relational data exists.
  • $(DWDatabase) - Target database where the relational data exists.
  • $(DwReaderAccount) - User account name that has read access to the relation database.
  • $(DwReaderPassword) - Password of the reader account.

Here is a sample section of the XMLA file with the above indicated replacements:

<DataSources>
  <DataSource xsi:type="RelationalDataSource">
    <ID>IMPACDW</ID>
    <Name>IMPACDW</Name>
    <ConnectionString>Data Source=$(ImpacDWServer);Initial Catalog=$(ImpacDWDatabase);Integrated Security=True</ConnectionString>
    <ImpersonationInfo>
      <ImpersonationMode>ImpersonateAccount</ImpersonationMode>
      <Account>$(ImpacDWReaderAccount)</Account>
      <Password>$(ImpacDWReaderPassword)</Password>
    </ImpersonationInfo>
    <ManagedProvider>System.Data.SqlClient</ManagedProvider>
    <Timeout>PT0S</Timeout>
    <DataSourcePermissions>
      <DataSourcePermission>
        <ID>DataSourcePermission 1</ID>
        <Name>DataSourcePermission 1</Name>
        <RoleID>Role 1</RoleID>
        <Read>Allowed</Read>
      </DataSourcePermission>
    </DataSourcePermissions>
  </DataSource>
</DataSources>

In order to run the XMLA file through command line (rather than directly in SQL Management Studio) you will need the ASCMD.EXE utility from Microsoft.  You can download it from the SQL Server Analysis Samples page on CodePlex.com (below are links to the SQL 2005 and 2008 pages).

SQL 2005

SQL 2008

Tags:

SSAS

SQL Script to Generate Table Inserts

by 23. September 2011 07:46

This script will accept a database name and comma delimited list of table names.  It will generate insert statements for all the records in the desired tables.  I will be adapting the script to include schema as well as table name.  The original script was provided by: http://blog.boxedbits.com/archives/50

CREATE Procedure [dbo].[sp_CreateDataLoadScript]
@databaseName	varchar(128) ,
@TblNames varchar(max)
as begin

	set nocount on;

	create table #a (id int identity (1,1), ColType int, ColName varchar(128))
	create table #out (lnr int, statements varchar(max))
	declare @sql nvarchar(4000)
	declare @TblName as varchar(128)
	declare @idx as bigint
	declare @previdx as bigint
	declare @last as bit
	declare @hasIdentity as bit
	declare @lnr as int

	set @lnr=0

	set @idx=charindex(',',@TblNames)
	set @previdx=1

	if @idx>0 begin  /* many tables */
		set @TblName=ltrim(rtrim(substring(@TblNames,@previdx,@idx-@previdx)))
		set @previdx=@idx+1
		set @last=0
	end
	else begin /* 1 table */
		set @TblName=ltrim(rtrim(@TblNames))
		set @last=1
	end

	while len(@TblName)>0 begin
	

		select @sql = 'select case when DATA_TYPE like ''%char%'' or DATA_TYPE like ''%date%'' or DATA_TYPE like ''uniqueidentifier'' then 1 else 0 end , COLUMN_NAME
			from 	information_schema.columns
			where 	TABLE_NAME = ''' + @TblName + '''
			order by ORDINAL_POSITION
			'

		select 	@sql = 'exec ' +  @databaseName + '.dbo.sp_executesql N''' + replace(@sql, '''', '''''') + ''''
		
		insert 	#a (ColType, ColName)
		exec (@sql)
		

		select @hasIdentity=max(cast(clmns.is_identity as int))
		from sys.tables AS tbl
		INNER JOIN sys.all_columns AS clmns ON  clmns.object_id = tbl.object_id
		where 	tbl.name = @TblName

		declare	@id int ,
		@maxid int ,
		@cmd1 varchar(7000) ,
		@cmd2 varchar(7000)

		insert into #out select @lnr, '/* ' + @TblName + ' */'
		set @lnr = @lnr+1
		insert into #out select @lnr, 'truncate table ' + @TblName
		set @lnr = @lnr+1

		if @hasIdentity=1 begin
			insert into #out select @lnr, 'set identity_insert ' + @TblName + ' ON'
			set @lnr = @lnr+1
		end
			
		select 	@id = 0 , @maxid = max(id)
		from 	#a

		select	@cmd1 = 'insert into #out select ' + cast(@lnr as varchar) + ', '' insert ' + @TblName + ' ( '
		select	@cmd2 = ' + '' select '' + '
		while @id < @maxid
		begin
			select @id = min(id) from #a where id > @id

			select 	@cmd1 = @cmd1 + '[' + ColName + '],'
			from	#a
			where	id = @id

			select @cmd2 = 	@cmd2
					+ ' case when [' + ColName + '] is null '
					+	' then ''null'' '
					+	' else '
					+	  case when ColType = 1 then  ''''''''' + replace(convert(varchar(max),[' + ColName + ']),'''''''','''''''''''') + ''''''''' else 'convert(varchar(50),[' + ColName + '])' end
					+ ' end + '','' + '
			from	#a
			where	id = @id
		end

		select @cmd1 = left(@cmd1,len(@cmd1)-1) + ' ) '' '
		select @cmd2 = left(@cmd2,len(@cmd2)-8) + ' from ' + @databaseName + '.dbo.' + @tblName

		exec (@cmd1 + @cmd2)
		truncate table #a

		if @hasIdentity=1 begin
			insert into #out select @lnr, 'set identity_insert ' + @TblName + ' OFF'
			set @lnr = @lnr+1
		end

		insert into #out select @lnr, 'go'
		set @lnr = @lnr+1

		-- next table
		set @idx=charindex(',',@TblNames,@previdx)
		if @idx>0 begin  /* more tables */
			set @TblName=ltrim(rtrim(substring(@TblNames,@previdx,@idx-@previdx)))
			set @previdx=@idx+1
		end
		else if @last=0 begin /* one more */
			set @TblName=ltrim(rtrim(substring(@TblNames,@previdx,8000)))
			set @last=1
		end
		else  /* done */
			set @TblName=''
	end

	drop table #a

	print 'use ' + @databaseName
	print 'go'
	print 'set nocount on'


	declare @statement varchar(max)
	declare @o int
	declare c_out cursor  LOCAL FAST_FORWARD for select statements from #out order by lnr
	open c_out

	declare @i int
	set @i=0
	fetch next from c_out into @statement

	while @@fetch_status=0 begin
		set @i=@i+1
		if @i=1000 begin
			print 'go'
			set @i=0
		end

		print @statement

		fetch next from c_out into @statement
	end

	close c_out
	deallocate c_out
	drop table #out
end

Tags:

SQL Server

Sample jQuery - Reading oData Using XML and JSON

by 21. September 2011 13:50

Below are some sample jQuery script methods that illustrate reading data from an oData service.  One uses XML, while the other uses JSON.  The attached zip file contains the full source code, including the AdventureWorks sample database and the C# WCF Data Service that binds to it.  NOTE: That the jQuery JSON call will fail if the web site is compiled under .Net 3.5 framework; however, it will work correctly if compiled under the .Net 4.0 framework.  I saw some other posts indicating that this was a known issue in 3.5 where the JSON was not valid (the jQuery JSON call then errors out claiming the JSON is not valid).

ODataWeb.zipx (603.57 kb)

$.ajaxSetup({ "error": function (XMLHttpRequest, textStatus, errorThrown) {
  alert(textStatus);
  alert(errorThrown);
  alert(XMLHttpRequest.responseText);
}
});

$(document).ready(function () {
  TestAjax();
  TestJSON();
});

function TestAjax() {
  // setup sample url to find all product descriptions that contain the word "alloy"
  var url = "http://localhost:4241/adventureworks_wcfdataservice.svc/ProductDescriptions?$filter=indexof(Description, 'alloy') ne -1";
  $('#TestAjaxLink').click(function () {
    $.ajax({
      url: url,
      beforeSend: function (xhr) {
        xhr.overrideMimeType('text/plain; charset=x-user-defined');
      },
      success: function (data) {
        //$('#TestAjaxData').html(data);
        var xml = $.parseXML(data);
        $(xml).find('entry').each(function () {
          var propXml = $(this).find('content').find('m\\:properties');
          var line = '
' + (propXml.find('d\\:ProductDescriptionID').text()) + ': ' + (propXml.find('d\\:Description').text()) + '
' $('#TestAjaxData').append(line); }); } }); }); } function TestJSON() { // setup sample url to find all product descriptions that contain the word "alloy" var url = "http://localhost:4241/adventureworks_wcfdataservice.svc/ProductDescriptions?$filter=indexof(Description, 'alloy') ne -1"; $('#TestJsonLink').click(function () { $.getJSON(url, function (results) { $.each(results.d, function (i, item) { var line = '
' + item.ProductDescriptionID + ': ' + item.Description + '
' $('#TestJsonData').append(line); }); }); }); }

 

Tags:

C# Code to Get AD Members of a Security Group

by 15. September 2011 09:57

This method will accept a domain name and security group name and return all the AD members of that group.

using System.Collections.Generic;
using System.DirectoryServices;

namespace AdReader
{
  class Program
  {
    static void Main(string[] args)
    {
      List users = GetGroupMembers("domainname.com", "security group name");
      foreach (DirectoryEntry user in users)
      {
        System.Diagnostics.Debug.WriteLine(user.Name.Replace("CN=", ""));
      }
    }
    /// Gets a list of members in the specified group.        
    public static List GetGroupMembers(string domain, string groupName)
    {
      List users = new List();
      string filter = string.Format("(&(ObjectClass={0})(sAMAccountName={1}))", "group", groupName); // principal);            
      string[] properties = new string[] { "fullname" };
      DirectoryEntry adRoot = new DirectoryEntry("LDAP://" + domain, null, null, AuthenticationTypes.Secure);
      DirectorySearcher searcher = new DirectorySearcher(adRoot);
      searcher.SearchScope = SearchScope.Subtree;
      searcher.ReferralChasing = ReferralChasingOption.All;
      searcher.PropertiesToLoad.AddRange(properties);
      searcher.Filter = filter;
      SearchResult result = searcher.FindOne();
      if (result != null)
      {
        DirectoryEntry directoryEntry = result.GetDirectoryEntry();
        foreach (object dn in directoryEntry.Properties["member"])
        {
          DirectoryEntry member = new DirectoryEntry("LDAP://" + dn);
          //Add users from other groups within this group (only go 1 level deep).      
          if (!IsGroup(member))
          {
            users.Add(member);
          }
        }
      }
      return users;
    }
    /// Determine whether the object is a group.        
    private static bool IsGroup(DirectoryEntry de)
    {
      return de.Properties["objectClass"][1].ToString() == "group";
    }
  }
}

Tags:

C#

C# Code to Extract Binary Data from SQL and Save to Disk File

by 14. September 2011 14:24

This code will allow a simple SQL connection to select a single record with binary data in image column and save it as a file on the local disk.

string SQL = "select [FileData] from [MyTable] where [RecordID] = 1";
string cnString = @"Data Source=Server\Instance,Port;Initial Catalog=DB;Integrated Security=True;";
SqlConnection cn = new SqlConnection(cnString);
SqlCommand cmd = new SqlCommand(SQL, cn);
cn.Open();
byte[] byt = (byte[])cmd.ExecuteScalar();
FileStream fs = new FileStream(@"c:\temp\tempfile.txt"
  , FileMode.CreateNew, FileAccess.Write);
fs.Write(byt, 0, byt.Length);
fs.Flush();
fs.Close();

 

 

Tags:

C#

Microsoft SSAS OLAP Error: A duplicate attribute key has been found when processing table column value

by 9. September 2011 21:28

Here is the specific error I encountered:

"Errors in the OLAP storage engine: A duplicate attribute key has been found when processing: Table: 'MyTableHere', Column: 'MyColumnHere', Value: '0'. The attribute is 'MyAttributeHere'."

At first I was very confused because I didn't understand how having multiple values of 0 was an issue. It turns out the real issue is having both 0 values AND null values. The issue is manifest by the processing engine as it performs a select distinct which results in one row for the 0 values and another for the null values. However, the null value is then converted into a 0 by default (if you have the "NullProcessing" attribute of the Dimension set to "Automatic").  This is what causes the conflict.  In my case making the nulls 0 before processing the cube resolved the issue.

NOTE: With the default NULL processing for dimension attributes being set to 'Automatic' nulls will be converted to a Zero (for numerical values) or an empty string (for string values). The issue is that the engine first performs a "select distinct ..." on the raw values, so it will come up with one row for NULL and another row for ZERO/BLANK (depending on data type), then the conversion from NULL to the corresponding default occurs thus resulting in conflicting (or duplicate) keys.

Thanks to this post for helping me out: http://ms-olap.blogspot.com/2009/11/duplicate-attribute-key-has-been-found.html

Tags:

SSAS

MDX CellSetGrid Source Code - Browse SSAS Cube

by 2. September 2011 08:38

This is a C# .Net framework 2.0 based custom web control that allows dynamic navigation of SSAS cube through a standard Asp.Net web page using the Microsoft.AnalysisServices.AdomdClient for data access.  To use it in Visual Studio, create a new solution and include the attached CellsetGrid project.  Then add a new file based web site and reference the CellsetGrid project from the web site.  Then drag the "CellSetGrid2" custom control onto the web page and set the ConnectionString and Cube properties.  ConnectionString will need at a minimum "Data Source=ServerName\InstanceName;Catalog=DatabaseName;".  Below is a screen shot of the control in action.

 

 

 

Tags:

C# | SSAS

SQL Server Analysis Services (SSAS) Issue Processing Database on Server

by 31. August 2011 16:28

I encountered the below error when attempting to process the SSAS database.  In my case all I needed to do was switch the data source connection string provider from "Native OLE DB\SQL Server Native Client 10.0" (SQLNCLI10.1) to ".Net Providers\SqlClient Data Provider" (System.Data.SqlClient).  For some reason the OLE DB provider worked fine on my local development PC; however, it did not work on my test server and required the native .Net SQL client to process.

ERROR MESSAGE:

OLE DB error: OLE DB or ODBC error: A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.; 08001; Client unable to establish connection; 08001; Encryption not supported on the client.; 08001.

Tags:

SQL Server Analysis Services (SSAS) Issue Processing Database on Server

by 30. August 2011 14:36

I encountered the below error when attempting to process the SSAS database.  In my case all I needed to do was switch the data source connection string provider from "Native OLE DB\SQL Server Native Client 10.0" (SQLNCLI10.1) to ".Net Providers\SqlClient Data Provider" (System.Data.SqlClient).  For some reason the OLE DB provider worked fine on my local development PC; however, it did not work on my test server and required the native .Net SQL client to process.

ERROR MESSAGE:

OLE DB error: OLE DB or ODBC error: A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.; 08001; Client unable to establish connection; 08001; Encryption not supported on the client.; 08001.

Tags:

SQL Server Analysis Services (SSAS) Deployment from Dev to Test/Prod

by 30. August 2011 10:59

 

I encountered the below error when attempting to process the SSAS database.  In my case I went into the Services control panel and found the login account that the SQL Server Analysis Services was using and granted that user db_datareader permission on my source data warehouse database.

ERROR MESSAGE:

OLE DB error: OLE DB or ODBC error: A network-related or instance-specific error has occurred while establishing a connection to SQL Server. Server is not found or not accessible. Check if instance name is correct and if SQL Server is configured to allow remote connections. For more information see SQL Server Books Online.; 08001; Client unable to establish connection; 08001; Encryption not supported on the client.; 08001.

Tags:

C# Utility to Read Exif Image Data

by 28. August 2011 17:05

The below code will represents a utility class that makes it easier to get Exif data from images.

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Linq;

namespace ImageProperties
{
  class ExifUtil
  {

    // Sample usage:
    // ExifUtil.EXIFReader exif = new ExifUtil.EXIFReader(@"c:\pathtoimage.jpg");
    // Console.WriteLine(exif[ExifUtil.PropertyTagId.EquipMake].ToString());
    // Console.WriteLine(exif[ExifUtil.PropertyTagId.EquipModel].ToString());

    public enum PropertyTagId
    {
      GpsVer = 0x0000,
      GpsLatitudeRef = 0x0001,
      GpsLatitude = 0x0002,
      GpsLongitudeRef = 0x0003,
      GpsLongitude = 0x0004,
      GpsAltitudeRef = 0x0005,
      GpsAltitude = 0x0006,
      GpsGpsTime = 0x0007,
      GpsGpsSatellites = 0x0008,
      GpsGpsStatus = 0x0009,
      GpsGpsMeasureMode = 0x000A,
      GpsGpsDop = 0x000B,
      GpsSpeedRef = 0x000C,
      GpsSpeed = 0x000D,
      GpsTrackRef = 0x000E,
      GpsTrack = 0x000F,
      GpsImgDirRef = 0x0010,
      GpsImgDir = 0x0011,
      GpsMapDatum = 0x0012,
      GpsDestLatRef = 0x0013,
      GpsDestLat = 0x0014,
      GpsDestLongRef = 0x0015,
      GpsDestLong = 0x0016,
      GpsDestBearRef = 0x0017,
      GpsDestBear = 0x0018,
      GpsDestDistRef = 0x0019,
      GpsDestDist = 0x001A,
      NewSubfileType = 0x00FE,
      SubfileType = 0x00FF,
      ImageWidth = 0x0100,
      ImageHeight = 0x0101,
      BitsPerSample = 0x0102,
      Compression = 0x0103,
      PhotometricInterp = 0x0106,
      ThreshHolding = 0x0107,
      CellWidth = 0x0108,
      CellHeight = 0x0109,
      FillOrder = 0x010A,
      DocumentName = 0x010D,
      ImageDescription = 0x010E,
      EquipMake = 0x010F,
      EquipModel = 0x0110,
      StripOffsets = 0x0111,
      Orientation = 0x0112,
      SamplesPerPixel = 0x0115,
      RowsPerStrip = 0x0116,
      StripBytesCount = 0x0117,
      MinSampleValue = 0x0118,
      MaxSampleValue = 0x0119,
      XResolution = 0x011A,
      YResolution = 0x011B,
      PlanarConfig = 0x011C,
      PageName = 0x011D,
      XPosition = 0x011E,
      YPosition = 0x011F,
      FreeOffset = 0x0120,
      FreeByteCounts = 0x0121,
      GrayResponseUnit = 0x0122,
      GrayResponseCurve = 0x0123,
      T4Option = 0x0124,
      T6Option = 0x0125,
      ResolutionUnit = 0x0128,
      PageNumber = 0x0129,
      TransferFunction = 0x012D,
      SoftwareUsed = 0x0131,
      DateTime = 0x0132,
      Artist = 0x013B,
      HostComputer = 0x013C,
      Predictor = 0x013D,
      WhitePoint = 0x013E,
      PrimaryChromaticities = 0x013F,
      ColorMap = 0x0140,
      HalftoneHints = 0x0141,
      TileWidth = 0x0142,
      TileLength = 0x0143,
      TileOffset = 0x0144,
      TileByteCounts = 0x0145,
      InkSet = 0x014C,
      InkNames = 0x014D,
      NumberOfInks = 0x014E,
      DotRange = 0x0150,
      TargetPrinter = 0x0151,
      ExtraSamples = 0x0152,
      SampleFormat = 0x0153,
      SMinSampleValue = 0x0154,
      SMaxSampleValue = 0x0155,
      TransferRange = 0x0156,
      JPEGProc = 0x0200,
      JPEGInterFormat = 0x0201,
      JPEGInterLength = 0x0202,
      JPEGRestartInterval = 0x0203,
      JPEGLosslessPredictors = 0x0205,
      JPEGPointTransforms = 0x0206,
      JPEGQTables = 0x0207,
      JPEGDCTables = 0x0208,
      JPEGACTables = 0x0209,
      YCbCrCoefficients = 0x0211,
      YCbCrSubsampling = 0x0212,
      YCbCrPositioning = 0x0213,
      REFBlackWhite = 0x0214,
      Gamma = 0x0301,
      ICCProfileDescriptor = 0x0302,
      SRGBRenderingIntent = 0x0303,
      ImageTitle = 0x0320,
      ResolutionXUnit = 0x5001,
      ResolutionYUnit = 0x5002,
      ResolutionXLengthUnit = 0x5003,
      ResolutionYLengthUnit = 0x5004,
      PrintFlags = 0x5005,
      PrintFlagsVersion = 0x5006,
      PrintFlagsCrop = 0x5007,
      PrintFlagsBleedWidth = 0x5008,
      PrintFlagsBleedWidthScale = 0x5009,
      HalftoneLPI = 0x500A,
      HalftoneLPIUnit = 0x500B,
      HalftoneDegree = 0x500C,
      HalftoneShape = 0x500D,
      HalftoneMisc = 0x500E,
      HalftoneScreen = 0x500F,
      JPEGQuality = 0x5010,
      GridSize = 0x5011,
      ThumbnailFormat = 0x5012,
      ThumbnailWidth = 0x5013,
      ThumbnailHeight = 0x5014,
      ThumbnailColorDepth = 0x5015,
      ThumbnailPlanes = 0x5016,
      ThumbnailRawBytes = 0x5017,
      ThumbnailSize = 0x5018,
      ThumbnailCompressedSize = 0x5019,
      ColorTransferFunction = 0x501A,
      ThumbnailData = 0x501B,
      ThumbnailImageWidth = 0x5020,
      ThumbnailImageHeight = 0x5021,
      ThumbnailBitsPerSample = 0x5022,
      ThumbnailCompression = 0x5023,
      ThumbnailPhotometricInterp = 0x5024,
      ThumbnailImageDescription = 0x5025,
      ThumbnailEquipMake = 0x5026,
      ThumbnailEquipModel = 0x5027,
      ThumbnailStripOffsets = 0x5028,
      ThumbnailOrientation = 0x5029,
      ThumbnailSamplesPerPixel = 0x502A,
      ThumbnailRowsPerStrip = 0x502B,
      ThumbnailStripBytesCount = 0x502C,
      ThumbnailResolutionX = 0x502D,
      ThumbnailResolutionY = 0x502E,
      ThumbnailPlanarConfig = 0x502F,
      ThumbnailResolutionUnit = 0x5030,
      ThumbnailTransferFunction = 0x5031,
      ThumbnailSoftwareUsed = 0x5032,
      ThumbnailDateTime = 0x5033,
      ThumbnailArtist = 0x5034,
      ThumbnailWhitePoint = 0x5035,
      ThumbnailPrimaryChromaticities = 0x5036,
      ThumbnailYCbCrCoefficients = 0x5037,
      ThumbnailYCbCrSubsampling = 0x5038,
      ThumbnailYCbCrPositioning = 0x5039,
      ThumbnailRefBlackWhite = 0x503A,
      ThumbnailCopyRight = 0x503B,
      LuminanceTable = 0x5090,
      ChrominanceTable = 0x5091,
      FrameDelay = 0x5100,
      LoopCount = 0x5101,
      GlobalPalette = 0x5102,
      IndexBackground = 0x5103,
      IndexTransparent = 0x5104,
      PixelUnit = 0x5110,
      PixelPerUnitX = 0x5111,
      PixelPerUnitY = 0x5112,
      PaletteHistogram = 0x5113,
      Copyright = 0x8298,
      ExifExposureTime = 0x829A,
      ExifFNumber = 0x829D,
      ExifIFD = 0x8769,
      ICCProfile = 0x8773,
      ExifExposureProg = 0x8822,
      ExifSpectralSense = 0x8824,
      GpsIFD = 0x8825,
      ExifISOSpeed = 0x8827,
      ExifOECF = 0x8828,
      ExifVer = 0x9000,
      ExifDTOrig = 0x9003,
      ExifDTDigitized = 0x9004,
      ExifCompConfig = 0x9101,
      ExifCompBPP = 0x9102,
      ExifShutterSpeed = 0x9201,
      ExifAperture = 0x9202,
      ExifBrightness = 0x9203,
      ExifExposureBias = 0x9204,
      ExifMaxAperture = 0x9205,
      ExifSubjectDist = 0x9206,
      ExifMeteringMode = 0x9207,
      ExifLightSource = 0x9208,
      ExifFlash = 0x9209,
      ExifFocalLength = 0x920A,
      ExifMakerNote = 0x927C,
      ExifUserComment = 0x9286,
      ExifDTSubsec = 0x9290,
      ExifDTOrigSS = 0x9291,
      ExifDTDigSS = 0x9292,
      ExifFPXVer = 0xA000,
      ExifColorSpace = 0xA001,
      ExifPixXDim = 0xA002,
      ExifPixYDim = 0xA003,
      ExifRelatedWav = 0xA004,
      ExifInterop = 0xA005,
      ExifFlashEnergy = 0xA20B,
      ExifSpatialFR = 0xA20C,
      ExifFocalXRes = 0xA20E,
      ExifFocalYRes = 0xA20F,
      ExifFocalResUnit = 0xA210,
      ExifSubjectLoc = 0xA214,
      ExifExposureIndex = 0xA215,
      ExifSensingMethod = 0xA217,
      ExifFileSource = 0xA300,
      ExifSceneType = 0xA301,
      ExifCfaPattern = 0xA302
    }

    public enum PropertyTagType
    {
      PixelFormat4bppIndexed = 0,
      Byte = 1,
      ASCII = 2,
      Short = 3,
      Long = 4,
      Rational = 5,
      Undefined = 7,
      SLONG = 9,
      SRational = 10
    }

    public class Fraction
    {
      #region Class constructor

      public Fraction(int numerator, int denumerator)
      {
        Numerator = numerator;
        Denumerator = denumerator;
      }

      public Fraction(uint numerator, uint denumerator)
      {
        Numerator = Convert.ToInt32(numerator);
        Denumerator = Convert.ToInt32(denumerator);
      }

      public Fraction(int numerator)
      {
        Numerator = numerator;
        Denumerator = 1;
      }

      #endregion

      #region Numerator

      private int numerator;
      public int Numerator
      {
        get
        {
          return numerator;
        }
        set
        {
          numerator = value;
        }
      }

      #endregion

      #region Denumerator

      private int denumerator;
      public int Denumerator
      {
        get
        {
          return denumerator;
        }
        set
        {
          denumerator = value;
        }
      }

      #endregion

      #region ToString override

      public override string ToString()
      {
        if (Denumerator == 1)
          return String.Format("{0}", Numerator);
        else
          return String.Format("{0}/{1}", Numerator, Denumerator);
      }


      #endregion
    }

    public class PropertyTagValue
    {
      public static object GetValueObject(PropertyItem property)
      {
        if (property == null)
          return null;
        switch ((PropertyTagType)property.Type)
        {
          //ASCII
          case PropertyTagType.ASCII:
            ASCIIEncoding encoding = new ASCIIEncoding();
            return encoding.GetString(property.Value, 0, property.Len - 1);
          //BYTE
          case PropertyTagType.Byte:
            if (property.Len == 1)
              return property.Value[0];
            else
              return property.Value;
          //LONG
          case PropertyTagType.Long:
            uint[] resultLong = new uint[property.Len / 4];
            for (int i = 0; i < resultLong.Length; i++)
              resultLong[i] = BitConverter.ToUInt32(property.Value, i * 4);
            if (resultLong.Length == 1)
              return resultLong[0];
            else
              return resultLong;
          //SHORT
          case PropertyTagType.Short:
            ushort[] resultShort = new ushort[property.Len / 2];
            for (int i = 0; i < resultShort.Length; i++)
              resultShort[i] = BitConverter.ToUInt16(property.Value, i * 2);
            if (resultShort.Length == 1)
              return resultShort[0];
            else
              return resultShort;
          //SLONG
          case PropertyTagType.SLONG:
            int[] resultSLong = new int[property.Len / 4];
            for (int i = 0; i < resultSLong.Length; i++)
              resultSLong[i] = BitConverter.ToInt32(property.Value, i * 4);
            if (resultSLong.Length == 1)
              return resultSLong[0];
            else
              return resultSLong;
          //RATIONAL
          case PropertyTagType.Rational:
            Fraction[] resultRational = new Fraction[property.Len / 8];
            uint uNumerator;
            uint uDenumerator;
            for (int i = 0; i < resultRational.Length; i++)
            {
              uNumerator = BitConverter.ToUInt32(property.Value, i * 8);
              uDenumerator = BitConverter.ToUInt32(property.Value, i * 8 + 4);
              resultRational[i] = new Fraction(uNumerator, uDenumerator);
            }
            if (resultRational.Length == 1)
              return resultRational[0];
            else
              return resultRational;
          //SRATIONAL
          case PropertyTagType.SRational:
            Fraction[] resultSRational = new Fraction[property.Len / 8];
            int sNumerator;
            int sDenumerator;
            for (int i = 0; i < resultSRational.Length; i++)
            {
              sNumerator = BitConverter.ToInt32(property.Value, i * 8);
              sDenumerator = BitConverter.ToInt32(property.Value, i * 8 + 4);
              resultSRational[i] = new Fraction(sNumerator, sDenumerator);
            }
            if (resultSRational.Length == 1)
              return resultSRational[0];
            else
              return resultSRational;
          //UNDEFINE
          default:
            if (property.Len == 1)
              return property.Value[0];
            else
              return property.Value;
        }
      }
    }

    public class EXIFReader
    {
      #region EXIFReader constructors

      public EXIFReader(Image image)
      {
        this.image = image;
        props = image.PropertyItems;
      }

      public EXIFReader(string path)
      {
        using (FileStream fs = new FileStream(path, FileMode.Open))
        {
          this.image = Image.FromStream(fs);
          props = image.PropertyItems;
        }
      }

      public EXIFReader(Stream stream)
      {
        this.image = Image.FromStream(stream);
        props = image.PropertyItems;
      }

      #endregion

      #region Image

      public Image image;
      private PropertyItem[] props;

      #endregion

      #region EXIF property indexers

      public object this[int Id]
      {
        get
        {
          try
          {
            PropertyItem property = props.Where(x => x.Id.ToString().Equals(Id.ToString())).FirstOrDefault();
            return PropertyTagValue.GetValueObject(property);
          }
          catch
          {
            return null;
          }
        }
      }

      public object this[PropertyTagId TagId]
      {
        get
        {
          try
          {
            PropertyItem property = props.Where(x => x.Id.ToString().Equals(((int)TagId).ToString())).FirstOrDefault();
            return PropertyTagValue.GetValueObject(property);
          }
          catch
          {
            return null;
          }
        }
      }

      #endregion
    }

  }
}

Tags:

C#

iTunes iPhone Backup Location - Set Alternate Folder Path

by 27. August 2011 13:21

When using iTunes to backup your iPhone it will typically store all the data (pictures, videos, etc.) in the following location: 

Old Style:  C:\Documents and Settings\USERNAME\Application Data\Apple Computer\MobileSync\Backup

New Style: C:\Users\jmpadmin\AppData\Roaming\Apple Computer\MobileSync\Backup

Apparently, there is no way to change this path through the iTunes configuration options.  When using a Windows based PC you can however use the Microsoft SysInternals "Junction.exe" program to create a pointer from one file path to another.  The command line example below would point to another drive.  In that example any files written to the Apple Backup folder on the C: drive will actually be stored in the folder on the E: drive.  This can be useful when (as in my case) the C: drive is nearly full and you want to store all that backup data on an external hard drive (in this example the E: drive represents an external hard drive).

1) Delete the "Backup" folder from inside the "MobileSync" folder (make sure to make a copy of whatever is inside the folder if you have already used iTunes on the computer).

2) Create a new "Backup" folder in your desired target location (copy your original files back into this new location).

3) Run the following command from a command prompt (note, you must the the Junction.exe executable located in the folder your command line is running from):

junction.exe  "C:\Users\USERNAME\AppData\Roaming\Apple Computer\MobileSync\Backup" D:\NEWFOLDERLOCATION

NOTE: You can also use MKLink command line that works similarly to Junction

Tags:

Convert C# DataTable to Delimited File

by 22. August 2011 16:11

 

public static DataTable GetDataTableFromCsv(string FilePath)
{
  return GetDataTableFromDelim(FilePath, ",");
}
public static DataTable GetDataTableFromTab(string FilePath)
{
  return GetDataTableFromDelim(FilePath, @"\t");
}
public static DataTable GetDataTableFromDelim(string FilePath, string Delim)
{
  DataTable tbl = new DataTable();
  string CsvData = string.Empty;
  CsvData = File.ReadAllText(FilePath);
  bool firstRow = true;
  foreach (string row in CsvData.Split("\n".ToCharArray()))
  {
    DataRow dr = tbl.NewRow();
    System.Text.RegularExpressions.RegexOptions options = (
        System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace
      | System.Text.RegularExpressions.RegexOptions.Multiline
      | System.Text.RegularExpressions.RegexOptions.IgnoreCase);
    Regex reg = new Regex(Delim 
      + @"(?=(?:[^\""]*\""[^\""]*\"")*(?![^\""]*\""))", options);
    var csvArray = reg.Split(row.Replace("\n", "").Replace("\r", ""));
    for (int i = 0; i < csvArray.Length; i++)
    {
      csvArray[i] = csvArray[i].Replace("\"\"", "");
      if (firstRow)
        tbl.Columns.Add(new DataColumn() { ColumnName = csvArray[i] });
      else
        dr[i] = csvArray[i];
      Console.WriteLine(csvArray[i]);
    }
    if (!firstRow && !dr[0].ToString().Length.Equals(0)) tbl.Rows.Add(dr);
    firstRow = false;
  }
  return tbl;
}

private static string DelimTextFromTable(DataTable tbl, string delim)
{
  var sb = new StringBuilder();
  sb.AppendLine(string.Join(delim,
    tbl.Columns.Cast<DataColumn>().Select(arg => arg.ColumnName)));
  foreach (DataRow dataRow in tbl.Rows)
    sb.AppendLine(string.Join(delim,
      dataRow.ItemArray.Select(arg => arg.ToString())));
  return sb.ToString();
}

Tags:

C#

Create a Simple Windows Service to Send Daily Email with Dynamically Created .CSV Attachment

by 17. August 2011 10:28

The sample code below shows how to setup a simple Windows service that will send a daily email with a dynamically generated .CSV file (built by querying a SQL database).  After you compile the program you can using these commands to setup and delete the service (to update the service you will delete and re-install):

  • sc create MyServiceName binpath= "C:\PathToExecutable\Executable.exe"
  • sc delete MyServiceName
using System;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Net.Mail;
using System.ServiceProcess;
using System.Text;

namespace CrmRatesheetDistributionListEmailer
{
  public partial class Emailer : ServiceBase
  {
    public Emailer()
    {
      InitializeComponent();
    }

    protected override void OnStart(string[] args)
    {
      BackgroundWorker wkr = new BackgroundWorker();
      wkr.DoWork += DailyEmailManager;
      wkr.RunWorkerAsync();
    }

    private void DailyEmailManager(object sender, DoWorkEventArgs e)
    {
      DateTime lastRun = DateTime.MinValue;
      do
      {
        if (lastRun.DayOfYear.Equals(DateTime.Today.DayOfYear))
        {
          System.Threading.Thread.Sleep(60 * 1000);
          continue;
        }
        lastRun = DateTime.Today;
        SmtpClient mail = new SmtpClient("mailrelay.mydomain.com");
        MailMessage msg = new MailMessage("fromme@mydomain.com", "toyou@yourdomain.com", "Sample Daily Email", "This is a sample windows service that will send a daily email.");
        msg.CC.Add(new MailAddress("someoneelse@yourdomain.com"));
        msg.Attachments.Add(new Attachment(GetAttachment()));
        mail.Send(msg);
      } while (true);
    }

    private string GetAttachment()
    {
      SqlConnection cn = new SqlConnection("Data Source=ServerName;Initial Catalog=DatabaseName;Integrated Security=true;");
      SqlCommand cmd = new SqlCommand("select * from SomeTable where SomeCritera = true", cn);
      DataTable tbl = new DataTable();
      SqlDataAdapter da = new SqlDataAdapter(cmd);
      da.Fill(tbl);
      string fileName = "c:\\temp\\SomeFileName.csv";
      System.IO.StreamWriter file = new System.IO.StreamWriter(fileName);
      file.Write(TableToCSV(tbl));
      file.Close();
      return fileName;
    }

    private static string TableToCSV(DataTable table)
    {
      var result = new StringBuilder();
      for (int i = 0; i < table.Columns.Count; i++)
      {
        result.Append(table.Columns[i].ColumnName);
        result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
      }
      foreach (DataRow row in table.Rows)
      {
        for (int i = 0; i < table.Columns.Count; i++)
        {
          result.Append(row[i].ToString());
          result.Append(i == table.Columns.Count - 1 ? "\n" : ",");
        }
      } return result.ToString();
    }

    protected override void OnStop()
    {
    }
  }
}

Tags:

C#

Customize MS CRM Marketing List Members Default View

by 7. July 2011 15:25

I wanted to customize the Marketing List Members default view, specifically just to add the EMail address column.  The default view was originally three columns: Full Name, Business Phone and Address 1: City.  I assumed this would be accomplished by modifying the Contact entity; specifically the "Contact Associated View".  When I opened that view it did in fact seem to match the Marketing List Members default view; however, after modifying and publishing the Contact Assoiated View, the Marketing List Members view was unaffected.  Upon further inspection I noticed the icon of the Marketing List Members was different than that of the Contacts which led me to believe that I was working with the correct entity.  However, I could not find any entity in the Customize Entities screen that had th same unique icon as the Marketing List Members.  As it turns out although you cannot modify the Marketing List Members default view through the Customize Entities screen, there is a workaround that will allow you to customize it. 

Follow the steps below:

  1. From the main CRM screen perform an "Advanced Find".
  2. In the "Look for:" dropdown select "View".
  3. In the details section dropdown select "View" from the "Fields" section of the dropdown values.
  4. Set the operator to "Equals" (which should be the default).
  5. In the "Enter Value" field type "All Members" and/or select from the magnifier button pop-up screen.  NOTE: there may be more than one "All Members" (in my case there were three), so make sure to select all of them.
  6. Click the "Find" button.
  7. Double-click the result rows (one at a time) and modify the view when it opens.
  8. Click "Save and Close", repeat as necessary for each of the views.
  9. IMPORTANT: The changes you made will not be visible until you go back to the Customize Entities screen and select "More Actions" > "Publish All Customizations" from the menu at the top of the entity list.

Tags:

MS CRM