How To Raise a "File Download" Dialog Box for a Known MIME Type

When you serve a document from a Web server, you might want to immediately prompt the user to save the file directly to the user’s disk, without opening it in the browser. However, for known MIME (Multipurpose Internet Mail Extensions) types such as Microsoft Word (“application/ms-word”), the default behavior is to open the document in Internet Explorer.

You can use the content-disposition header to override this default behavior. Its format is:

Content-disposition: attachment; filename=fname.ext

[http://support.microsoft.com/kb/260519/EN-US/]

 

Controlling optimization and debug info in Release builds in .Net applications

Some interesting info on controlling optimization and debug info for deployed .NET applications:

…the little-known little-used [.NET Framework Debugging Control] section of a .INI file. These help guide and control the JIT. From MSDN:

This JIT configuration has two aspects:

  • You can request the JIT-compiler to generate tracking information. This makes it possible for the debugger to match up a chain of MSIL with its machine code counterpart, and to track where local variables and function arguments are stored.
  • You can request the JIT-compiler to not optimize the resulting machine code.

So Mark suggested this (emphasis mine):

You can have the best of both worlds with a rather neat trick. The major differences between the default debug build and default release build are that when doing a default release build, optimization is turned on and debug symbols are not emitted. So:

    • Step 1: Change your release config to emit debug symbols. This has virtually no effect on the performance of your app, and is very useful if (when?) you need to debug a release build of your app.
    • Step 2: Compile using your new release build config, i.e. *with* debug symbols and *with* optimization. Note that 99% of code optimization is done by the JIT compiler, not the language compiler, so read on…
    • Step 3: Create a text file in your app’s folder called xxxx.exe.ini (or dll or whatever), where xxxx is the name of your executable. This text file should initially look like:


[.NET Framework Debugging Control]
GenerateTrackingInfo=0
AllowOptimize=1

    • Step 4: With these settings, your app runs at full speed. When you want to debug your app by turning on debug tracking and possibly turning off (CIL) code optimization, just use the following settings:


[.NET Framework Debugging Control]
GenerateTrackingInfo=1
AllowOptimize=0

[http://www.hanselman.com/blog/ DebugVsReleaseTheBestOfBothWorlds.aspx]

 

Converting a byte[] to a System.String

Discussion at http://weblogs.asp.net/oldnewthing/ archive/2004/09/07/226306.aspx:

For some reason, this question gets asked a lot. How do I convert a byte[] to a System.String? (Yes, this is a CLR question. Sorry.)

You can use String System.Text.UnicodeEncoding.GetString() which takes a byte[] array and produces a string.

Note that this is not the same as just blindly copying the bytes from the byte[] array into a hunk of memory and calling it a string. The GetString() method must validate the bytes and forbid invalid surrogates, for example.

You might be tempted to create a string and just mash the bytes into it, but that violates string immutability and can lead to subtle problems.

The MSDN help for Encoding.GetString() is here:

http://msdn.microsoft.com/library/default.asp? url=/library/en-us/cpref/html/ frlrfSystemTextEncodingClassGetStringTopic1.asp

 

Assembly Dependency Viewer

This simple application gets any VS.NET project or assembly and displays all the assembly / project dependencies. All dependencies are shown in a tree view with images that indicate the assembly location (Bin, GAC or registered as COM+ component).

http://www.codeproject.com/dotnet/Assemblydependencies.asp

Understanding Delphi’s perception of COM

Delphi is great for COM if you want to do something simple; as soon as someting a little more complex is needed, COM in Delphi can be a real headache. Here is a braindump from a recent investigation:

The LocalServer class registration function CoRegisterClassObject is called for each Class Factory registered with the Singleton ComServer object in TComServer.Initialize. Class Factories are registered in the initialization section of units in which they are defined, and TComServer.Initialize does not get called until after Application.Initialize has been called (using some InitProc hackery in first ComObj and then ComServ). Crucially, ComServer is a helper object to guarantee registration of all the Class Factories in the application (or DLL), so ComServer.ObjectCount refers to the number of objects it has helped to create (via Class Factories) not the number of references held (say, externally) to any particular COM object.

A post from b.p.d.activex.controls.writing by one Patrice Corteel explains further:

Now let’s go a step further in COM threading model discussion and look at local and remote servers versus in-proc servers.
A Delphi local or remote exe server has a main thread which calls CoInitialize which makes it an apartment. And as a default behaviour, every COM component based on the delphi COM framework is created in this thread and marked as apartment threaded. If you explicitly spawn new threads you can initialize them as you want but you must get a marshalled interface to call components created by your main thread.
If you want to create free threaded components it’s far more difficult since you can’t rely directly on Delphi implementation and you have to rewrite large parts of ComServ and subclass many of ComObj classes. I’m currently working on this topic and I’ll post more on this when I am over with tests.

Note that if lengthy initialisation is needed, set ComServer.StartSuspended to True before Application.Initialize; this causes the class factories to be registered with the REGCLS_SUSPENDED flag, and ComServ.InitComServer makes the required call to CoResumeClassObjects to activate them again.

References