torsten's .NET blog In the end, everything is a gag [Ch. Chaplin]
# Sunday, May 18, 2008
WebBrowser control hosting and build-in zoom: how to get it work again

You may have noticed the zoom keyboard shortcuts (CTRL+mouse wheel forward/back, CTRL+PLUS SIGN, and CTRL+MINUS SIGN) are not enabled by default when hosting the WebBrowser control if you have installed IE7, while it does without any problem with older IE versions. This was now an issue for a long time in RSS Bandit, that we couldn't fix. Yesterday I did a research again and found this page: MSDN about IZoomEvents. We already implemented the font size change using a menu (see KB 304103) but it offers not the same usability that you have with older IE x and loose if you switch from IEx to IE7 and run RSS Bandit. Now it works again like a charm and for your convenience I repeat the important part you have to apply in your own IE hosting code:

"To enable this behavior, call IWebBrowser2::ExecWB with OLECMDID_OPTICAL_ZOOM, passing 100 in pvaIn. Once set, the keyboard shortcuts remain available as long as the host navigates to HTML content because the same instance of MSHTML is used. However, if the host navigates to Active documents, such as XML or Portable Document Format (PDF) files, optical zoom is disabled and will need to be enabled again."

What the docs are not mention: you should call this at a time the hosted control is visible and fully initialized, or you will get wired COM exceptions...

Technorati tags:  |  |  | 
Sunday, May 18, 2008 12:50:20 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [2]  | 
# Friday, October 19, 2007
Get the local mapped network drives using WMI

Today I helped a coworker to get the local mapped network drives using WMI instead of COM Interop/native windows API. Just to keep the code as a reminder and help others with the same problem I provide it here.

The result of the code below is in general the same you will get if you hit the "net use" command at the windows command shell prompt. For further infos and reading I suggest http://msdn2.microsoft.com/en-us/library/aa394173.aspx (Win32_LogicalDisk; MSDN WMI Reference); for immediate results of query the WMI you should use Scriptomatic (download from http://www.microsoft.com/downloads/details.aspx?familyid=09DFC342-648B-4119-B7EB-783B0F7D1178&displaylang=en).

Little bit optimization is yet possible providing the drive type in the WQL as a where clause parameter, so here it is:

/// <summary>
/// Container for Share entries
/// </summary>
public struct SharePathEntry
{
  public string Name;
  public string Path;
  public SharePathEntry(string n, string p) {
    Name = n;
    Path = p;
  }
}

// for other types see: http://msdn2.microsoft.com/en-us/library/aa394173.aspx
const int NetworkDriveType = 4;

public static List<SharePathEntry> GetLocalShares()
{
  List<SharePathEntry> allLocalShares = new List<SharePathEntry>(); // a container

  WqlObjectQuery objectQuery = new WqlObjectQuery("select DriveType,DeviceID,ProviderName from Win32_LogicalDisk");
  ManagementScope scope = new ManagementScope(@"\\.\root\cimv2"); // local WMI namespace
  scope.Options.Impersonation = ImpersonationLevel.Impersonate;
  scope.Options.EnablePrivileges = true;
  ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, objectQuery);
  foreach (ManagementObject share in searcher.Get())
  {
    int driveType = Convert.ToInt32(share["DriveType"]);
    if (driveType == NetworkDriveType) {
      object objName = share["DeviceID"];
      object objPath = share["ProviderName"];
      if (null != objName && null != objPath)
      {
        allLocalShares.Add(new SharePathEntry(objName.ToString(), objPath.ToString()));
      }
    }
  }
  return allLocalShares;
}
Technorati tags:  |  | 
Friday, October 19, 2007 10:02:12 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Thursday, August 02, 2007
Make use of it: the portable Bandit

Is I wrote recently, I worked to get RSS Bandit running as a portable application. Now it is time to test it: you can download the ShadowCat Beta 2 release installer, then read how you get it done.

Technorati tags:  |  | 
Thursday, August 02, 2007 2:17:27 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [4]  | 
# Sunday, July 01, 2007
The portable Bandit

I read about portable apps (applications, that are running from a stick without any further installation) in my favourite magazine and it just took a hour to set the sources to get RSS Bandit running from a stick:

The Portable.Bandit

There is at least one issue left: the .NET framework must be installed at the machine running the portable Bandit...

Tomorrow I will walk to different machines to get it more tested.

Technorati tags:  |  | 
Sunday, July 01, 2007 7:28:05 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [6]  | 
# Tuesday, June 19, 2007
Avoid this.Handle != IntPtr.Zero checks!

Just because requesting the Handle (IntPtr, see remarks section) will create the handle internally in case it is IntPtr.Zero and may cause issues on disposing or closing! How to get around? Just use the this.IsHandleCreated property...

Technorati tags:  | 
Tuesday, June 19, 2007 6:30:12 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Wednesday, March 07, 2007
RSS Bandit and the 100% CPU issue

Today I could track down an annoying issue: on some installations of the newer version of RSS Bandit (starting with the first betas of 1.5.0.x) it starts using 100% CPU time on a thread. As we started also to use lucene.NET with this new release I guessed it was a related issue, I was right. But as we run into multiple issues with lucene it was not obvious as a separate problem. So here it is:

We used a slightly modified version of lucene.NET to include the available language dependent analyzers and stopword filters. Before we released, I already fixed some obvious issues I got with e.g. french stemmer. Now we got more with the CJK (Japanese/Korean, bug report) and possibly Chinese analyzers. It looks like it get into a state it never returns. The attached debug callstack was very helpful to got the direction to search for! I found this: TextReader.Read(char[], int, int) was called and the return value checked against -1 only, not against 0 (zero). So I run over all analyzers to find all the places I have to change that code and here it is: the modified lucene.net.dll (zipped, 142K).

To all users that run into the problem: can you test the modification, please? Just download, unzip into the installation folder, restart Bandit. Please report here (or as comments to the bug reports mentioned above) if it help - so we can refresh the installer for the major public.

Technorati tags:  | 
Wednesday, March 07, 2007 12:59:08 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [22]  | 
# Tuesday, February 20, 2007
.NET Issue with Vista icons

Today I stumbled over a wired issue in both VS.IDE 2003 and VS.IDE 2005: they did not compiled my project anymore! Error was:

Compiler Error CS1583 (CSC583.tmp is not a valid Win32 resource ...

I just refreshed the french resources, so my first thought was it also caused that error, but I'm wrong. Just before this change I fixed a issue with our Vista Icon - added more ico image resolutions - and also a 256x256 Vista compressed image. What I forgot: I did not compiled after the icon change! All the google'd answers did not matched my case. I simply removed the 256x256 icon image - then it compiled successfully!

So my question is: how do I compile a .NET application with a Vista compressed icon? Do I have to compile under Vista? But how about VS 2003?

Technorati tags:  |  | 
Tuesday, February 20, 2007 7:14:50 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [4]  | 
# Friday, December 01, 2006
Strange XSL Transform Exception - figured out

Recently we migrated our software dev. to use CLR 2.0. One part of the migration was to rework the usage of XslTransform class to the new XslCompiledTransform class. Reading the "Migrating From the XslTransform class" MSDN paper, it was not much work, just minutes. But then I got this strange exception:

Cannot transform XML using stylesheet 'transform.xslt.'
Exception: Extension function parameters or return values which have Clr type 'ConcatString' are not supported.

This really took me a half day to track it down! First, I did the usual things like reading more carefully the MSDN docs (my wrong direction: security issues), google'd for it and found at least one topic about. This was the right direction to solve it, but I tried various other things to get around - inclusive a complete redesign of the transformation code not using any stylesheet scripts. At last I was more confused (introduced other errors) than as I started, so I reverted the most unrelated changes. After reading the more interesting post "Introducing XslCompiledTransform" and IM'ed with a OS project coworker it gets more clear to me what happens: the System.Xml.Xsl.Runtime.XmlQueryRuntime.ChangeTypeXsltResult(XmlQueryType xmlType, Object value) visible in the call stack try to make my <msxsl:script language="JScript" ...> functions to return strong types - but: only the top level functions called from XSL element! Here is the non-working stylesheet code sample:

<msxsl:script language="JScript" implements-prefix="local"><![CDATA[
   
    function fmtDate(val, fmtmask)
    {

   var s = "" + val; 
   ...
   return formatDate(new Date(s.substring(0,4),s.substring(4,6)-1,s.substring(6,8)), fmtmask);
    }
    function formatDate(varDate, bstrFormat)
    {
...
return "" + formattedDate;
}
]]></msxsl:script>

And this is the working one:

<msxsl:script language="JScript" implements-prefix="local"><![CDATA[
   
    function fmtDate(val, fmtmask)
    {

   var s = "" + val; 
   ...
   return "" + formatDate(new Date(s.substring(0,4),s.substring(4,6)-1,s.substring(6,8)), fmtmask);
    }
    function formatDate(varDate, bstrFormat)
    {
...
return "" + formattedDate;
}
]]></msxsl:script>

You notice the small but important difference? Now the stylesheet compiler consider my return value correctly as a string. Whoa...

Technorati tags:  | 
Friday, December 01, 2006 8:58:49 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [1]  | 
# Tuesday, September 19, 2006
BASTA! 2006

I'm now again at BASTA! 2006, Mainz - Germany. Had alreda some interesting discussions here with some of the speakers, also the SOA architecture day yesterday was very interesting. Lesson learned: SOA is not really new, and it is not a technology. Just a idea to live.

Most interesting session today was about advanced debugging, by Ingo Rammer. He introduced some tools I never heard of and pointed out how to catch the most often issues debugging is used for, such as memory leaks in Windows Forms applications, or how to debug a CLR windows service. We had look inside WinDbg - what a cryptic tool, just remembered my time using the vi/unix years ago...

Most impressive was the keynote by Jason Zanders the "father of .NET Framework 3.0" today: about .NET Framework 3.0 and Vista. Live programming on Vista (RC) in Python using CLR 3.0, WPF and speech support (build in in CLR 3.0). Just one issue: the presentation machine with the slides just stopped working and required a (live) reboot. Lesson to learn: don't use beta software to just show slides ;-)

Technorati tags:  |  |  | 
Tuesday, September 19, 2006 1:02:16 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Saturday, March 25, 2006
Update: DiffPatchResources creates .strings file(s)

As I yet posted this is a little tool to help with common tasks to maintain resource files. Recently I started to use the famous StringResourceTool MS used within the Enterprise Library and it is way cool! Worth to have a look if you start a new project from scratch.
But stop! You can now migrate existing project(s) to use the the StringResourceTool by the little help of the DiffPatchResources tool! Just download and copy it to a folder you configured to be found if you start a windows command line (%PATH% variable). Then use the new option -s to create the .strings file out of your existing main .resx file and save all the hand writings...

Update: to get the StringResourceTool run in VSIDE 8.0, add these settings to your registry by help of a .reg file with content:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\VisualStudio\8.0\Generators\{FAE04EC1-301F-11D3-BF4B-00C04F79EFBC}\StringResourceTool]
"CLSID"="{1D47CA76-5AF1-4152-8106-08140FF9886E}"
"GeneratesDesignTimeSource"=dword:00000001
@="Microsoft Data Warehouse String Resource Generator"

Technorati tags:  | 
Saturday, March 25, 2006 5:12:31 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [3]  | 
# Friday, March 03, 2006
Enterprise Library - Syslog Sink Extension available for download
My user sample related to the Enterprise Library is now up and available for download. It extends the logging by providing a sink that is able to log to a syslog daemon (some of you may know that from UNIX systems). It works  according to the definitions in RFC 3164 (http://www.faqs.org/rfcs/rfc3164.html) writing log entries to UDP port 514. Not yet optimized for speed and no EntLib Configuration Console support, but a starting point. Binaries, a short documentation and source can you find here.
Technorati tags:  | 
Friday, March 03, 2006 3:28:14 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [1]  | 
# Saturday, January 07, 2006
Remoting from CLR 1.1 to 2.0 and back: issue 1

This week I had a hard day to track down a remoting issue we had with our product. We have a application service running (Windows Service or Console Window for tests) under CLR 1.1 and a ASP.NET 2.0 application want to call the service. After figuring out an issue with a third party software component I got another exception: "Serialization Error: Unknown member TextInfo". I'm talking about remoting serialization of function parameters and return values, not using/calling any formatter like SOAP. Diving into the problem analysis I found our software never uses such a member and so I examined a involved CLR class that member is part of using reflector: the CaseInsensitiveHashCodeProvider class used indirectly by an own collection inherited from NameObjectCollectionBase. I know MS worked hard to get the old style collections compatible to the new implementations using Generics and new approaches and so it is with that base collection. It is mentioned at the .NET 2.0 obsolete type/member list the collection is using a new preferred constructor with the IEqualityComparer parameter and they wrap up the old style HashCodeProvider and Comparer with a internal class named CompatibleComparer.

Knowing all that now I had to find a way to get around the serialization exception. It happens the moment the CLR 1.1 running at the app service try to deserialize the CLR 2.0 serialized collection. I started to create some experimental own HashCodeProvider classes and one that worked recently had the original (don't change the semantic!) CaseInsensitiveHashCodeProvider hold as a non-serialized member and just serialized the CultureInfo.Name to be able to re-create it on creation/deserialization implementing ISerializable and IDeserializationCallback to set the private members ("_hashProvider" and "_comparer" using reflection - they can only be set via the costructor!) of NameObjectCollectionBase. We had to replace the Comparer also, because after it serialized/deserialized our migratable HashCodeProvider successfully we got another wired exception we had to workaround by a homebrewed Comparer class implemented similar to our HashCodeProvider class.

Now it works fine. What we learned? Also MS don't keep in mind to consider also internal classes to provide backward compatible serialization formats. They used only the code attribute "Serializable" and don't implement ISerializable to explicitly get compatible serialization. I expect to get more issues like this... :-(

Update: It looks like the new cool feature named VTS (version tolerant serialization) will not work for Net.Remoting, isn't it?

Technorati tags:  | 
Saturday, January 07, 2006 2:34:02 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [1]  | 
# Tuesday, October 25, 2005
1.3.0.36 Alpha and AdsBlocker HowTo

We decided to post another iteration of the Rss Bandit Alpha (v1.3.0.36): read about the details at Dare Obasanjo's blog and download it here.

It is the first version that is AddIn - enabled and you can find and use the first AddIn available here: AdsBlocker. So how to use it?

  1. Download and unzip to a folder you like (e.g. "AddIns" sub-folder within your Bandit installation path).
  2. Start Bandit and open the AddIns dialog via Tools|AddIns... menu.
  3. Press the "Add..." button and select the AdsBlocker.AddIn.dll
  4. Press "Close"
  5. Optional: add entries/modify the ads.blacklist.txt file (regular expressions) to configure your blocked content (urls)
  6. Optional: create a white list "ads.whitelist.txt" in the same location if your blacklist gets large and you want to re-enable some blocked content.

 

Technorati tags:  |  |  | 
Tuesday, October 25, 2005 6:59:45 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [4]  | 
# Tuesday, September 27, 2005
More to know about .NET Timers

As you may know, .NET 1.1 supports three different Timer classes:

  1. Windows timers with the System.Windows.Forms.Timer class
  2. Periodical delegate calling with System.Threading.Timer class
  3. Exact timing with the System.Timers.Timer class

The timings are more or less accurate (see CodeProject: Multithreading in .NET), but that is not the point I want to highlight today. Two sentences from the mentioned codeproject article are important for this post:

"... Events raised from the windows forms timer go through the message pump (together with all mouse events and UI update messages)..."

and

"...the System.Timers.Timer class. It represents server-based timer ticks for maximum accuracy. Ticks are generated outside of our process..."

To report state and newly retrieved items from requested feeds we used a concept to serialize the asynchronous received results from background threads with the help of a timer. This was introduced in the NightCrawler Alpha Dare Obasanjo posted last week for external tests. Some users reported strange failures, memory hog up and bad UI behavior with this Alpha so I would suggest here to not use it anymore for testing if your subscribed feeds count is higher than 20 or 30 feeds.

The idea was not as bad as it seems to be (if you only look at the issues above). The real issue in our case was to use simply the wrong timer class! The UI state refresh includes an update of the unread counters that is reported to the user within the treeview as number postfixes and (more important here) a font refresh (as user decides, default is to mark the feed caption text bold). Have a look to the constructor of the class we used for background thread result processing:

    1 public ThreadResultManager(RssBanditApplication owner, ISynchronizeInvoke syncObject) {

    2       this.owner = owner;

    3       resultInfos = PriorityQueue.Synchronize(new PriorityQueue());

    4 

    5       // what we catch on:

    6       this.owner.FeedHandler.UpdateFeedStarted += new NewsHandler.UpdateFeedStartedHandler(this.OnUpdateFeedStarted);

    7       this.owner.FeedHandler.OnUpdatedFeed += new NewsHandler.UpdatedFeedCallback(this.OnUpdatedFeed);

    8       this.owner.FeedHandler.OnUpdateFeedException += new NewsHandler.UpdateFeedExceptionCallback(this.OnUpdateFeedException);

    9 

   10       processResult = new System.Timers.Timer(250);

   11       processResult.Elapsed += new System.Timers.ElapsedEventHandler(OnProcessResultElapsed);

   12       processResult.SynchronizingObject = syncObject;

   13       processResult.Start();

   14     }

As you can see in line 10 we used the System.Timers.Timer class. The syncObject parameter is (as you can guess) the main form.

So what happens exactly now if the timer fires? I used the CLR Profiler to get the following exiting results. The event is called in sync. with the SynchronizingObject, means Control::WndProc(m) calls calls into System.Windows.Forms.Control::InvokeMarshaledCallbacks void(), MulticastDelegate::DynamicInvokeImpl()... and then our event method OnProcessResultElapsed(). The allocation graph mentions 101 MB (44.78%) used here! Here is the implementation:

   20 private void OnProcessResultElapsed(object sender, System.Timers.ElapsedEventArgs e) {

   21       // get them out of the resultInfos list and deliver

   22       if (resultInfos.Count > 0) {

   23         ThreadResultInfo t = (ThreadResultInfo)resultInfos.Dequeue();

   24         if (t.Args is NewsHandler.UpdateFeedEventArgs) {

   25           this.owner.OnUpdateFeedStarted(t.sender, (NewsHandler.UpdateFeedEventArgs)t.Args);

   26         } else if (t.Args is NewsHandler.UpdatedFeedEventArgs) {

   27           this.owner.OnUpdatedFeed(t.sender, (NewsHandler.UpdatedFeedEventArgs)t.Args);

   28         } else if (t.Args is NewsHandler.UpdateFeedExceptionEventArgs) {

   29           this.owner.OnUpdateFeedException(t.sender, (NewsHandler.UpdateFeedExceptionEventArgs)t.Args);

   30         }

   31       }

   32     }

As you can see: no real magic things happen. Interesting is the line 22: if there are no queued results, we just return and do nothing. But there was already a cost calling it in sync with the main UI thread, look at the call chain above! And as such it breaks the UI thread every 250 msecs also if there is just nothing to do.

But lets look what will happen if there is a result to process: let's pick the call into owner.OnUpdatedFeed(). The owner forwards to the UI class and no .InvokeRequired call is needed (the only good thing so far). It calls into FeedTreeNodeBase class to update the unread counter and node text of the treeview that in turn calls the TreeNode::UpdateNode() function. It will call into the treeview:WndProc(m), WmNotify(), CustomDraw()..., FontHandleWrapper::.ctor,... Font::ToHFont(), Font:ToLogFont() and...? You are right: it checks the code access security with CodeAccessPermission::Demand()! Right and secure, but slow. More slow even though the CodeAccessSecurityEngine::Check calls into a AppDomain::MarshalObject(Object) followed by a parameter memory serialization into another AppDomain! I scratched my head: what the f...? Then I remembered the second quote (above): Ticks are generated out of process! So this was the obvious reason for the cross-AppDomain call (memory allocation: 75MB, 33%).

So what to do to fix the problem(s)? Simply use the Windows.Forms.Timer! Think about it: it is driven by the main window message pump and runs always in the right context of the main UI thread (no .InvokeRequired calls). Timing isn't an important point here, we just want to process one result each time we are called. Further: no cross-AppDomain security check should happen anymore! With that timer it is just a simple update control(s) with some fresh data!

So take care of the timer class(es) you may use in your projects! Check their implications! Be careful, there are also other issues with it I did not mentioned here, read the docs!
Now I'm off to close related bugs...

Technorati tags:  |  | 
Tuesday, September 27, 2005 1:52:06 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Thursday, September 08, 2005
BASTA! 2005
BASTA! 2005
Technorati tags:  | 
Thursday, September 08, 2005 11:40:01 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Friday, September 02, 2005
"Send to OneNote..." plugin for RSS Bandit
Just got it work, yesss! You can download it here. Just expand the zip to your RSS Bandit installation sub-folder named plugins. Within the config file you can change the default note page used and some templates to format the posted item link and content.
Inspired by a comment by MrPuck at Dare Obasanjo's post I got the idea. It should work with OneNote 2003 SP1. Thanks to Donovan and Andrew.
Technorati tags:  |  |  | 
Friday, September 02, 2005 8:11:06 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [2]  | 
# Tuesday, July 05, 2005
Why .NET Remoting does not have a RemotingConfiguration.Reset() ?

Hopefully the .NET 2.0 bits will support a similar call to reset the remoting infrastructure the clear way without restarting the whole remoting application!

As you may have noticed: there exists a RemotingChannels.UnregisterChannel() method to use to get rid of a old used channel and switch to a new one (registering). But that is not enough to get an application seamlessly work with a new remoting service endpoint: after you really used one of you configured services, you will get an exception if you try to register the service again with a different service endpoint. This is because the RemotingConfigHandler+RemotingConfigInfo method AddWellknownEntry() calls a method named CheckForRedirectedClientType() that cause a CantUseRedirectedTypeForWellKnownService exception. So after I tried a "fix" with managing the calls to the .NET remoting classes within a new separate AppDomain (and unload that on a reset remoting request) that did not work I end up with a hack using Reflection to get around that.

Here is the used code that works for our requirements:

    /// <summary>

    /// This is cool, but it is a HACK. Please validate the code each time

    /// the .NET framework gets updated. There is a little safty included to

    /// throw a InvalidOperationException if something changed we require to get

    /// it work somehow.

    /// </summary>

    /// <exception cref="InvalidOperationException">

    /// On every failed reflection call or if we do not get any of

    /// the required FieldInfo objects</exception>

    /// <remarks>

    /// The HACK bases on the fact Remoting informations are cached

    /// in the well hidden sync. Hashtable field "_remoteTypeInfo" after they get used once.

    /// This field you can find within the (internal) class

    /// RemotingConfigHandler.RemotingConfigInfo. The static RemotingConfigHandler.Info

    /// field holds a reference to an instance if that class.

    /// To reset we simply initialize that field with a new instance of

    /// a synchronized Hashtable.

    /// Note: We do only "fix" for Singleton objects, not client activated services.

    /// So to get it "fully" work (complete state reset), you may have to hack

    /// more and other fields.

    /// </remarks>

    private static void Release_NETRemotingResources() {

      bool raiseError = true// warn if we switch to a new .NET env where the reflection is maybe not working anymore!

      try {

        //HACK: please verify it after each Service Pack or new version of .NET runtime to be used!

        Type configHandlerType = Type.GetType("System.Runtime.Remoting.RemotingConfigHandler");

        if (configHandlerType != null) {

          FieldInfo infoFI = configHandlerType.GetField("Info", BindingFlags.GetField | BindingFlags.Public | BindingFlags.Static);

          if (infoFI != null) {

            object infoFIRef = infoFI.GetValue(null);  // static, so no object instance to provide

            if (infoFIRef != null) {

              FieldInfo remoteTypeInfoFI = infoFI.FieldType.GetField("_remoteTypeInfo", BindingFlags.Instance | BindingFlags.NonPublic);

              if (remoteTypeInfoFI != null) {

                remoteTypeInfoFI.SetValue(infoFIRef, Hashtable.Synchronized(new Hashtable()));

                raiseError = false// all seems to be OK

              }

            }

          }

        }

      } catch (Exception ex) {

        throw new InvalidOperationException("Failed to reset .NET internal remoting state.", ex);

      }

 

      if (raiseError)

        throw new InvalidOperationException("Failed to reset .NET internal remoting state.");

    }

Technorati tags:  | 
Tuesday, July 05, 2005 9:21:19 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [2]  | 
# Tuesday, May 31, 2005
Cool shell extension for .NET assemblies
Back from vacations today I found the article Shell Extensions for .NET Assemblies at codeproject.com: really useful tool (must have) to get our projects organized (old VB6 stuff vs. newer .NET stuff). It visually distinguish between normal windows DLL's and .NET assemblies and shows if the assembly is signed via a public key token column.
Technorati tags:  |  |  | 
Tuesday, May 31, 2005 10:20:00 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [4]  | 
# Tuesday, May 03, 2005
Serious issues in .NET that may affect my work

Today there was a flood of fixed isses (12) for .NET 1.1 published via the Most Recent KB for MS .NET Framework 1.1 article feed. Some that that may affect me at work are

Is there any deadline known for SP2?

Technorati tags:  |  | 
Tuesday, May 03, 2005 7:21:17 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Tuesday, February 22, 2005
Keep them synchronized!

Today I wrote a little tool to keep the various language resource files of VS7 projects synchronized: you know usually you have to add a new resource string to all the language files as you need a new one. But I think I'm not the only one: I'm lazy to maintain them all the time I need a new entry :-( Especially if you have more than a hand full of language specific .resx files. So here it is:

http://www.rendelmann.info/packages/DiffPatchResources.zip

From the readme:

A small console application to keep VS7 .resx files in sync. with the main resource.

It expect the path and filename to the main text resource file (.resx, no language LCID) as a command line parameter, so you can simply drag/drop the main resource file to the executable file, e.g.:

 DiffPatchResources.exe "C:\MyProjects\MyApp\Resources\mainText.resx"

It will iterate the "/root/data" entries in the main file (e.g. main.resx) and
patch each dependent language file (mainText.[LCID].resx) to contain any missing entry. Further, if the source data contains a comment element and the content of that starts with "CHANGED" text, it will replace the yet existing target entry with the changed entry of the source.

It writes a .bak file on each modified resource and reports success/failures and some statistics to the console.

========= ATTENTION! =============

Currently it does NOT work on .resx files related to Forms! You should not try to get it run on such files! I will not guarantee for any success and will not be responsible for any damage resulting of the any usage of this tool!

For any improvements or comments leave a comment here, please. Have fun!

Technorati tags:  | 
Tuesday, February 22, 2005 12:13:53 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Tuesday, January 25, 2005
Small issue in Visual Studio IDE 7.1 replace dialog

Dunno if anyone else ever noticed that small resizable dialog form issue of the "Replace" dialog within Visual Studio 7.1 (.NET):

VS.IDE 7.1 issue

At least the form widgets does not resize as the form resize. But please keep it resizable if it gets fixed! Or is it already done...?

PS: the missnig picture is now there.

Technorati tags:  | 
Tuesday, January 25, 2005 1:18:58 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Friday, December 24, 2004
Merry Christmas!

Small issue I detected yesterday in the current .NET 1.1 compiler. Try to compile the following code:

        public string MyProperty {
            get { return null; }
            set { ; }
        }
It results in messages like this:
D:\Visual Studio Projects\test\ThreadedListView\ThreadedListView.cs: 
Internal Compiler Error: stage 'BEGIN'
D:\Visual Studio Projects\test\ThreadedListView\ThreadedListView.cs(1):
Internal Compiler Error: stage 'BEGIN' symbol ''
D:\Visual Studio Projects\test\ThreadedListView\ThreadedListView.cs(11):
Internal Compiler Error: stage 'BEGIN' symbol 'ThreadedListView'
Internal Compiler Error (0xc0000005 at address 53630902):
likely culprit is 'BEGIN'. An internal error has occurred in the compiler.
To work around this problem, try simplifying or changing the program near the
locations listed below. Locations at the top of the list are closer to the point at
which the internal error occurred.

I just removed the semicolon in the set, and it compiles fine. Today I wanted to repro that: but now no problems occured... So sorry, I cannot post a bug to MS for it.

Technorati tags:  | 
Friday, December 24, 2004 3:03:48 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Thursday, October 14, 2004
How do you know if you need pinvoke.net?

Today I found a real cool page within MSDN: Microsoft Win32 to Microsoft .NET Framework API Map. Have a look there before you go to pinvoke.net or setup your very own interop declarations...

Technorati tags:
Thursday, October 14, 2004 4:39:49 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Friday, September 24, 2004
RSS Bandit and IPv6

A while ago one user complains about RSS Bandit was not running with installed/configured IPv6 on a windows machine. Today I got the answer (by mail from Frank Fischer, Microsoft Germany - thanks again!): open machine.config located at C:\Windows\Microsoft.NET\Framework\v1.1.xxxx\CONFIG and change the XML tag:

<!-- <ipv6 enabled="false" /> -->

to:

<ipv6 enabled="true" />

This change allows the framework to parse and resolve IPv6 addresses. So any .NET application will be IPv6 enabled, not only RSS Bandit (but also ;-)

Technorati tags:  | 
Friday, September 24, 2004 2:48:20 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Saturday, September 18, 2004
BASTA!

About to go to the BASTA! conference tomorrow. My plan for monday: Security Special with J. Freiberger and M. Willers and the Jet Lag open forum with Dan. I go by train, so the topic does not fit really, but I like to meet Dan!

Technorati tags:
Saturday, September 18, 2004 10:25:25 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [1]  | 
# Tuesday, August 17, 2004
My two cents to pinvoke.net: urlmon.FindMimeFromData()

Yeah: it was not as difficult to add the new topic, once I figured out how to get it work ;-)

See http://www.pinvoke.net/default.aspx/urlmon.FindMimeFromData and get your MIME sniffing work...

Technorati tags:  | 
Tuesday, August 17, 2004 4:02:02 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [5]  | 
# Friday, July 09, 2004
Nice little feature of .NET password textboxes

Today I stumbled over this little balloon window popping up as I pressed Ctrl-C on a simple textbox with password char set to '*':

BTW: who wonders about the green progressbar - it is a password quality meter you may know from Mozilla browser...

Technorati tags:  | 
Friday, July 09, 2004 1:39:57 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Friday, May 28, 2004
NameValueCollection not CLSCompliant

Today I stumbled over a framework v1.1 issue related to the wellknown System.Collections.Specialized.NameValueCollection. I used it in a public interface as a return parameter and somewhere again as method parameter within a assembly marked with the attribute CLSCompliant(true). The MSDN docs are silent about CLS compliance in that case and I figured out, it is not compliant! Got compile errors like this:

ADSIAuthenticationProvider.cs(31,37): error CS3001: Argument type 'PROCOS AG.Components.Authentication.Shared.IAuthenticationConfiguration' is not CLS-compliant

or

ADSIAuthenticationProvider.cs(44,10): error CS3002: Return type of 'PROCOS AG.Components.Authentication.Services.ADSIAuthenticationProvider.Authenticate(System.Collections.Specialized.NameValueCollection)' is not CLS-compliant

Both are NameValueCollection types. So: is it a bug? I did not found a notice about looking around with google, so I think I have to change my type(s) to a other one that is hopefully CLS compliant.

Technorati tags:  | 
Friday, May 28, 2004 8:26:00 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [1]  | 
# Tuesday, April 27, 2004
Visual Studio 7 Forms Designer issue: order of classes is important

Today I stumbled over this issue with the Visual Studio 7 Forms Designer:

 "The class Main can be designed, but is not the first class in the file.  Visual Studio requires that designers use the first class in the file.  Move the class code so that it is the first class in the file and try loading the designer again."

Here is the sample code:

namespace Test
{
 public class MyEventArgs {
  public string Param1;
  public bool Param2;
 }
 /// <summary>
 /// Summary description for Main Form.
 /// </summary>
 public class Main : System.Windows.Forms.Form
 {
 }
}

So: avoid this by using separate files for each class if possible or keep at least the forms class code alone.

Technorati tags:  | 
Tuesday, April 27, 2004 4:51:34 PM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Friday, April 23, 2004
Subtle differences
Apart from the again taken up discussion I wanted to refer with my post rather to the subtle difference between the 1.0 and 1.1 version of the NET Frameworks: Programs (and concomitantly RssBandit) behave differently, depending upon installed Framework version. So I think, we should decide to get them working the same standard conformant way: need to set its Normalization property to true for .NET 1.0 [see Reading and Writing Wellformed XML]. But what really I hate is this (pseudo-)code:
if (System.Runtime.Version.Major == 1 && 
    System.Runtime.Version.Minor < 1 ) {...} else {...}

Isn't this (and variations) enough to have:

if (Environment.OSVersion.Major == 5 && 
    Environment.OSVersion.Minor >= 1 ) {...} else {...}

There are really enough differences we have to consider... :-(

Technorati tags:  | 
Friday, April 23, 2004 8:43:04 AM (W. Europe Standard Time, UTC+01:00)    #  Comments [0]  | 
# Thursday, March 18, 2004
Bandit UI Translation progress, coordination

I added some tasks related to UI Translation at sourceforge.net:

http://sourceforge.net/pm/task.php?group_project_id=34629&group_id=96589&func=browse

So to get an idea what languages are offered by contributors and how it progress, have a look there.