.Net
.Net
I was asked how to register to an event via reflection.
It is described here
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.
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.
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.
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>
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();
}
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.
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());
}
}
Microsoft Israel is having another .Net event.
I'll be there.
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.
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.
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
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.
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.
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;
}
}
I really like the DSWatch adding. It let you to view a dataset at debug time in a nice visual form.
The problem of the DSWatch is that it uses GetXml. This means that the form shows a different instance of the dataset. That is the reason why you cannot edit the data through that form.
I was wondering how to get a real pointer to the original dataset at debug time. Maybe the solution is a debugger extension.
Isn't it a lot of work? Interesting indeed.
Service pack 1 for .Net Framework 1.0 & Service pack 3 for .Net Framework 1.0 will be avilable soon.
Information can be found here
There are many changes but most of them still dont have description.
----
Finally layout problems in Inherited User Control will be fixed