Saar Carmi

A .NET Blog

<October 2008>
SuMoTuWeThFrSa
2829301234
567891011
12131415161718
19202122232425
2627282930311
2345678


Navigation

Subscriptions

Post Categories



Team System - how to get tf.exe install folder ?

You can find tf.exe under Visual Studio IDE folder, which is specified under the key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0

value name: InstallDir

So far it seems that the install dir is written to the registry even if only the TFC is installed.

posted Monday, March 20, 2006 2:48 AM by saarc with 0 Comments

Calling from .Net 1.1 to .Net 2.0

Hi

A process cannot load both .net frameworks 1.1 & 2.0.

Therefore, to call 2.0 object from a 1.1 object, you must have a cross process call. One of the ways (but not the only) to do so, is to host the 2.0 object within COM+ process and expose it as a COM object. To do so, your object must derive Serviced Component and be marked as ComVisible.

Here is a simple example.

Save this as SimpleClient.cs

using System;
using System.Reflection;

public class SimpleClient
{
 public static void Main()
 {
  Type t = Type.GetTypeFromProgID ("MyObject");
  System.Diagnostics.Debug.Assert (t != null);
 
  object o = Activator.CreateInstance(t);
  Console.WriteLine (Environment.Version.ToString());
  t.InvokeMember ("Increment", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Instance, null, o, new object[0]);
  
 }
}

Save this as MyObject.cs

using System;
using System.Reflection;
using System.EnterpriseServices;
using System.Runtime.InteropServices;

[assembly: ApplicationActivationAttribute(ActivationOption.Server)]
[assembly: ApplicationName ("MyObject")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: ApplicationAccessControl(false)]

[System.Runtime.InteropServices.ComVisible (true)]
[Guid("65D66FCF-997E-4737-896D-60EEC0AF0E88")]
public class MyObject : ServicedComponent
{
 public void Increment ()
 {
  
  System.Windows.Forms.MessageBox.Show("COM CALL - " + Environment.Version.ToString());
 }
}

Create an snk file using the command "sn -k snk.snk"

Complie & register both source files with the following command lines:

"c:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\csc" SimpleClient.cs
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\csc" /t:library MyObject.cs /keyfile:snk.snk
"c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\regsvcs" MyObject.dll

 

 

posted Monday, February 27, 2006 2:49 PM by saarc with 0 Comments

Decimal Percision - short code, strange problem

http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_frm/thread/867f655285c0e04d/8a59fb7d2904c775?tvc=1&q=saar+decimal#8a59fb7d2904c775Could anyone help me to understand why in the following code sum1 is different from sum2?
Basically it's the same calculation done. Keep in mind the x is 28 digits so it's within the range of decimal.


decimal  x = (-0.0084682975822291150192357277M);
decimal sum1 , sum2;

sum2 = (3500.91M * x) + (x * 3500M + 822m);
sum1 = (3500.91M * x) + (x * 3500M) + 822m;

Console.WriteLine (sum1);
Console.WriteLine (sum2);

------------

Well, the reason is that the decimal type precision s not 28 right to the decimal digit, but 28 digits overall. Thanks for those who answered.

posted Monday, February 06, 2006 12:37 PM by saarc with 0 Comments

Singletons and inheritance

Jon Skeet posted an example of Singletons and inheritance.

What do you think about this generic singleton solution? This way you dont have to update the factory method with each subclass creation. It would be neater if the new generics' constraint would support parameters, but you can overcome it with abstract method CreateInstance which returns T.

abstract class DataProvider<T> where T: new()
   {
        private static T mInstance = new T();

        public T Instance
        {
            get
            {
                return mInstance;
            }
        }

        public abstract void Connect();
    }

    class Oracle : DataProvider<Oracle>
    {
        public override void Connect()
        {
            Console.WriteLine ("Connecting to Oracle");
        }
    }

    class SqlServer : DataProvider<Oracle>
    {
        public override void Connect()
        {
            Console.WriteLine ("Connecting to Sql Server");
        }
    }

posted Monday, February 06, 2006 12:31 PM by saarc with 0 Comments

MHO about ANTS

Hi

I have been using ANTS profiler for a while.
There are 3 bullets I must say.

1. I find the new interface very inconvenite:
 In the hierarchy view, the windows of the called methods and caller methods
 should be placed one above the other and not side by side to allow better
 view of methods with long names.
 
2. The source view must have a Reload button. If you switch to source view
and the ANTS cannot find the source code file, it shows a File Open dialog.
If you accidently press Esc, the is no way to get back to this dialog, unless you
restart ANTS.

3. If A calls C and B calls C, when you look in the hierarchy window for methods A calls,
you see the full cost of C (i.e. calls from A and from C). Why do you have
to switch to source code window to see the specific cost of calling C from A?

 

posted Friday, July 29, 2005 10:35 AM by saarc with 0 Comments

Late bound event registration via reflection

I was asked how to register to an event via reflection.

It is described here

posted Wednesday, February 23, 2005 1:40 PM by saarc with 7 Comments

Reactivating the IntelliSense (Code Completion) - after using Resharper

Reactivating the IntelliSense (Code Completion) after disabling Resharper

I recently installed the Resharper trail version.
When the trail version expires and does not complete the code statement, Visual Studio 2003 does not automatically shows the code completion options instead.

To reactivate the code completion – go to:
Tools mean -> Options -> Text Editor -> C#

and check the first three checkboxes on the right pane.

posted Tuesday, February 15, 2005 7:36 AM by saarc with 6 Comments

Server GC configuration

In .Net Framework 1.1 SP1, the server GC is supported for any type of application by setting the

<gcserver enabled="true"/>

setting in the applications configuration file


In 1.1 only ASP.NET and COM+ application used the Server GC by default. (on multi processors machines).  

In 1.1 SP1, you can use the gcserver flag.

 

It is NOT recommended nor supported to implement your own host.

posted Tuesday, February 15, 2005 3:27 AM by saarc with 4 Comments

Regsvcs error - "Insufficient state to deserialize the object. More information is needed"

While you run Regsvcs you might get a message saying:

An unknown exception occurred during installation:

1: System.Runtime.Serialization.SerializationException - Insufficient state to deserialize the object.  More information is needed.

This might occur because the assembly you are trying to register references another assembly that is missing (could be a versioning problem)

You can use Fusion Log Viewer to determine which assembly is missing.

---

You can also get this message in other situations which are not related to Regsvcs.

posted Monday, February 14, 2005 6:03 AM by saarc with 4 Comments

Determine whether someone is registered on event

A friend of mine asked me how would he determine whether a someone is registered on event of a another class.

If you want to check it from inside the class that defines the event, that's pretty easy - just check if the event field is not null.

But, if you want to do it from out side (without having the option to recompile the class that publishes the event),  the C# compiler does not let you compile that code. The only way I found to do it, is by using Reflection

Pay attention this is BAD CODING - you are not allowed to access private fields of other classes.

<code>
using System;
using System.Reflection;
using System.Windows.Forms;

public class A
{
 public event EventHandler MyEvent;
 public void AB()
 {
  if (MyEvent!= null) //compiles
  {}
 }

}

public class B
{
 public static void MyEventHandler (object source, EventArgs args)
 {}
 public static void Main()
 {
  A a = new A();
  //if (MyEvent!= null) //compilation error
 {}

  IsRegistered (a);
  
  a.MyEvent += new EventHandler (MyEventHandler);
  IsRegistered (a);
 }

 private static void IsRegistered (A a)
 {
  Type t = a.GetType();
  FieldInfo fld =t.GetField ("MyEvent", BindingFlags.NonPublic  | BindingFlags.Instance);
  System.Diagnostics.Debug.Assert (fld != null);
  
  Object o = fld.GetValue (a);
  System.Diagnostics.Debug.Assert (o != null);
  
  EventHandler eh = (EventHandler)o;
  if (eh == null)
  {
   Console.WriteLine ("no one is registerd");
  }
  else
  {
   Console.WriteLine ("still registered");
  }
 }
}


<code>

posted Wednesday, December 22, 2004 9:01 AM by saarc with 5 Comments

Setting IIS to support Windows Authentication and Content Expiration by code

I was wondering how to set the IIS virtual directory to Windows Authentication during the application install time.

Well, here is the code snip.

 

Using System.DirectoryServices;

const int MD_AUTH_NT = 0x00000004; //Windows authentication schemes available.

DirectoryEntry folderRoot = new DirectoryEntry("IIS://localhost/W3SVC/1/Root/" + virutalDirecty);

folderRoot.RefreshCache();

folderRoot.Properties["AuthFlags"].Value = MD_AUTH_NT; //Windows authentication

folderRoot.Properties["HttpExpires"].Value = "D, 86400"; //Content expiration after 1 day

folderRoot.CommitChanges();

}

posted Monday, November 29, 2004 2:32 AM by saarc with 6 Comments

ReaderWriterLock - Acquire lock with infinite timeout

The documantion of the methods AcquireReaderLock and AcquireWriteLock do not include information about how to get infinite timeout.

The information is available in the class's documentation.

Anyway, you can use the value Timeout.Infinite (== -1) for infinite timeout.

 

 

posted Tuesday, October 19, 2004 1:50 AM by saarc with 7 Comments

Binary Serialization of DataSets in .Net Framework 2.0

I read Dino Esposito's article about Binary Serialization of DataSets In ADO.NET 2.0.

DataSet serialization is a real pain in the .Net Framework 1.1.

I made a test to check the size and time it take to serialize a DataSet.
The test included memory serialization of the a DataSet with one table and 20,000 rows.

I tested the serialization with inserted rows.

The tests used BinaryFormatter and was run on framework version 2.0.40607.85.

Here are the results:

.Net framework 1.1
5,220,304 bytes , about 14.3 seconds

.Net framework 2.0 with RemotingFormatter = SerializationFormat.Xml :
 5,800,442 bytes , about 13 seconds

.Net framework 2.0 with RemotingFormatter = SerializationFormat.Binary :
 1,727,292 bytes , about 1 minutes and 18 seconds


------

It seems that SerializationFormat indeed saves network traffic, but the problem is that it take too much time to create the serialization stream. There was no real performance change with unchanged rows (after calling to AcceptChanges).

Do I miss anything?

Here is the test code:

using System;

using System.Data;

using System.IO;

using System.Runtime.Serialization;

using System.Runtime.Serialization.Formatters.Binary;

class Class1

{

[STAThread]

static void Main(string[] args)

{

//Create a dataset with a scheme

DataSet ds = new DataSet();

DataTable tbl = ds.Tables.Add ("tbl");

tbl.Columns.Add ("a", typeof(int));

tbl.Columns.Add ("b", typeof(int));

tbl.Columns.Add ("c", typeof(string));

tbl.Columns.Add ("d", typeof(int));

tbl.Columns.Add ("e", typeof(int));

tbl.Columns.Add ("f", typeof(string));

tbl.Columns.Add ("g", typeof(Byte));

tbl.Columns.Add ("y", typeof(int));

tbl.Columns.Add ("i", typeof(int));

tbl.Columns.Add ("j", typeof(string));

tbl.Columns.Add ("k", typeof(int));

tbl.Columns.Add ("l", typeof(int));

tbl.Columns.Add ("m", typeof(string));

tbl.Columns.Add ("n", typeof(int));

tbl.Columns.Add ("o", typeof(string));

tbl.Columns.Add ("p", typeof(DateTime));

tbl.Columns.Add ("q", typeof(DateTime));

ds.RemotingFormat = SerializationFormat.Xml;

//Load rows into dataset

for (int i = 0; i < 20000; i++)

{

ds.Tables["tbl"].Rows.Add (new object[] {

0,1,"a",2,3,"ab",4,5,6,7,8,9,10,11,"abcd",DateTime.Now,DateTime.Now});

}

MemoryStream ms;

BinaryFormatter bf = new BinaryFormatter();

//Record the start time

DateTime s = DateTime.Now;

for (int i = 0; i < 10; i++)

{

//Serialize the dataset into memory

using (ms = new MemoryStream())

{

bf.Serialize (ms, ds);

Console.WriteLine (ms.Position);

}

}

//Record the end time

DateTime e = DateTime.Now;

Console.WriteLine (e-s);

Console.WriteLine (System.Environment.Version.ToString());

}

}

posted Monday, September 20, 2004 4:52 AM by saarc with 3 Comments

Microsoft .Net on the Beach

Microsoft Israel is having another .Net event.

I'll be there.

 

posted Wednesday, September 08, 2004 2:28 PM by saarc with 5 Comments

GetCurrentProcess - Performance Issue

I used the following code line to get the process name. (Our application calls that line once in each execution).
System.Diagnostics.Process.GetCurrentProcess().ProcessName

Out client installed the application on two machines:
This first one is Compaq dual process. It takes about 0.3 seconds to run that line.

The other machine is a 4 CPU partition of Unisys machine. On that machine it takes between 1 to 50 seconds to execute that code.

I could find what causes that difference.

posted Sunday, September 05, 2004 11:27 AM by saarc with 6 Comments

.Net Framework Service Pack - Installation Error

Wow!

This must be a beta version.

They probably know why it isn't published on their main web page yet.

The setup crashes with Object Null Reference Exception when trying to register something with Regsvcs.

 

posted Wednesday, September 01, 2004 11:52 PM by saarc with 6 Comments

.NET Framework 1.1 (RTM?) is available for download

You can find .NET Framework 1.1 Service Pack 1 at following link

I think it's RTM version.

There is a different version for Windows 2003 server

posted Wednesday, September 01, 2004 10:46 PM by saarc with 5 Comments

Visual Studio error - "Could not instantiate the resource processor"

If you get the error “Could not instantiate the resource processor” when trying to build a project with .resx file, you should need to reinstall the .Net framework.

Other symptoms of the problem could be missing empty Toolbox, problems with the Project Properties window (or the Solution Properties) – not showing the properties as usual.

 To reinstall the .Net framework locate the dotnetfx.exe file in the installation source and run the command:

dotnetfx.exe /t:%temp% /c:"msiexec.exe /fvecms %temp%\netfx.msi"

For more information look in the file C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\1033\repairRedist.htm on local hard drive.

posted Monday, August 30, 2004 4:03 AM by saarc with 7 Comments

Custom action within installer - Could not find MyAction.Installstate

I wanted to run custom action code during the Commit phase of the Setup Project.

I created an installer class and override the Commit method. I also added that installer as a custom action to the Commit phase (View->Custom Actions).

During the installation process I got an exception saying “Could not find C:\Program Files\MyApp\MyAction.Installstate”

The problem is that the MSI infrastructure  is looking for the installation state file which is usually created during the Install phase. If the custom action does not participate in the Install phase, no file is created.

The solution is to add the custom action to both the Install and the Commit phases, although it does nothing during the install phase.

posted Thursday, August 26, 2004 7:21 AM by saarc with 5 Comments

Adding System Environment Value Using the Installer Project

If you want to add a system environment variable with the installer project, you can do by adding the key to direct location in the registry.
You should create a registry value under the key HKEY_LOCAL_Machine\System\CurrentControlSet\Control\Session Manager\Environment .
The value's name is the variables name.

Pay attention that after doing this the Windows Explorer does not read the new system environment value until you logoff. This means that your application will not get that system variable if it is executed just after the installation process.

To propagate the environment variables changes to the system you can add a Custom Action to your installer project and call the attached code. Pay attention that you need to call it during the Commit process – to make sure the installer already added the key to the registry.


public const int HWND_BROADCAST = 0xffff;
public const int WM_SETTINGCHANGE = 0x001A;
public const int SMTO_NORMAL = 0x0000;
public const int SMTO_BLOCK = 0x0001;
public const int SMTO_ABORTIFHUNG = 0x0002;
public const int SMTO_NOTIMEOUTIFNOTHUNG = 0x0008;

[DllImport("user32.dll", CharSet=CharSet.Auto, SetLastError=true)]
[return:MarshalAs(UnmanagedType.Bool)]
public static extern bool
  SendMessageTimeout(
  IntPtr hWnd,
  int Msg,
  int wParam,
  string lParam,
  int fuFlags,
  int uTimeout,
  out int lpdwResult
);

private void BroadCast()
{
 try
 {
  const int SomeTimeoutValue = 1000;
  int result;
  SendMessageTimeout( (System.IntPtr)HWND_BROADCAST,
   WM_SETTINGCHANGE,0,"Environment",SMTO_BLOCK | SMTO_ABORTIFHUNG |
   SMTO_NOTIMEOUTIFNOTHUNG, SomeTimeoutValue, out result);
 }
 catch (Exception ex)
 {
  System.Diagnostics.Trace.WriteLine ("Could not broadcast");
  Throw;
 }
}


 

posted Thursday, August 26, 2004 7:00 AM by saarc with 8 Comments




Powered by Dot Net Junkies, by Telligent Systems