<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Shri Borde's WebLog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/shrib/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/shrib/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:24:53 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>GitDiff.bat - power-diffing with GIT</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/gitdiff-bat-power-diffing-with-git</link>
      <pubDate>Mon, 13 Apr 2009 12:56:14 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2009/04/13/gitdiff-bat-power-diffing-with-git/</guid>
      <description><![CDATA[As mentioned in the GIT documentation, you can set the environment variable GIT_EXTERNAL_DIFF to use...]]></description>
      <content:encoded><![CDATA[<p>As mentioned in <a href="http://kernel.org/pub/software/scm/git/docs/v1.0.13/git-diff-files.html">the GIT documentation</a>, you can set the environment variable GIT_EXTERNAL_DIFF to use a custom diff utility. Try doing "set GIT_EXTERNAL_DIFF=echo" and running a "git diff" command to see how GIT_EXTERNAL_DIFF works. </p> <p>One limitation of this technique is that GIT launches the diff utility program once for every file modified. What this means is that you do not get to see the list of all files changed upfront (if you want to see how many files have changed, etc), and are also forced to review the files in the order GIT chooses. If you want to see all the test files first for example, or if you need to go back to a file you have already diffed, you have to start the "git diff" command all over again. Also, if you want to end the review half way through, you cannot do that easily and are forced to manually close the diff program multiple times until the "git diff" command terminates.</p> <p>Luckily, there is a simple solution to this. You can use a simple script. See <a href="http://github.com/shri/ironruby/blob/5e8c6b232a3c952985adbf1b9cda5c456d503cea/Merlin/Main/Languages/Ruby/Scripts/GitDiff.bat">GitDiff.bat</a> (and <a href="http://github.com/shri/ironruby/blob/5e8c6b232a3c952985adbf1b9cda5c456d503cea/Merlin/Main/Languages/Ruby/Scripts/GitDiff.rb">GitDiff.rb</a>). The arguments to the script are the same as "git diff". However, it will show you a diff of two <em>folders</em>, one with the old version of the files and one with the new version of the files. You can review the files in the order you chose...</p> <p>Here is a screenshot using Beyond Compare as the diffing tool. The window at the top is the main window showing the list of files. The two windows at the bottom are diffs of two of the changed files.</p> <p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/shrib/WindowsLiveWriter/GitDiff.batpowerdiffingwithGIT_1426F/GitDiff_2.png" original-url="http://blogs.msdn.com/blogfiles/shrib/WindowsLiveWriter/GitDiff.batpowerdiffingwithGIT_1426F/GitDiff_2.png"><img style="border-right: 0px; border-top: 0px; border-left: 0px; border-bottom: 0px" height="1202" alt="GitDiff" src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/shrib/WindowsLiveWriter/GitDiff.batpowerdiffingwithGIT_1426F/GitDiff_thumb.png" original-url="http://blogs.msdn.com/blogfiles/shrib/WindowsLiveWriter/GitDiff.batpowerdiffingwithGIT_1426F/GitDiff_thumb.png" width="851" border="0"></a> </p> <p>&nbsp;</p> <p>Setup instructions:</p> <ul> <li>Copy GitDiff.bat and GitDiff.rb to somewhere in your path  <li>Make sure that ruby.exe is in the path  <li>Go to a folder in a GIT repo  <li>GitDiff.bat &lt;old-sha&gt; &lt;new-sha&gt;</li></ul>]]></content:encoded>
    </item>
    <item>
      <title>Proposed spec for Ruby's Thread.critical=</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/proposed-spec-for-rubys-thread-critical</link>
      <pubDate>Wed, 07 Jan 2009 12:24:31 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2009/01/07/proposed-spec-for-rubys-thread-critical/</guid>
      <description><![CDATA[Ruby has green threads, and so its implementation of Thread.critical= is speced as follows:  Sets...]]></description>
      <content:encoded><![CDATA[<p>Ruby has <a href="http://spec.ruby-doc.org/wiki/Ruby_Threading">green threads</a>, and so its implementation of <a href="http://www.ruby-doc.org/core/classes/Thread.html#M000461">Thread.critical=</a> is speced as follows:</p> <blockquote> <p>Sets the <a href="http://www.ruby-doc.org/Thread.html#M000473">status</a> of the global ``thread <a href="http://www.ruby-doc.org/Thread.html#M000460">critical</a>’’ condition and returns it. When set to <tt>true</tt>, prohibits scheduling of any existing thread. Does not block <a href="http://www.ruby-doc.org/Thread.html#M000449">new</a> threads from being created and <a href="http://www.ruby-doc.org/Thread.html#M000464">run</a>. Certain thread operations (such as stopping or killing a thread, sleeping in the <a href="http://www.ruby-doc.org/Thread.html#M000457">current</a> thread, and raising an exception) may cause a thread to be scheduled even when in a <a href="http://www.ruby-doc.org/Thread.html#M000460">critical</a> section. <tt>Thread::critical</tt> is not intended for daily use: it is primarily there to support folks writing threading libraries.</p></blockquote> <p>The requirement of descheduling other threads complicates things for Ruby implementations like IronRuby and JRuby which use native threads. Furthermore, most uses of Thread.critical= do not actually depend on the descheduling of other threads. This is canonical usage:</p><pre style="font-weight: bold; font-size: 10pt; background: black; color: white; font-family: consolas"><p>def get_unique_cookie()
<p>    begin
<p>        Thread.critical = true
<p>        cookie = @@counter
<p>        @@counter += 1
<p>    ensure
<p>        Thread.critical = false
<p>    end
<p>    cookie
<p>end
<p></p></pre>
<p>So most usages expect Thread.critical to behave like a critical section. Given this, here is the proposed new behavior. This behavior can be efficiently implemented even on native threads, and also works for most usage scenarios providing users with a simple locking construct.</p>
<blockquote>
<p>Sets the status of the global ``thread critical’’ condition and returns it. When set to true, blocks any other thread that tries to set Thread.critical=true. It is recommend to use an ensure clause to set Thread.critical to false to exit the "global critical section".</p>
<p>If a thread terminates while it is in the global critical section (either because of an uncaught exception, because of normal termination at the end of the block, or because of a call to Thread.kill), it leaves the process in an undefined state. Some implementations might leave the global critical section allowing other threads to enter it; some implementations might do nothing causing the app to hang if any other thread tries to set Thread.critical=true; some might exit the process.</p>
<p>Calling "sleep" in the critical section does nothing. Calling "Thread.stop" in the global critical section also does nothing (it sets Thread.critical to false in Ruby 1.8.6).</p>
<p>Thread.critical= is not reentrant. If a thread in the global critical section tries to set Thread.critical=true again, the behavior is undefined. Some implementations might require a single Thread.critical=false to leave the global critical section; some might require a matching number of Thread.critical=false; some might throw an exception. </p>
<p>The behavior when calling Thread.critical=false from a thread that is not in the global critical section causes undefined behavior. Some implementations might ignore the call; some might cause the thread in the global critical section (if any) to exit the critical section; some might throw an exception.</p>
<p>The code that executes in the global critical section should be kept to a minimum, and should ideally not call any user-defined code as it opens up the possibility of deadlocks. Since its hard to know when user-defined code can execute (because any library method may have been monkey-patched), Thread.critical= should be used very carefully. Thread::critical is not intended for daily use: it is primarily there to support folks writing threading libraries.</p></blockquote>
<p>We intend to propose this to ruby-core for approval.</p>
<p>Update: Ruby 1.9 does not support Thread#critical! So this issue should go away in the future. For 1.8.*, <a href="http://www.nabble.com/-ruby-core%3A20999--Supporting-Thread.critical%3Dwith-native-threads-td21224464.html">here</a> is the ruby-core discussion thread. There may be a few scenarios which rely on thread descheduling, but it does seem to be marginal. JRuby is going to try to implement Thread#critical= as a global mutex. IronRuby is likely to stay on that plan too.</p>]]></content:encoded>
    </item>
    <item>
      <title>OLE Automation support ON in IronPython 2.0 Beta 4</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/ole-automation-support-on-in-ironpython-2-0-beta-4</link>
      <pubDate>Wed, 30 Jul 2008 18:15:00 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/07/30/ole-automation-support-on-in-ironpython-2-0-beta-4/</guid>
      <description><![CDATA[As I had mentioned in a previous post, we have added support in IronPython for accessing OLE...]]></description>
      <content:encoded><![CDATA[<P>As I had mentioned in a <A href="http://blogs.msdn.com/shrib/archive/2008/04/10/ole-automation-idispatch-support-in-ironpython.aspx" mce_href="http://blogs.msdn.com/shrib/archive/2008/04/10/ole-automation-idispatch-support-in-ironpython.aspx">previous post</A>, we have added support in IronPython for accessing <A href="http://en.wikipedia.org/wiki/OLE_Automation" mce_href="http://en.wikipedia.org/wiki/OLE_Automation">OLE Automation</A> objects using the <A href="http://msdn.microsoft.com/en-us/library/ms221608(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms221608(VS.85).aspx">IDispatch</A> interface, without having to rely on interop assemblies. This was enabled with the "ipy.exe -X:PreferComDispatch" command-line until IronPython 2.0 Beta 3. In Beta 4, this behaviour is on by default. This makes IronPython's support for OLE Automation more script-friendly akin to VBScript and JScript.</P>
<H4>See the difference</H4>
<P>In IronPython 1.X, trying to use Excel would cause IronPython to generate the inteorp assembly on the fly, which would take more than minute, before resulting in an exception. If you explictly added a reference to Microsoft.Office.Interop.Excel.dll, then things get back on track. However, note that not all machines with Office installed will necessarily have the primary interop assemblies (<A href="http://msdn.microsoft.com/en-us/library/aax7sdch.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aax7sdch.aspx">PIAs</A>) installed in the GAC, as explained in <A href="http://support.microsoft.com/kb/827476" mce_href="http://support.microsoft.com/kb/827476">this link</A>.</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">c:\IronPython-<FONT color=#00ff00>1.1.2</FONT>&gt;ipy.exe -v<BR>IronPython 1.1.2 (1.1.2) on .NET 2.0.50727.1433<BR>Copyright (c) Microsoft Corporation. All rights reserved.<BR>&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; t = System.Type.GetTypeFromProgID("Excel.Application")<BR>&gt;&gt;&gt; excel = System.Activator.CreateInstance(t)<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add() # This will take a long time<BR><FONT color=#00ff00>Generating Interop assembly for 000208d5-0000-0000-c000-000000000046<BR></FONT>Traceback (most recent call last):<BR>&nbsp; File , line 0, in &lt;stdin&gt;##16<BR>SystemError: Could not load type 'Excel._Application' from assembly 'Excel, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null'.<BR>&gt;&gt;&gt;<BR>&gt;&gt;&gt; import clr<BR>&gt;&gt;&gt; <FONT color=#00ff00>clr.AddReference("Microsoft.Office.Interop.Excel")</FONT><BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR>&gt;&gt;&gt;</PRE><BR>
<P>In IronPython 2.0 <A href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=12988" mce_href="http://www.codeplex.com/IronPython/Release/ProjectReleases.aspx?ReleaseId=12988">Beta 3</A>, things work much better, but as can be seen from the type of "wb", it still relies on the PIA. If the PIA is not installed or registered on the machine, IronPython would try to generate the interop assembly on the fly, again taking a very long time.</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">c:\IronPython-<FONT color=#00ff00>2.0B3</FONT>&gt;ipy.exe -v<BR>IronPython 2.0 Beta (2.0.0.3000) on .NET 2.0.50727.1433<BR>Type "help", "copyright", "credits" or "license" for more information.<BR>&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; t = System.Type.GetTypeFromProgID("Excel.Application")<BR>&gt;&gt;&gt; excel = System.Activator.CreateInstance(t)<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR>&gt;&gt;&gt; wb<BR>&lt;Microsoft.Office.Interop.Excel.WorkbookClass object at 0x000000000000002B&gt;<BR>&gt;&gt;&gt; wb.GetType().Assembly.CodeBase<BR><FONT color=#00ff00>'file:///C:/Windows/assembly/GAC/Microsoft.Office.Interop.Excel/12.0.0.0__71e9bce111e9429c/Microsoft.Office.Interop.Excel.dll'<BR></FONT>&gt;&gt;&gt; excel.Quit()<BR>&gt;&gt;&gt;</PRE>
<P>In IronPython 2.0 Beta 4, things just work, thanks to the shiny new OleAut support. "wb" is just a simple COM object that supports IDispatch, and there is no need for a PIA anymore!</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">c:\IronPython-<FONT color=#00ff00>2.0B4</FONT>&gt;ipy.exe -v<BR>IronPython 2.0 Beta (2.0.0.4000) on .NET 2.0.50727.1433<BR>Type "help", "copyright", "credits" or "license" for more information.<BR>&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; t = System.Type.GetTypeFromProgID("Excel.Application")<BR>&gt;&gt;&gt; excel = System.Activator.CreateInstance(t)<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR>&gt;&gt;&gt; wb<BR><FONT color=#00ff00>&lt;System.__ComObject (_Workbook) object at 0x000000000000002B&gt;<BR></FONT>&gt;&gt;&gt; excel.Quit()<BR>&gt;&gt;&gt;</PRE>
<P mce_keep="true">&nbsp;</P>
<H4>Different ways to get started</H4>
<P>IDispatch is about invoking a method on an existing OleAut object. But how do you get to an OleAut object in the first place? VBScript and VBA have a method called CreateObject to create an OleAut object. There are multiple ways of doing the same in IronPython. </P>
<P>The first is to use the <A href="http://msdn.microsoft.com/en-us/library/system.type.gettypefromprogid(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.type.gettypefromprogid(VS.71).aspx">Type.GetTypeFromProgID</A> method as shown here. This is the simplest solution.</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; <FONT color=#00ff00>t = System.Type.GetTypeFromProgID("Excel.Application")</FONT><BR>&gt;&gt;&gt; excel = System.Activator.CreateInstance(t)<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR></PRE>
<P>The second way is to use the new "clr.AddReferenceToTypeLibrary"&nbsp; function. This currently requires hard-coding the <A href="http://msdn.microsoft.com/en-us/library/aa372092.aspx" mce_href="http://msdn.microsoft.com/en-us/library/aa372092.aspx">GUID of the typelib</A> (we could consider easier ways in the future). However, the advantage is that you can access the typelib just like a Python module. This is particularly handy if you need to access enum values in your program. Using the TLB, you can use the symbolc enum names instead of hard-coding int constants.</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; excelTypeLibGuid = System.Guid("00020813-0000-0000-C000-000000000046")<BR>&gt;&gt;&gt; import clr<BR>&gt;&gt;&gt; <FONT color=#00ff00>clr.AddReferenceToTypeLibrary(excelTypeLibGuid)</FONT><BR>&gt;&gt;&gt; from Excel import Application<BR>&gt;&gt;&gt; excel = Application()
<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR></PRE>
<P>Finally, you can use the PIA as before. There is no particular advantage to doing this. It just means that your old code will keep on working as before (though method invocation will use the new IDispatch mechanism).</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">&gt;&gt;&gt; import clr<BR>&gt;&gt;&gt; <FONT color=#00ff00>clr.AddReference("Microsoft.Office.Interop.Excel")</FONT><BR>&gt;&gt;&gt; from Microsoft.Office.Interop.Excel import Application<BR>&gt;&gt;&gt; excel = Excel()<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR></PRE>
<P>All of the above techniques end up calling the Win32 function <A href="http://msdn.microsoft.com/en-us/library/ms686615.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms686615.aspx">CoCreateInstance</A>. So one more technique you could use is to make a pinvoke call to CoCreateInstance!</P>
<P>Once you have created a COM object, the rest of the code to access the object should work pretty much like before; it just wont require the presence of a PIA.</P>
<H4>How to turn back the clock?</H4>
<P>If you run into any bugs with the new OleAut support, there is a way to get to the old behavior. This is done by setting an environment variable called COREDLR_PreferComInteropAssembly to "TRUE" as show here. Do report the bug to <A href="mailto:users@lists.ironpython.com" mce_href="mailto:users@lists.ironpython.com">users@lists.ironpython.com</A> so that the issue can be fixed. COREDLR_PreferComInteropAssembly might go away in the future.</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">c:\IronPython-2.0B4&gt;ipy.exe<BR>IronPython 2.0 Beta (2.0.0.4000) on .NET 2.0.50727.1433<BR>Type "help", "copyright", "credits" or "license" for more information.<BR>&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; t = System.Type.GetTypeFromProgID("Excel.Application")<BR>&gt;&gt;&gt; excel = System.Activator.CreateInstance(t)<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR>&gt;&gt;&gt; wb<BR><FONT color=#00ff00>&lt;System.__ComObject (_Workbook) object at 0x000000000000002B&gt;</FONT><BR>&gt;&gt;&gt; ^Z 
<BR> <BR>c:\IronPython-2.0B4&gt;<FONT color=#00ff00>set COREDLR_PreferComInteropAssembly=TRUE</FONT> 
<BR> <BR>c:\IronPython-2.0B4&gt;ipy.exe<BR>IronPython 2.0 Beta (2.0.0.4000) on .NET 2.0.50727.1433<BR>Type "help", "copyright", "credits" or "license" for more information.<BR>&gt;&gt;&gt; import System<BR>&gt;&gt;&gt; t = System.Type.GetTypeFromProgID("Excel.Application")<BR>&gt;&gt;&gt; excel = System.Activator.CreateInstance(t)<BR>&gt;&gt;&gt; wb = excel.Workbooks.Add()<BR>&gt;&gt;&gt; wb<BR>&lt;Microsoft.Office.Interop.Excel.WorkbookClass (Workbook) object at 0x000000000000002B&gt;<BR>&gt;&gt;&gt; wb.GetType()<BR><FONT color=#00ff00>&lt;System.RuntimeType object at 0x000000000000002C [Microsoft.Office.Interop.Excel.WorkbookClass]&gt;</FONT><BR>&gt;&gt;&gt;<P mce_keep="true">&nbsp;</P></PRE>
<H4>Known issues</H4>
<P>There are few expected differences to be aware of.</P>
<UL>
<LI>There is one important detail worth pointing out. IronPython tries to use the typelib of the OleAut object if it can be found, in order to do name resolution while accessing methods or properties. The reason for this is that the IDispatch interface does not make much of a distinction between properties and method calls. This is because of VB6 semantics where "excel.Quit" and "excel.Quit()" have the exact same semantics. However, IronPython has a strong distinction between properties and methods, and methods are first class objects. For IronPython to know whether "excel.Quit" should invoke the method Quit, or just return a callable object, it needs to inspect the typelib. If a typelib is not available, IronPython assumes that it is a method. So if a OleAut object has a property called "prop" but it has no typelib, you would need to write "p = obj.prop()" in IronPython to read the property value. This behavior is by design.</LI>
<LI>Calling a method with "out" (or in-out) parameters requires explicitly passing in an instance of "clr.Reference" as described in <A href="http://blogs.msdn.com/haibo_luo/archive/2007/10/04/5284947.aspx" mce_href="http://blogs.msdn.com/haibo_luo/archive/2007/10/04/5284947.aspx">this blog</A>, if you want to get the updated value from the method call. Note that COM methods with out parameters are not considered Automation-friendly. JScript does not support out parameters at all. If you do run into a COM component which has out parameters, having to use "clr.Reference" is a reasonable workaround. Another workaround is to leverage the inteorp assembly by using the full method name syntax of "outParamAsReturnValue = InteropAssemblyNamespace.IComInterface(comObject)".</LI>
<UL>
<LI>Note that the Office APIs do have "VARIANT*" parameters, but there methods do not update the value of the VARIANT. The only reason they were defined with "VARIANT*" parameters was for performance since passing a pointer to a VARIANT is faster than pushing all the 4 DWORDs of the VARIANT onto the stack. So you can just treat such parameters as "in" parameters.</LI>
<LI>Real world examples of APIs with out parameters are <A class="" href="http://msdn.microsoft.com/en-us/library/ms681559(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms681559(VS.85).aspx">ADODB.Command.Execute</A>, most of the <A class="" href="http://msdn.microsoft.com/en-us/library/ms697837(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms697837(VS.85).aspx">Microsoft Agent APIs</A>. If you run into any others, let me know, so that I can compile a list here for reference. If this issue affects many scenarios, we could consider returning the out parameters as a return value tuple. This would require checking the ITypeInfo to check the type of parameters. We have avoided doing this so that we can have the same consistent code path irrespective of whether the typelib is available or not.</LI></UL></UL>
<P>Currently, there are a few bugs in corner cases:</P>
<UL>
<LI>Passing a Python long (BigInteger) as an argument to a COM method expecting a LONGLONG causes a TypeError (InvalidCastException).</LI>
<LI>Passing some types of objects (eg "xrange(1)") to a COM method expecting an IUnknown results in a TypeError (InvalidCastException).</LI>
<LI>There are some corner cases where code that would have throw an exception before is now allowed. For example, it is possible to pass any object to a COM method expecting a BSTR. This is because the&nbsp; default IDispatch marshalling rules allow this. Noone should be affected by this because it is a negative scenario anyway.</LI></UL>
<H4>Under the hoods</H4>
<P>Running with "ipy.exe -X:ShowRules", you can see that the generated code makes pinvoke calls on the IDispatch interfaces. This is similar to what VBScript (or VBA late bound code) would have done. UnsafeMethods.IDisaptchInvoke is a helper function in Microsoft.Scripting.Core.dll that will dereference the vtable of the OleAut object, get the function pointer for IDispatch::Invoke, and make a call to the function pointer.</P><PRE style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; BACKGROUND: black; COLOR: white; FONT-FAMILY: consolas">&gt;&gt;&gt; wb = com.Workbooks<BR>//<BR>// AST: Rule<BR>// .scope &lt;rule&gt; (<BR>) {<BR>&nbsp;&nbsp;&nbsp; .if ((((.arg $arg0) != .null) &amp;&amp; (Marshal.IsComObject)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.arg $arg0),<BR>&nbsp;&nbsp;&nbsp; )) ) {.return .site (Object) GetMember Workbooks( // Python GetMember Workbooks IsNoThrow: False<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ComObject.ObjectToComObject)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.arg $arg0),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.arg $arg1)<BR>&nbsp;&nbsp;&nbsp; );<BR>&nbsp;&nbsp;&nbsp; } .else {/*empty*/;<BR>&nbsp;&nbsp;&nbsp; }}
<BR>// AST: Rule<BR>// 
<P>.scope &lt;rule&gt; (<BR>) {<BR>&nbsp;&nbsp;&nbsp; .if (((((.arg $arg0) != .null) &amp;&amp; (((Object)(.arg $arg0)).(Object.GetType)() == ((Type)IDispatchComObject))<BR>&nbsp;&nbsp;&nbsp; ) &amp;&amp; ((IDispatchComObject)(.arg $arg0).ComTypeDesc == (ComTypeDesc)System.Scripting.Com.ComTypeDesc)<BR>&nbsp;&nbsp;&nbsp; ) ) {.scope (<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Scripting.Com.IDispatchObject dispatchObject<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.IntPtr dispatchPointer<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Int32 dispId<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Runtime.InteropServices.ComTypes.DISPPARAMS dispParams<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Scripting.Com.Variant invokeResult<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Object returnValue<BR>&nbsp;&nbsp;&nbsp; ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .scope (<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <FONT color=#00ff00>(.var dispId) = (ComMethodDesc)Object&amp;&nbsp; Workbooks().DispId</FONT><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispParams).cArgs = 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispParams).cNamedArgs = 0<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispatchObject) = (IDispatchComObject)(.arg $arg0).DispatchObject<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispatchPointer) = ((.var dispatchObject)).(IDispatchObject.GetDispatchPointerInCurrentApartment)(<BR>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .try {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .scope (<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Scripting.Com.ExcepInfo excepInfo<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.UInt32 argErr<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.Int32 hresult<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ) {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var hresult) = (<FONT color=#00ff00>UnsafeMethods.IDispatchInvoke</FONT>)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispatchPointer),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispId),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (INVOKEKIND)INVOKE_FUNC, INVOKE_PROPERTYGET,<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispParams),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var invokeResult),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var excepInfo),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var argErr),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (ComRuntimeHelpers.CheckThrowException)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var hresult),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var excepInfo),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var argErr),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; "Workbooks",<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var returnValue) = ((.var invokeResult)).(Variant.ToObject)()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } .finally {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((.var dispatchObject)).(IDispatchObject.ReleaseDispatchPointer)(<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (.var dispatchPointer),<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; )<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((.var invokeResult)).(Variant.Clear)()<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .return (.var returnValue);<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; }<BR>&nbsp;&nbsp;&nbsp; } .else {/*empty*/;<BR>&nbsp;&nbsp;&nbsp; }}</P></PRE>]]></content:encoded>
    </item>
    <item>
      <title>CLS compilation of IronPython</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/cls-compilation-of-ironpython</link>
      <pubDate>Thu, 24 Jul 2008 01:01:39 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/07/24/cls-compilation-of-ironpython/</guid>
      <description><![CDATA[One of the common feature requests for IronPython is to support static compilation. While the...]]></description>
      <content:encoded><![CDATA[<p>One of the common feature requests for IronPython is to support static compilation. While the feature looks like a no-brainer initially, it does have a few wrinkles when you look at the details. Here are the different forms that a related question might look like?</p> <ul> <li>Can I call IronPython code from C#?</li> <li>Can I statically compile my IronPython source code to a binary?</li> <li>Can I define <a href="http://msdn.microsoft.com/en-us/library/system.attribute.aspx">custom attributes</a> in IronPython?</li></ul> <h4>Terminology</h4> <p>This has several aspects related to compilation, with different folks caring about different aspects of the issue. To clarify the issues involved, here is the terminology I will use.</p> <ul> <li>Compiling to an assembly on disk - This is useful if you do not want to ship your source code. This by itself does not imply if the IL it contains is CLS compliant or not. IronPython 1.X does support this feature, and IronPython 2 will be restoring the feature in Beta 4 (due shortly).</li> <li>Generating CLS compliant IL - <a href="http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx">Common Language Specification</a> (CLS) specifies the requirements on IL (and metadata) so that it can be seamlessly consumed from other statically compiled languages like C# and VB.Net.&nbsp; IronPython normally generates mangled IL to implement all the dynamic features of Python which cannot be represented with CLS compliant IL in general. However, users are willing to put up with some restrictions in order to get CLS compliant code (which can be either on disk or in-memory).</li> <li>Calling IronPython code from C# - Many folks assumes this implies compilation of IronPython code, but this is not true. See the Alternatives section below.</li></ul> <h4>CLS compilation usage scenarios</h4> <p>This blog is about the CLS compliant compilation aspect. While CLS compliance is a nice goal by itself, it is interesting to think of the different ways that the generated IL could be consumed.</p> <ol> <li>Authoring .NET assemblies - The compiled assembly would be referenced from statically typed language like C# or VB.Net. This would be consumed using something like "csc /r:PythonWidgetAssembly.dll app.cs". The author of PythonWidgetAssembly.dll would probably want IronPython to support the full range of CLS features as she wants to use IronPython as a first-class languages completely on par with C# and VB.Net.</li> <li>Reflection on the generated assembly - This is used by tools like NUnit which look for all types in a test assembly with a given custom attribute. Similarly, a host might look in a plugin assembly for a type inherting from some known interface.</li> <li>Reflection on an object at runtime - Some .NET API might inspect its incoming argument object for a method with given name, or a property with a custom attribute. <a href="http://msdn.microsoft.com/en-us/library/bb425822.aspx">LINQ to SQL</a> looks for custom attributes like <a href="http://msdn.microsoft.com/en-us/library/system.data.linq.mapping.tableattribute.aspx">TableAttribute</a> on the class of the object being used in a LINQ query to determine how to map the LINQ query to a database operation. Normally, IL generanted by Python is mangled so that a Python class method does not really exist on instances of the Python class. Also, Python does not have a concept of custom attributes.</li></ol> <h4>Issues</h4> <ul> <li>First two usage patterns, you need to explicitly compile your Python code to an assembly. This takes away one of the important qualities of Python which is the ability to just run your source code (as "ipy.exe foo.py") without an extra compile step. In general, you want the code to have the same semantics irrespective of whether you precompile it to as assembly on disk, or not.</li> <li>Extensions to Python syntax - Expressing the full range of CLS features will need adding new syntax to IronPython. For example, Python has no syntax for accessibility of members (public, protected, private, internal, etc), method type like virtual or abstract, the type of arguments or the return type, custom attributes on assembly, types, methods, and arguments, specifying events, etc. See the description of <a href="http://msdn.microsoft.com/en-us/library/12a7a7h3.aspx">CLS</a> for the complete list. It could stay valid Python code by expressing the features as comments or interpreting existing Python elements in creative ways. But at some point, it will start becoming P# in appearance (ie. not quite Python). At that point, would you be better off writing those parts of your application in C# or VB.Net?</li> <li>Extensions to Python semantics - All Python name resolution is dynamic. For eg, if you had "System.Console.WriteLine("foo")", then the name "System" is usually resolved at runtime. For the first two usage patterns, IronPython would need to attempt to bind this at compile-time which does bend the rules. In general, IronPython's support of .NET is done in a very Pythonic way. IronPython code using .NET code can in theory also run under CPython if the .NET libraries were implemented as Python libraries. There is an experimental project called <a href="http://code.google.com/p/python-system/">Python-System</a> which attempts to do this. This would be a tall task, but the point is that IronPython has not bent the core semantics of the language.</li></ul> <h4>Alternatives</h4> <p>I do want to provide people with some possible alternative solutions that might work for their scenarios in the meantime</p> <ul> <li>Writing part of the application in C# or VB.Net, and then extending it from IronPython - For example, you could define the SQL-related types in C# or VB.Net so that you could set the custom attributes from the System.Data.Linq namespace. (This would not work as IronPython does not support authoring LINQ queries yet, but it illustrates the point)</li> <li>Using the <a href="http://compilerlab.members.winisp.net/dlr-spec-hosting.doc">DLR hosting APIs</a> to call into IronPython code from C# or VB.Net</li> <li>In the future, languages could possibly provide better support to call into IronPython as discussed in <a href="http://blogs.msdn.com/charlie/archive/2008/01/25/future-focus.aspx">this blog</a>.</li></ul> <h4>Conclusion</h4> <p>Usage 3 above (Reflection on an object at runtime) seems like the main issue to me as the user is not trying to persist an assembly to disk (which is not Pythonic). </p> <p>Also, some features might provide big bang for the buck (like custom attributes on types and members as required by LINQ to SQL), whereas supporting the full range of CLS features may not be warranted. I would be curious to hear of real world use-case of how people want to use "static compilation" to understand what the right design point is. </p> <p>If you have run into a wall with trying to use IronPython because of one of the issues above, do leave a comment about your exact scenario, which libraries were involved, what your workaround was, etc.</p>]]></content:encoded>
    </item>
    <item>
      <title>Signals on Windows</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/signals-on-windows</link>
      <pubDate>Fri, 23 May 2008 19:01:00 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/05/23/signals-on-windows/</guid>
      <description><![CDATA[While looking at signal support in IronRuby, I played with the signal and raise functions that are...]]></description>
      <content:encoded><![CDATA[<P>While looking at signal support in IronRuby, I played with the <A href="http://msdn.microsoft.com/en-us/library/xdkz3x12(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/xdkz3x12(VS.71).aspx">signal</A> and <A href="http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx" mce_href="http://msdn.microsoft.com/en-us/library/dwwzkt4c(VS.71).aspx">raise</A> functions that are available in the C runtime. It turns out that these functions are much more limited than their Unix counterparts. On Unix, <A href="http://en.wikipedia.org/wiki/Kill_%28Unix%29" mce_href="http://en.wikipedia.org/wiki/Kill_%28Unix%29">kill</A> can be used to send a signal to another process, enabling cross-process communication.</P>
<P>However, the CRT raise function does not take a process id. It can only send a synchronous signal on the same thread to the process it is being called from. This does not seem to be of much use. SIGINT (Ctrl-C) can also be dealt with using <A href="http://msdn.microsoft.com/en-us/library/ms686016.aspx" mce_href="http://msdn.microsoft.com/en-us/library/ms686016.aspx">SetConsoleCtrlHandler</A> in unmanaged code, or <A href="http://msdn.microsoft.com/en-us/library/system.console.cancelkeypress.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.console.cancelkeypress.aspx">Console.CancelKeyPress</A> in managed code, and the Windows runs the handler on a separate thread. SIGILL, SIGSEGV, and SIGTERM are not generated on Windows NT. So that only leaves SIGABRT and SIGFPE. Not sure how important these are.</P>
<P>If asynchronous signals were truly supported on existing threads, this would present challenges to using managed code to handle the signals. The thread may not be in an interruptible state when the handler is run. If the handler triggers a GC or stack-walk, that would cause trouble. Also, running managed code can allocate memory since the code may not have been JITed. Doing such heavy-weight operations in the handler would also lead to trouble. <A class="" href="http://www.python.org/doc/2.4/lib/module-signal.html" mce_href="http://www.python.org/doc/2.4/lib/module-signal.html">Python</A> ("they can only occur between the ``atomic'' instructions of the Python interpreter") and <A class="" href="http://perldoc.perl.org/perlipc.html#Deferred-Signals-(Safe-Signals)" mce_href="http://perldoc.perl.org/perlipc.html#Deferred-Signals-(Safe-Signals)">Perl</A> ("to avoid these problems signals are deferred") seem to defer running of the signal handler from a safe point, or run it on a <A class="" href="http://www.xav.com/perl/lib/Thread/Signal.html" mce_href="http://www.xav.com/perl/lib/Thread/Signal.html">new thread </A>like SIGINT on Windows.</P>
<P>I am attaching a test case to use signals from managed code if anyone wants to play with it. All handlers are run synchronously. Ctrl-C is run asynchronously but on a new thread.</P>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/08/54/23/13/signal.cs" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-54-23-13/signal.cs">signal.cs</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Accessing IronPython objects from native JScript (using IReflect)</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/accessing-ironpython-objects-from-native-jscript-using-ireflect</link>
      <pubDate>Tue, 13 May 2008 17:29:00 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/05/13/accessing-ironpython-objects-from-native-jscript-using-ireflect/</guid>
      <description><![CDATA[The DLR aims to enable dynamic languages like IronPython and IronRuby to access and minipulate...]]></description>
      <content:encoded><![CDATA[<P>The DLR aims to enable dynamic languages like <A href="http://www.codeplex.com/IronPython" mce_href="http://www.codeplex.com/IronPython">IronPython</A> and <A href="http://ironruby.rubyforge.org/" mce_href="http://ironruby.rubyforge.org/">IronRuby</A> to access and minipulate objects created by each other. But what about dynamic languages like JScript implemented using unmanaged code? It is sometimes useful for IronPython and native JScript to interact with each other. Consider the following scenarios:</P>
<UL>
<LI>IronPython could be used to host a <A href="http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.windows.forms.webbrowser.aspx">System.Windows.Forms.WebBrowser</A> control which loads a Web page with native JScript. See <A href="http://msdn.microsoft.com/en-us/library/a0746166.aspx" mce_href="http://msdn.microsoft.com/en-us/library/a0746166.aspx">this MSDN article</A> for a description of the WebBrowser control. Srivatsn discusses some of the issues related to using it from IronPython <A href="http://blogs.msdn.com/srivatsn/archive/2008/05/09/accessing-ironpython-objects-from-native-javascript.aspx" mce_href="http://blogs.msdn.com/srivatsn/archive/2008/05/09/accessing-ironpython-objects-from-native-javascript.aspx">here</A>.</LI>
<LI>Native Web browser JScript could talk with <A href="http://silverlight.net/learn/dynamiclanguages.aspx/" mce_href="http://silverlight.net/learn/dynamiclanguages.aspx/">IronPython running in a Silverlight 2 application</A> embedded in the Web page. (Note that unfortunately, this scenario will not currently work. See "Issues and Limitations" #1 below.)</LI>
<LI>VBA macros running inside Office could load and run IronPython scripts.</LI></UL>
<P>IronPython is now able to access native JScript objects because of the <A href="http://blogs.msdn.com/shrib/archive/2008/04/10/ole-automation-idispatch-support-in-ironpython.aspx" mce_href="http://blogs.msdn.com/shrib/archive/2008/04/10/ole-automation-idispatch-support-in-ironpython.aspx">IDispatch support</A> we have added to the DLR.</P>
<P>For the reverse direction of native JScript accessing IronPython objects, the IronPython objects need to be marshalled to unmanaged code as <A href="http://msdn2.microsoft.com/en-us/library/ms221608.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/ms221608.aspx">IDispatch</A> (and ideally also <A href="http://msdn.microsoft.com/en-us/library/sky96ah7(VS.85).aspx" mce_href="http://msdn.microsoft.com/en-us/library/sky96ah7(VS.85).aspx">IDispatchEx</A>). I had <A href="http://blogs.msdn.com/shrib/archive/2007/09/04/ireflect-and-idispatch.aspx" mce_href="http://blogs.msdn.com/shrib/archive/2007/09/04/ireflect-and-idispatch.aspx">previously discussed</A> how managed types can implement <A href="http://msdn2.microsoft.com/en-us/library/system.reflection.ireflect.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.reflection.ireflect.aspx">System.Reflection.IReflect</A> to be marshalled as IDispatch. Reading Srivatsn's blog, I decided to see how I could build on this IReflect &lt;-&gt; IDispatch mapping. This turns out to be fairly straightforward. I have implemented a Python modules called IReflectUtils. This allows an IronPython class to trivally indicate that it wants to make itself accessible to native JScript. The IronPython class declaration looks like the following:</P>
<BLOCKQUOTE>
<P><FONT face="Courier New">from IReflectUtils import IReflectBase </FONT>
<P><FONT face="Courier New">class TestClass(IReflectBase):<BR>&nbsp;&nbsp;&nbsp; def foo(self):<BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; print "In TestClass.foo"</FONT><FONT face="Courier New">&nbsp;</FONT></P></BLOCKQUOTE>
<P>All it takes is inheriting from a single class IReflectBase. No other change is needed. At that point, the Python class becomes accessible from native JScript. JScript can invoke any of the methods of the Python class, including dynamically added methods. JScript can also read and write any of the attributes defined on the object. Tada!</P>
<P>Note that because of a bug in IronPython, IReflectBase needs to be the first base type specified. So the class declaration in <A href="http://blogs.msdn.com/srivatsn/archive/2008/05/09/accessing-ironpython-objects-from-native-javascript.aspx" mce_href="http://blogs.msdn.com/srivatsn/archive/2008/05/09/accessing-ironpython-objects-from-native-javascript.aspx">Srivatsn's blog</A> would become:</P>
<BLOCKQUOTE>
<P><FONT face="Courier New">class MyForm(IReflectBase, Form):</FONT></P></BLOCKQUOTE>
<H4>How it works</H4>
<P>Under the hoods, IReflectBase implements IReflect. It needs to implement the following two main functions:</P>
<UL>
<LI><A href="http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethods.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethods.aspx">IReflect.GetMethods</A> - this is implemented by calling "dir" on the object and returning all the attributes as method names. The function needs to return the method names as an array of MethodInfo, and so we have to create a subtype of MethodInfo which basically just knows the name it corresponds to.</LI>
<LI><A href="http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethods.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethods.aspx">IReflect.InvokeMember</A> - this turns into a "getattr(target, name)", possibly followed by a call to the returned object. The invokeAttr parameter that is passed into the method indicates whether the Python attribute should just be returned (if <A href="http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.reflection.bindingflags.aspx">BindingFlags</A>.GetProperty is set), or if it should be invoked (if BindingFlags.InvokeMethod is set)</LI></UL>
<H4>Issues and limitations</H4>
<OL>
<LI>This solution will not work on Silverlight 2 which currently does not include any COM Support. Hence, it does not support the IReflect &lt;-&gt; IDispatch mapping. It would be possible to port this functionality from .NET Frameworks to a future version of Silverlight.</LI>
<LI>This solution will only work with IE, since only Microsoft's JScript implementation is based on IDispatch. Firefox's implementation uses a similar but different interface that is part of XPCOM. I do not what the XPCOM interface looks like, but if it is similar to IDispatch, it should be possible to map IReflect to it as well.</LI>
<LI>Python classes with __getattribute__ will not work. The CLR calls IReflect.GetMethodNames to get a full list of methods supported by the object. This is different than IDispatch.GetIDsOfNames which only supports querying whether a single given method is supported or not (which is similar to how __getattribute__ works). Because of this, such Python classes will not be able to expose all the method names that __getattribute__ recognizes. IReflect does have a <A href="http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethod.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.reflection.ireflect.getmethod.aspx">GetMethod</A> method that could have been used to query whether a specific method existed, but the IReflect &lt;-&gt; IDispatch mapping does not use this. A theoretical solution is for IReflect.GetMethodNames to return the complete infinite set of all character combinations, but this does not really work. Ruby's method_missing will run into the same issue. This will need a creative fix to the IReflect &lt;-&gt; IDispatch mapping, or for a new interface to be added to the CLR which more closely follows the IDispatch model.</LI>
<LI>This feature could be shipped in different ways. The attached sample show a simple Python module. This could even be used with <A href="http://www.codeplex.com/IronPython/Wiki/View.aspx?title=v1.1.1%20Release%20Notes&amp;referringTitle=Home" mce_href="http://www.codeplex.com/IronPython/Wiki/View.aspx?title=v1.1.1%20Release%20Notes&amp;referringTitle=Home">IronPython 1.X</A>. However, it requires that all Python classes explicitly opt in, which may not work well for large existing code bases. Also, builtin types with dynamic behavior implemented by IronPython.dll will not work as the user cannot make them implement IReflect. The feature could be built into the IronPython runtime so that all IronPython user-defined classes would implicitly inherit from IReflect, and any builtin types could be made to implement IReflect.</LI>
<LI>The current solution relies on inheriting from IReflect (via IReflectBase). This can lead to name collisions if the user defines method with names which are the same as some significant IReflect method.</LI>
<LI>VBScript does not require the use of paranthesis while calling a method with no arguments. This makes ambiguous the syntax for an instance method call and a property access. This can cause some issues since the IReflect.InvokeMember needs to know whether a property should be accessed or if the attribute should be invoked. Similarly, VBScript and IDispatch are case-insensitive whereas Python is case-sensitive. The IReflect &lt;-&gt; IDispatch mapping seems to do a case-insensitive search and randomly picking an attribute if there are multiple matches.</LI>
<LI>We could support richer interaction between managed and unmanaged dynamic languages by taking advantage of the <A href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.expando.iexpando.aspx" mce_href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.expando.iexpando.aspx">System.Runtime.InteropServices.Expando.IExpando</A> &lt;-&gt; IDispatchEx mapping that the CLR supports. This would allow addition and deletion of attributes. This is currently left as an exercise for the user. Also, note that this feature has bugs in it, and the support may not be sufficient for all the scenarios you would care about.</LI></OL>
<H4>About the attached file</H4>
<P>IReflectUtils.zip contains the following files:</P>
<UL>
<LI>IReflectUtils.py - The main Python module file. This file can be used in your own IronPython projects.</LI>
<LI>TestClass.py - A sample Python class that inherits from IReflectUtils.py</LI>
<LI>ManagedFactory.cs - A bridge between test.js/test.vbs and TestClass.py. It includes a class that is ComVisible and hence can be instantiated by test.js and test.vbs. The class loads TestClass.py and passes the IronPython object back to test.js and test.vbs. See the top of the file for instructions on compiling and registering the file.</LI>
<LI>test.js and test.vbs - The driver files which instantiate ManagedFactory, use it to get an IronPython object, and then access the object. See the top of the file for instructions on running the files.</LI></UL>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/08/50/18/16/IReflectUtils.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-08-50-18-16/IReflectUtils.zip">IReflectUtils.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>OLE automation (IDispatch) support in IronPython</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/ole-automation-idispatch-support-in-ironpython</link>
      <pubDate>Thu, 10 Apr 2008 17:57:52 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/04/10/ole-automation-idispatch-support-in-ironpython/</guid>
      <description><![CDATA[IronPython 1.X IronPython 1.X supported COM interop by building on top of the COM interop support...]]></description>
      <content:encoded><![CDATA[<h3>IronPython 1.X</h3> <p>IronPython 1.X supported COM interop by building on top of the <a href="http://msdn2.microsoft.com/en-us/library/6bw51z5z(VS.80).aspx">COM interop</a> support built into the CLR. This relies on the use of interop assemblies for managed code to access COM objects. The interop assembly can be accessed in different ways:</p> <ol> <li>clr.AddReference("interopAssembly") - This is the preferred mechanism so that the interop assembly does not have to be created multiple times. The down-side is that it complicates deployment. You have to <a href="http://msdn2.microsoft.com/en-us/library/697w37zd(VS.80).aspx">ensure</a> that the interop assembly exists on the machine.  <li>Having IronPython automatically generate it on the fly - if you have a OLE automation object, IronPython tries to find its type library (TLB) and then to convert the TLB to an interop assembly on the fly using the <a href="http://msdn2.microsoft.com/en-us/library/system.runtime.interopservices.typelibconverter(VS.80).aspx">TypeLibConverter</a> class. The advantage is that this works seamlessly as long as there is a type library on the machine. The down-side is that this conversion can take a long time for large TLB files.</li></ol> <p>This is how Word could be accessed in IronPython 1.X. It requires the interop assembly Microsoft.Office.Interop.Word.dll to be available on the machine.</p> <blockquote> <p><font face="Courier New">c:\&gt;ipy.exe<br>IronPython 2.0 Beta (2.0.0.1000) on .NET 2.0.50727.1433<br>Copyright (c) Microsoft Corporation. All rights reserved.<br>&gt;&gt;&gt; import clr<br>&gt;&gt;&gt; clr.AddReference("Microsoft.Office.Interop.Word") # load interop assembly<br>&gt;&gt;&gt; from Microsoft.Office.Interop.Word import ApplicationClass<br>&gt;&gt;&gt; word = ApplicationClass() # load class defined in interop assembly<br>&gt;&gt;&gt; word.Visible = True # this works via CLR's COM interop support<br>&gt;&gt;&gt; doc = word.Documents.Add()<br>&gt;&gt;&gt; doc.Range().Text = "Hello from IronPython"<br>&gt;&gt;&gt; word.Quit()<br>&gt;&gt;&gt;</font></p></blockquote> <h3>IronPython 2.0</h3> <p>IronPython 2.0 has added support for interacting with OLE automation objects using the IDispatch interface. This completely eliminates the need for interop assemblies. This is the same mechanism that <a href="http://msdn2.microsoft.com/en-us/isv/bb190538.aspx">VBA</a> late-bound code and also <a href="http://msdn2.microsoft.com/en-us/library/9bbdkx3k.aspx">WSH</a> use to interact with OLE automation object. This feature can currently be accessed using the -X:PreferComDispatch command line option.</p> <p>Here is an interactive session showing access to Word. There are no interop assemblies in the picture.</p> <blockquote> <p><font face="Courier New">c:\&gt;ipy.exe -X:PreferComDispatch<br>IronPython 2.0 Beta (2.0.0.1000) on .NET 2.0.50727.1433<br>Copyright (c) Microsoft Corporation. All rights reserved.<br>&gt;&gt;&gt; import clr<br>&gt;&gt;&gt; import System<br>&gt;&gt;&gt; wordTypeLibGuid = System.Guid("00020905-0000-0000-C000-000000000046")<br>&gt;&gt;&gt; clr.AddReferenceToTypeLibrary(wordTypeLibGuid)<br>&gt;&gt;&gt; from Word import Application<br>&gt;&gt;&gt; word = Application() # this uses Type.GetTypeFromCLSID and Activator.CreateInstance under the hood</font><font face="Courier New"><br>&gt;&gt;&gt; word.Visible = True # this uses IDispatch.Invoke<br>&gt;&gt;&gt; doc = word.Documents.Add()<br>&gt;&gt;&gt; doc.Range().Text = "Hello from IronPython"<br>&gt;&gt;&gt; word.Quit()<br>&gt;&gt;&gt;</font></p></blockquote> <p>The feature is not complete yet, and so is not currently (April 08) enabled by default. The default behavior is still the same as IronPython 1.X. I can't say for sure when we will enable it by default, but its already quite stable for many real-world uses. We run all of our COM tests in both modes - using interop assemblies and using IDispatch. There are a few differences between the two cases in the minute details, but the mainline scenarios work well in both. This feature is implemented in the DLR, and so should be accessible from all DLR-based languages with little effort on the part of the language-implementors.</p>]]></content:encoded>
    </item>
    <item>
      <title>What if a C# snippet does not work when transliterated to IronPython?</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/what-if-a-c-snippet-does-not-work-when-transliterated-to-ironpython</link>
      <pubDate>Mon, 24 Mar 2008 17:54:49 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/03/24/what-if-a-c-snippet-does-not-work-when-transliterated-to-ironpython/</guid>
      <description><![CDATA[Say you have a working piece of C# code. You want to include it in your IronPython app. So you...]]></description>
      <content:encoded><![CDATA[<p>Say you have a working piece of C# code. You want to include it in your IronPython app. So you transliterate it to IronPython code. And it stops working. What do you do?</p> <p>You might feel lost at this point since the IronPython code is "supposed" to work. You have the following options:</p> <ol> <li>The first step ofcourse is to double-check your transliteration.</li> <p>&nbsp;</p> <li>The next step is simple but sometimes not obvious when you are in the middle of many other ongoing issues. This solution is to convert the C# code a function at a time to IronPython, or even a line at a time if needed. C# and IronPython can call each other very easily. So its easy to move small pieces of C# code over to IronPython. At every step, you check that the combined code works. You can use a binary search by speculatively moving bug chunks of code from C# to IronPython, and backing off when such a move exposes a problem. You will hopefully be able to narrow the problem down to a single line of IronPython code, which you can leave in C# until you figure out why IronPython cannot deal with it. </li> <p>This isnt a perfect solution. Some problems can be non-deterministic, and the problem might repro at random times. However, in many cases, you will be able to narrow down the problem to a single line of IronPython code.</p> <li>You could manually write C# code that uses Reflection.Emit to do the same work as the original C# code (once you have narrowed down the issue to a few line of code). IronPython code also gets compiled to Reflection.Emit code on the fly. Any issues that affect Reflection.Emit will be surfaced by your C# + Ref.Emit code.</li></ol>]]></content:encoded>
    </item>
    <item>
      <title>IronPython cannot call AutomationElement.FromHandle</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/ironpython-cannot-call-automationelement-fromhandle</link>
      <pubDate>Mon, 24 Mar 2008 02:10:20 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2008/03/24/ironpython-cannot-call-automationelement-fromhandle/</guid>
      <description><![CDATA[If you use IronPython to call AutomationElement.FromHandle, it will return null. This happens...]]></description>
      <content:encoded><![CDATA[<p>If you use IronPython to call <a href="http://msdn2.microsoft.com/en-us/library/system.windows.automation.automationelement.fromhandle.aspx">AutomationElement.FromHandle</a>, it will return null. This happens because FromHandle uses <a href="http://msdn2.microsoft.com/en-us/library/system.reflection.assembly.getcallingassembly(vs.85).aspx">Assembly.GetCallingAssembly</a> and expects to get a statically compiled assembly with references to the correct version of the UIAutomation libraries. However, since IronPython code gets compiled on the fly using Reflection.Emit and DynamicMethods, it confuses AutomationElement.</p> <p>This UIAutomation team knows about the issue and will be fixing it. I am not sure which particular release will have the fix. The workaround is to narrow down the specific call which is failing, and then perform that call from C#/VB.Net assembly.</p> <p>I had added this comment to the Assembly.GetCallingAssembly docs. I am including it here to explain the details of the problem</p> <blockquote> <p>The common case is for the caller to have directly called currently executing method. However, the caller may have invoked the currently executing method via a delegate, or in a late-bound way using MethodBase.Invoke. The delegate or the MethodInfo might have been created by one assembly, and then another assembly could have invoked it. GetCallingAssembly will not indicate who created the delegate or the MethodInfo. So if you use GetCallingAssembly to make security decisions, you will need to be extremely careful to ensure that you handle the cases of late-bound invocation. <p>Another unusual case is if the caller is a DynamicMethod. Since DynamicMethods can potentially be associated with arbitrary assemblies during creating, GetCallingAssembly will return the associated assembly.</p></blockquote>]]></content:encoded>
    </item>
    <item>
      <title>Saving a file to the local disk in Silverlight</title>
      <link>https://docs.microsoft.com/archive/blogs/shrib/saving-a-file-to-the-local-disk-in-silverlight</link>
      <pubDate>Tue, 25 Sep 2007 00:10:00 GMT</pubDate>
      <dc:creator><![CDATA[shrib]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/shrib/2007/09/25/saving-a-file-to-the-local-disk-in-silverlight/</guid>
      <description><![CDATA[All user code in Silverlight runs in a sandbox. Hence, for security reasons, there are no APIs to...]]></description>
      <content:encoded><![CDATA[<P>All user code in Silverlight runs in a sandbox. Hence, for security reasons, there are no APIs to directly open local files from disk. However, there is a OpenFileDialog class which allows a Silverlight app to open files on disk. Human intervention is required to interact with the dialog box. This ensures that the user trusts the app to open the files selected in the dialog box.</P>
<P>However, currently there is no equivalent to writing to a file to disk, even if the user wants to allow such an operation. This is unfortunate. If you implemented a text or image editor in Silverlight, the user would not be able to save the edited file to disk. However, there is a workaround -&nbsp;but at the cost of extra network traffic. The solution involves the following steps:</P>
<UL>
<LI>The Silverlight client app running in the browser sends the data that needs to be saved to disk to the web server using a POST operation using System.Windows.Browser.Net.BrowerHttpWebRequest::GetResponse</LI>
<LI>The web server saves the data to a temporary file and returns a URL for the temporary file in the response</LI>
<LI>The Silverlight client app reads the URL that is returned in the System.Net.HttpWebResponse object.</LI>
<LI>It navigates to the URL using System.Windows.Browser.HtmlPage::Navigate.</LI>
<LI>This will result in the browser invoking the default action for the given file type. This is often to prompt the user to save the file to disk. If the browser opens the file directly, the user could then have the browser save the file to disk. If multiple files need to be saved, the web server could save them all in a zip file using System.IO.Compression.GZipStream.</LI></UL>
<P>This solution is obviously not ideal as it result in unnecessarily sending the data back and forth over the network. For large files, this could be prohibitive. For small files, its a reasonable solution until there is a SaveFileDialog API in Silverlight.</P>
<P>I do not know if there will be a SaveFileDialog in Silverlight 1.1, but I hear that the Silverlight team is looking into it...</P>]]></content:encoded>
    </item>
  </channel>
</rss>