Software design and other ramblings RSS 2.0
# Friday, 22 June 2012

Friday, 22 June 2012 11:43:52 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Thursday, 07 May 2009

I had an issue today with installing assemblies into the GAC through installshield. My installer has several components configured with a Destination of [GlobalAssemblyCache] which is the recommended way of performing a GacUtil through installshield. Now previously, the ".NET Scan at Build" property for these components had been set to "Dependencies and Properties" and everything worked fine. Recently we have been updating the installers to work for 64 bit installations (managed by altering the ISM as part of our build process). As a result of this I had to remove the dependancy scan as this was causing issues on 64 bit servers. I set this field to "None" and soon found that all the assemblies I had targeted at the GAC ended up on the root of the install drive (i.e. c:\) instead of in the GAC :o

Anyway, I eventually managed to solve this issue by setting the ".NET Scan at Build" property to "Properties Only". It seems that this has to be set for GACed assemblies as it causes the MsiAssembly table to be populated.

Hope this helps anyone else with similar issues.

Thursday, 07 May 2009 17:00:58 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
Installshield
# Wednesday, 06 May 2009

I've seen a few newsgroups with SSIS developers having difficulties enlisting in the active transaction with a custom Data Flow component in .NET. I recently had to do this to enable message queue operations to be performed within the active transaction for the package. Unfortunately the built in Message Queue task has no support for enlisting in the active transaction so a custom approach was required. I'm sure that most SSIS developers who have dabbled with custom components will have seen the following Microsoft.SqlServer.Dts.Pipeline.PipelineComponent class:

/// <summary>
/// Establishes a connection to a connection manager
/// </summary>
public virtual void AcquireConnections (object transaction)

This method can be overriden a custom component and used to establish any required connections. Now we know that SSIS uses DTC transactions and that MSMQ supports DTC but how do the two map together? What is the transaction object that we are passed in? There seems to be very little documentation on this subject available on the internet so I experimented with the debugger and found a way to map this through to .NET. The first stage is to convert the supplied object into a managed System.Transactions.Transaction object. This can be achieved with the following code:

/// <summary>
/// Get a <code>System.Transactions.Transaction</code> from a supplied COM transaction pointer
/// </summary>
public static Transaction GetTransactionFromCom(object comTransaction)
{
    Transaction managedTransaction = null;

    ITransaction transactionInterface = comTransaction as ITransaction;

    if (transactionInterface != null)
    {
        managedTransaction =
            TransactionInterop.GetTransactionFromDtcTransaction((IDtcTransaction)transactionInterface);
    }

    return managedTransaction;
}

Once the supplied COM transaction pointer has been converted to a managed Transaction object it can be used as normal with your .NET code. For message queue transactions this means setting the ambient transaction and sending/receiving messages using MessageQueueTransactionType.Automatic. For example:

// Save the current transaction
Transaction previousTransaction = Transaction.Current;

// Set the current ambient transaction
Transaction.Current = managedTransaction;

try
{
    using (MessageQueue queue = new MessageQueue(messageQueuePath))
    {
        queue.Send("Body", "Label", MessageQueueTransactionType.Automatic);
    }
}
finally
{
    Transaction.Current = previousTransaction;
}
Wednesday, 06 May 2009 21:04:57 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | C#

I recently needed to access the Label property of a remote private MSMQ through .NET. Naturally my first thought was that this should be a pretty trivial operation as this property is exposed via the MessageQueue (System.Messaging) class in the .NET framework. Unfortunately however, this property can only be read for local private queues (those on the same machine as the executing code) not for remote private queues. According to Microsoft "Private queues are registered on the local computer, not in the directory service, and their properties cannot be obtained by Message Queuing applications running on remote computers".

After a bit of testing, I found that it is possible to access remote private queue properties through .NET using DCOM. The following example shows how this can be achieved for the Label property. The same technique can be applied to retrieve other queue properties such as the Transactional state of the queue.

public static string GetRemoteQueueLabel(MessageQueue queue, string serverAddress)
{
    // Find label for remote private queue
    object queueInfoDcom = Activator.CreateInstance(Type.GetTypeFromProgID("MSMQ.MSMQQueueInfo", serverAdress));

    Type classType = queueInfoDcom.GetType();

    // Invoke method using reflection and return outputs
    BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.SetProperty;

    classType.InvokeMember("FormatName", bindingFlags, null, queueInfoDcom, new object[] { queue.FormatName });

    bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.InvokeMethod;

    classType.InvokeMember("Refresh", bindingFlags, null, queueInfoDcom, new object[] { });

    bindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.GetProperty;

    string label = (string)classType.InvokeMember("Label", bindingFlags, null, queueInfoDcom, new object[] { });

    return label;
}
Wednesday, 06 May 2009 20:37:55 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | C#
# Saturday, 02 May 2009

Just a quick blog to test the Mail To WebLog feature of DasBlog!



This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email

Saturday, 02 May 2009 13:23:49 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

# Sunday, 27 July 2008

Here was me thinking I'd escaped the complete ineptness of three mobile 5 years ago but unfortunately its back to haunt me! After closing my account back in December 2003 (and paying the remaining 6 months line rental up front to do so!) I've just recieved a letter from Lowell Portfolio indicating that they have been sold the outstounding debt of £20.07 that I owe on my three account. I was shocked to say the least! The account was fully closed and is marked as settled in my credit report. In addittion, i have never recieved any requests from 3 for this so-caled balance! I contacted three straight away and after being passed around one of their useless indian call centres no one could explain where this additional money had come from - but obviously its left to me to spend my time and money sorting this mess out.

Anyway, clearly the money isn't really the issue but I'm prepared to fight this issue on behalf of all the other ex-three customers out there who are probably being screwed in much the same way! If anyone's considering switching to three and has stumbled accross this site please take one piece of advice from me....

If you value your sanity - *never* enter into any dealings with this company. Their customer service is appauling. If one good thing can come out of this incident it's the hope that at least one potential customer will be swayed away from three by this post :o) Let me know if you've had any similar problems.

Sunday, 27 July 2008 18:57:32 (GMT Daylight Time, UTC+01:00)  #    Comments [1] -

# Wednesday, 02 July 2008

The other day I had to update a existing windows GUI application to enable it to be called via the command line. In order to do this, you need to add the following import to your .NET application (C# example shown):

/// <summary>
/// AttachConsole gives the ability for a GUI application to write to the console window of the console from which it was started.
/// </summary>
[System.Runtime.InteropServices.DllImport("kernel32.dll")]
static extern bool AttachConsole(uint dwProcessId);

/// <summary>
/// Flag indicating that we should attach to parent console
/// </summary>
const uint ATTACH_PARENT_PROCESS = 0x0ffffffff;

After adding these declarations to your main class, its a simple case of adapting your Main method to detect if you're running in console or GUI mode and acting accordingly. E.g:

/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main(string[] args)
{
     // Are we in console mode
     bool isConsole = args.Length > 0;

     if (!isConsole)
     {
          RunVisual();
     }
     else
     {
          // Attach to console
          AttachConsole(ATTACH_PARENT_PROCESS);

          // Run console app
          RunConsole(args);
     }
}
Wednesday, 02 July 2008 16:31:56 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -
.NET | C# | Software Development
# Saturday, 28 June 2008

Hi and welcome to scott-hill.co.uk.

After months of neglect I've decided to give the web site an overhaul and a brand new look. I've now migrated to dasBlog 2.1 and so far things are looking good. Some of my older articles won't be available from now on but I'll try and repost the most popular ones shortly.

Enjoy!

Saturday, 28 June 2008 09:50:54 (GMT Daylight Time, UTC+01:00)  #    Comments [0] -

Top Cashback
TopCashback
Archive
<2017 September>
SunMonTueWedThuFriSat
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567
About the author/Disclaimer

Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

© Copyright 2017 Scott Hill

Sign In
Statistics
Total Posts: 8
This Year: 0
This Month: 0
This Week: 0
Comments: 2
All Content © 2017, Scott Hill