<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>Tips</title><link>http://www.pixvillage.com/blogs/devblog/category/15.aspx</link><description>Tips</description><managingEditor>Buz &amp; Skup</managingEditor><dc:language>en-US</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>Buz &amp; Skup</dc:creator><title>Downloading a File with a Save As Dialog in ASP.Net</title><link>http://www.pixvillage.com/blogs/devblog/archive/2007/05/24/6496.aspx</link><pubDate>Thu, 24 May 2007 11:49:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2007/05/24/6496.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/6496.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2007/05/24/6496.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/6496.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/6496.aspx</trackback:ping><description>&lt;P&gt;Scott Guthrie &lt;A href="http://weblogs.asp.net/scottgu/archive/2007/05/22/may-22nd-link-listing-asp-net-visual-studio-silverlight-wpf-and-net.aspx"&gt;points&lt;/A&gt;&amp;nbsp;to&amp;nbsp;&lt;A href="http://west-wind.com/weblog/posts/76293.aspx"&gt;Rick Strahl's&amp;nbsp;blog&lt;/A&gt; about how to automaticaly open a Save As dialog on a link click. Very useful to download attachments.&lt;/P&gt;
&lt;P&gt;I'd just like to add that IE and FireFox have different handling with non ASCII characters that we can use in my french country for instance... IE doesn't like those chars, so you have to URLEncode it. But when URLEncoded, FireFox doesn't catch it, and keeps '+' chars&amp;nbsp;instead of spaces...&lt;/P&gt;
&lt;P&gt;The solution is simple.. you just have to check the client browser :&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: #e0e0e0 1px solid; BORDER-TOP: #e0e0e0 1px solid; FONT-SIZE: 10pt; BACKGROUND: white; BORDER-LEFT: #e0e0e0 1px solid; COLOR: black; BORDER-BOTTOM: #e0e0e0 1px solid; FONT-FAMILY: Consolas"&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;static&lt;/SPAN&gt; &lt;SPAN style="COLOR: blue"&gt;void&lt;/SPAN&gt; PrepareAttachmentReponse(&lt;SPAN style="COLOR: #2b91af"&gt;HttpContext&lt;/SPAN&gt; context, &lt;SPAN style="COLOR: blue"&gt;string&lt;/SPAN&gt; filename)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: blue"&gt;if&lt;/SPAN&gt; (context.Request.Browser.Browser == &lt;SPAN style="COLOR: #a31515"&gt;"IE"&lt;/SPAN&gt;)&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; filename = context.Server.UrlPathEncode(filename);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR: green"&gt;// send response&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; context.Response.AppendHeader(&lt;SPAN style="COLOR: #a31515"&gt;"Content-Disposition"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #a31515"&gt;"attachment; filename=\""&lt;/SPAN&gt; + filename + &lt;SPAN style="COLOR: #a31515"&gt;"\""&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN: 0px"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;And that's it.&lt;!--EndFragment--&gt;&lt;/P&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/6496.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Buz &amp; Skup</dc:creator><title>COM Interop without additional assemblies</title><link>http://www.pixvillage.com/blogs/devblog/archive/2005/03/24/167.aspx</link><pubDate>Thu, 24 Mar 2005 00:08:00 GMT</pubDate><guid>http://www.pixvillage.com/blogs/devblog/archive/2005/03/24/167.aspx</guid><wfw:comment>http://www.pixvillage.com/blogs/devblog/comments/167.aspx</wfw:comment><comments>http://www.pixvillage.com/blogs/devblog/archive/2005/03/24/167.aspx#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.pixvillage.com/blogs/devblog/comments/commentRss/167.aspx</wfw:commentRss><trackback:ping>http://www.pixvillage.com/blogs/devblog/services/trackbacks/167.aspx</trackback:ping><description>&lt;P&gt;In this post, I'm about to deal with the use of COM components inside a .Net project. &lt;/P&gt;
&lt;P&gt;Access to Windows or third-party API is commonly made through COM, and when you're working on a .Net project, this is typically done by adding a reference to the project (&lt;EM&gt;Project&lt;/EM&gt;, &lt;EM&gt;Add Reference...&lt;/EM&gt; menu, &lt;EM&gt;COM&lt;/EM&gt; tab). Visual Studio then creates an assembly that contains the stub of interop code for the COM Type Library.&lt;/P&gt;
&lt;P&gt;Unfortunatelly, each assembly corresponds to a file on the disk, and each file is at least 64KBytes large.&lt;/P&gt;
&lt;P&gt;In the &lt;A href="http://www.pixvillage.com/"&gt;PixVillage&lt;/A&gt; project, the installation package need to be as small as possible in order to reduce download time and bandwidth, so we looked after a way to reduce the number and size of COM Interop assemblies.&lt;/P&gt;
&lt;P&gt;A (quite) simple way to achieve both these goals is to use &lt;A href="http://www.aisto.com/roeder/dotnet"&gt;Lutz Roeder's Reflector&lt;/A&gt; to generate the C# code of the COM stub directly from the assembly IL.&lt;/P&gt;
&lt;P&gt;To do so (&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt; represents the name of the Type Library) :&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Start Reflector, 
&lt;LI&gt;Find the COM Interop assembly (refer to the properties of the reference : the file name should be "Interop.&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt;.dll"), 
&lt;LI&gt;Open the COM Interop assembly in Reflector, 
&lt;LI&gt;Expand both the assembly (Interop.&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt;) and file (&lt;STRONG&gt;&lt;EM&gt;xxx&lt;/EM&gt;&lt;/STRONG&gt;.dll) nodes in the treeview, 
&lt;LI&gt;Select the node of the Type Library base namespace in the tree (the node called &lt;EM&gt;&lt;STRONG&gt;xxx&lt;/STRONG&gt;&lt;/EM&gt; with a &lt;STRONG&gt;{ } &lt;/STRONG&gt;icon), 
&lt;LI&gt;Press the &lt;EM&gt;Space&lt;/EM&gt; bar to generate C# code for the namespace, 
&lt;LI&gt;Click in the right pane, select all code (&lt;EM&gt;Ctrl+A&lt;/EM&gt;) and copy it to the clipboard (&lt;EM&gt;Ctrl+C&lt;/EM&gt;), 
&lt;LI&gt;Paste the code in a new C# (&lt;EM&gt;.cs&lt;/EM&gt;) file in Visual Studio.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;Now, there might be missing references : you must add them (with the &lt;EM&gt;using&lt;/EM&gt; keyword) at the very beginning of the new file. For instance, you may have to add references to the following namespace : &lt;EM&gt;System, System.Collections&lt;/EM&gt;, &lt;EM&gt;System.Runtime.InteropServices&lt;/EM&gt;, &lt;EM&gt;System.Reflection&lt;/EM&gt;, &lt;EM&gt;System.Runtime.CompilerServices&lt;/EM&gt;...&lt;/P&gt;
&lt;P&gt;You may also have duplicate member definitions because inheriting interfaces define the same members as their parent : remove them.&lt;/P&gt;
&lt;P&gt;The last thing to do is to clean the content of the &lt;EM&gt;classes&lt;/EM&gt; (which are different from &lt;EM&gt;interfaces&lt;/EM&gt;) contained in the namespace. When rendered by Reflector, a class implements one or more interfaces and contains a number of properties / methods with no code, which do not compile. To make your code compile, remove all of its base interfaces and all of its content to make it empty.&lt;/P&gt;
&lt;P&gt;Now you might have in your code :&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;A number of enums and interfaces that represents the &lt;EM&gt;interfaces&lt;/EM&gt; and &lt;EM&gt;constant values&lt;/EM&gt; exposed by the Class Library, 
&lt;LI&gt;One or more interfaces having a &lt;EM&gt;&lt;STRONG&gt;CoClass&lt;/STRONG&gt;&lt;/EM&gt; attribute, corresponding to the &lt;EM&gt;components&lt;/EM&gt; exposed by the Class Library 
&lt;LI&gt;One or mode classes used by the framework to create the instances of the exposed components.&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;For instance, if you are importing the MSN Messenger API, you may have a &lt;EM&gt;IMessenger&lt;/EM&gt; interface, a &lt;EM&gt;Messenger&lt;/EM&gt; component and a &lt;EM&gt;MessengerClass&lt;/EM&gt; class. In order to access the API, you will have to type &lt;EM&gt;IMessenger msn = new Messenger();&lt;/EM&gt;&lt;/P&gt;&lt;img src ="http://www.pixvillage.com/blogs/devblog/aggbug/167.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>