<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Luca Salvarani</title>
    <description>The latest articles on DEV Community by Luca Salvarani (@lukesavefrogs).</description>
    <link>https://dev.to/lukesavefrogs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F657551%2F985a25d0-20cd-4a1a-84bf-30a9f414115f.jpeg</url>
      <title>DEV Community: Luca Salvarani</title>
      <link>https://dev.to/lukesavefrogs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/lukesavefrogs"/>
    <language>en</language>
    <item>
      <title>Introduction to COM</title>
      <dc:creator>Luca Salvarani</dc:creator>
      <pubDate>Wed, 02 Nov 2022 15:48:47 +0000</pubDate>
      <link>https://dev.to/lukesavefrogs/introduction-to-com-1f02</link>
      <guid>https://dev.to/lukesavefrogs/introduction-to-com-1f02</guid>
      <description>&lt;p&gt;This will be the first post of a series i intend to write in order to challenge myself and share my knowledge about COM automation on Windows.&lt;/p&gt;

&lt;h2&gt;
  
  
  Useful sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Early vs Late binding:

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/a/70821925/8965861"&gt;this&lt;/a&gt; and &lt;a href="https://stackoverflow.com/questions/50127959/win32-dispatch-vs-win32-gencache-in-python-what-are-the-pros-and-cons"&gt;this&lt;/a&gt; SO answers&lt;/li&gt;
&lt;li&gt;"&lt;a href="http://www.icodeguru.com/WebServer/Python-Programming-on-Win32/ch12.htm#:~:text=Forcing%20Early%20or%20Late%20Binding"&gt;Python Programming on Win32&lt;/a&gt;" book (&lt;em&gt;Andy Robinson, Mark Hammond&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartClientCom.html#StaticDispatch"&gt;pywin32 docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;"&lt;a href="https://www.youtube.com/watch?v=xPtp8qFAHuA"&gt;Early Vs Late Binding In Win32Com&lt;/a&gt;" Youtube video (by "Sigma Coding")&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;API references:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://learn.microsoft.com/en-us/office/vba/api/overview"&gt;Office Suite VBA Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Use COM &lt;a href="http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartClientCom.html#UsingComConstants:~:text=of%20the%20object.-,Using%20COM%20Constants,-Makepy%20automatically%20installs"&gt;Constants&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Tutorials:

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=MTFCV2qbAIw&amp;amp;list=PLcFcktZ0wnNkHGYuS-p8wUu7SrzO7TKR3"&gt;Python - Win32COM - Core Concepts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/playlist?list=PLHnSLOMOPT11njaNmENJN6p2ro9MTc7t_"&gt;Python Outlook Automation | pywin32&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>excel</category>
      <category>automation</category>
      <category>python</category>
      <category>win32com</category>
    </item>
    <item>
      <title>Basic operations</title>
      <dc:creator>Luca Salvarani</dc:creator>
      <pubDate>Sun, 30 Oct 2022 14:41:39 +0000</pubDate>
      <link>https://dev.to/lukesavefrogs/basic-operations-4oom</link>
      <guid>https://dev.to/lukesavefrogs/basic-operations-4oom</guid>
      <description>&lt;p&gt;Let's dive into the basic operations...&lt;/p&gt;

&lt;h2&gt;
  
  
  Dispatch methods
&lt;/h2&gt;

&lt;p&gt;A COM object can be created in various ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;code&gt;win32com.client.Dispatch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;win32com.client.DispatchEx&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;win32com.client.DispatchWithEvents&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;win32com.client.dynamic.Dispatch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;win32com.client.gencache.EnsureDispatch&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. &lt;code&gt;win32com.client.Dispatch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This is the &lt;strong&gt;most common&lt;/strong&gt; way to start an instance of a COM object.&lt;br&gt;
It tries to automatically detect and use the best dispatching method (early or late binding). &lt;br&gt;
In fact, behind the scenes, this method uses &lt;code&gt;dynamic.Dispatch&lt;/code&gt; or &lt;code&gt;gencache.EnsureDispatch&lt;/code&gt;. The order in which the dispatch types are tested is the following (the first valid dispatch is returned):&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Early binding&lt;/strong&gt; (also called "Static Dispatch") if possible&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Late binding&lt;/strong&gt; (also called "Dynamic Dispatch") otherwise
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;win32com&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="n"&gt;excel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Excel.Application'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2. &lt;code&gt;win32com.client.DispatchEx&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Same as &lt;code&gt;win32com.client.Dispatch&lt;/code&gt;, but allows to create a DCOM object on a &lt;strong&gt;remote machine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, in the following code snippet, we will open Excel on the server with IP &lt;em&gt;192.168.1.17&lt;/em&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;win32com&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="n"&gt;server_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s"&gt;"192.168.1.17"&lt;/span&gt;
&lt;span class="n"&gt;excel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DispatchEx&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Excel.Application'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;server_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. &lt;code&gt;win32com.client.DispatchWithEvents&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Same as &lt;code&gt;win32com.client.Dispatch&lt;/code&gt;, but allows to respond to &lt;strong&gt;events triggered by the application&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example, in the following code a message will be printed on screen every time a user performs a &lt;em&gt;double click&lt;/em&gt; on a cell:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;win32com&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;ExcelEvents&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;BeforeDoubleClick&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Target&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Cancel&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;"A double click has occurred"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;excel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DispatchWithEvents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Excel.Application'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ExcelEvents&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. &lt;code&gt;win32com.client.dynamic.Dispatch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This method completely bypasses the COM cache, directly querying the object instead. &lt;a href="https://groups.google.com/g/xsi_list/c/NSV-e-thdtY/m/d9Vp49sZAzUJ"&gt;It can solve some problems with the cache&lt;/a&gt;, but it is slower and is subject to application rules (for example in Excel everything is case insensitive, so &lt;code&gt;excel.VISIBLE&lt;/code&gt; is equal to &lt;code&gt;excel.Visible&lt;/code&gt;) but it can&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;win32com&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="n"&gt;excel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;dynamic&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Dispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Excel.Application'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;PRO:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Case insensitive&lt;/em&gt; lookup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CONS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Slower&lt;/em&gt; than &lt;code&gt;gencache.EnsureDispatch&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  5. &lt;code&gt;win32com.client.gencache.EnsureDispatch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;This method forces the use/creation of the cache.&lt;/p&gt;

&lt;p&gt;The cache can be found inside the folder: &lt;code&gt;C:\Users\{USERNAME}\AppData\Local\Temp\gen_py&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;win32com&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;

&lt;span class="n"&gt;excel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;gencache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnsureDispatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;'Excel.Application'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Known bugs
&lt;/h4&gt;

&lt;p&gt;Using this method you might encounter &lt;a href="https://stackoverflow.com/a/51993953/8965861"&gt;some bugs&lt;/a&gt; involving the cache, like the infamous &lt;code&gt;AttributeError: 'module' object has no attribute 'CLSIDToPackageMap'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This problem in particular can be solved in two ways:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://stackoverflow.com/a/66910869/8965861"&gt;deleting&lt;/a&gt; the cache folder (&lt;code&gt;%TEMP%/gen_py&lt;/code&gt;) so that the next call to &lt;code&gt;EnsureDispatch&lt;/code&gt; will trigger a cache refresh;&lt;/li&gt;
&lt;li&gt;forcing a &lt;a href="https://stackoverflow.com/a/66910869/8965861"&gt;cache refresh&lt;/a&gt; yourself;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then all you need to do is running again the &lt;code&gt;client.gencache.EnsureDispatch&lt;/code&gt; function and you'll be good to go!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PRO:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Faster&lt;/em&gt; than &lt;code&gt;dynamic.Dispatch&lt;/code&gt; thanks to the cache&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CONS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More subject to &lt;em&gt;errors&lt;/em&gt; (most notably the &lt;code&gt;AttributeError&lt;/code&gt; cited before) caused by the cache&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>excel</category>
      <category>automation</category>
      <category>python</category>
      <category>com</category>
    </item>
  </channel>
</rss>
