title: Get target file path from custom action
body: <p>How can I get a path to file being installed from a <a href="http://en.wikipedia.org/wiki/WiX" rel="nofollow">WiX</a> custom action?</p>
  
  <p>I'm creating a <em>WIX Extension</em>, which has a custom element which can be nested under <code>&lt;File&gt;</code> component like this:</p>
  
  <pre><code>&lt;Component Id="FooComponent"&gt;
     &lt;File Id="filekey" Name="foo.txt"&gt;
         &lt;myextension:Stuff /&gt;
     &lt;/File&gt;
  &lt;/Component&gt;
  </code></pre>
  
  <p>The extension has its custom table which has a foreign key columns pointing to "Component" and "File" tables, and it is executed when a file's component is being installed/uninstalled (like the built-in IIS extension or SQL extension for example)</p>
  
  <p>What I want to achieve is, in my deferred (sheduled) custom action, figure out the target path of the file the extension isbound to. I.e. basically in the differed custom action, I want to get value of <code>[!filekey]</code> (in terms of MSI <a href="https://msdn.microsoft.com/en-us/library/aa368609.aspx" rel="nofollow">formatted</a> string). How can I go about that?</p>
  
  <p>I have found a somewhat similar topic <a href="https://social.msdn.microsoft.com/Forums/en-US/b92a2147-92b4-450f-946d-f468e5c6558e/how-to-find-component-path-in-windows-installer-custom-action?forum=winformssetup" rel="nofollow">here</a></p>
  
  <p>One of the solutions suggested was to use <code>MsiFormatRecord</code> from a custom action and pass that <code>[#filekey]</code> to that function. It resolves properly then.</p>
  
  <p>I've found examples of using this approach in WiX sources, in gaming extension and NetFX extensions; they use code like this:</p>
  
  <pre><code>    StrAllocFormatted(&amp;pwzFormattedFile, L"[#%s]", pwzFileId);
      WcaGetFormattedString(pwzFormattedFile, &amp;pwzGamePath);
  </code></pre>
  
  <p>Here <code>WcaGetFormattedString</code> is basically a wrapper for <code>MsiFormatRecord</code></p>
  
  <p>Still unanswered, is this a right approach to the issue?</p>