0

I have got problem with custom actions in my project. Some are working, some not. I have got two projects C# CustomAction Project and Setup Project in VS 2012. My custom actions look like this. The two first actions are not causing the problem. Only the third one is not working.

[CustomAction]
public static ActionResult WriteToConfigStore(Session session)
{
    ...
}

[CustomAction]
public static ActionResult CleanConfigStore(Session session)
{
    ...
}

[CustomAction]
public static ActionResult CheckPrograms(Session session)
{
    string s = "";

    Process[] p = Process.GetProcesses();

    foreach (Process ps in p)
    {
        s += ps.ProcessName + ";";
    }

    MessageBox.Show(s);

    return ActionResult.Success;
}

I defining custom actions like this:

<Binary Id="CustomActionsId" SourceFile="$(var.ResourcesDir)\DriverCA.CA.dll" />
<CustomAction Id="ca_writeToConfigStoreId" BinaryKey="CustomActionsId" DllEntry="WriteToConfigStore" Execute="deferred" Return="check" />
<CustomAction Id="ca_cleanConfigStoreId" BinaryKey="CustomActionsId" DllEntry="CleanConfigStore" Execute="deferred" Return="check" />
<CustomAction Id="ca_setParameter" Return="check" Property="ca_writeToConfigStoreId" Value="param1=.;param2=;param3=;param4=;param5=IviDriver1.0, IviSwtch1.0" />
<CustomAction Id="ca_setCleanParameter" Return="check" Property="ca_cleanConfigStoreId" Value="param1=;" />
<CustomAction Id="ca_checkProgramsId" BinaryKey="CustomActionsId" DllEntry="CheckPrograms" Execute="deferred" Return="check" />

My install sequence is looking like this:

<InstallExecuteSequence>
  <Custom Action="ca_setParameter" Before="InstallFinalize" />
  <Custom Action="ca_setCleanParameter" Before="InstallFinalize" />
  <!--Call only when not uninstall (install, change, repair)--> 
  <Custom Action="ca_writeToConfigStoreId" After="ca_setParameter">NOT(REMOVE="ALL")</Custom>
  <!--Call only when uninstall or upgrade--> 
  <Custom Action="ca_cleanConfigStoreId" After="ca_setCleanParameter">REMOVE="ALL"</Custom>
  <!--Call only when not install--> 
  <Custom Action="ca_checkProgramsId" After="MsiUnpublishAssemblies">Installed</Custom>
</InstallExecuteSequence>

When I comment <Custom Action="ca_checkProgramsId" After="MsiUnpublishAssemblies">Installed</Custom> everything works fine. But when this part is not commented out, then I got error There is problem with this Windows Installer package. A DLL required for this install to complete could not be run. when uninstalling the program. I can't see any error. Every name and ID are correct. I am not using PInvoke or anything like that.

UPDATE: The goal of custom action is to check if some processes are running or not and interrup uninstall process according to it. Setup is per system and I didn't have problem problem with message boxes in any other custom actions. I solved it with another custom action project that have problem custom action in it by itself, but otherwise I am using exactly same methods and setup definitions (excluding another dll definition of course) Still don't know what the problem is.

benderto
  • 896
  • 11
  • 39

2 Answers2

0

A few things that might help:

You may need privilege to enumerate processes on the system - I can't tell if your setup is per user (and therefore not elevated) or per system (and elevated through an elevation prompt).

I'm not sure that you can do a MessageBox.Show if the custom actions are elevated (and running with the system account) because exposing a Windows message loop to the desktop is a security hole.

What do you think is the issue that after MsiPublishAssemblies is solving? It's not obvious to me why you think that helps. I don't think it's related to the problem unless your code actually has a dependency on an assembly in the GAC because it won't be installed until InstallFinalize (which is what really matters, not publishing assemblies).

PhilDW
  • 20,260
  • 1
  • 18
  • 28
  • MsiPublishAssemblies runs in the commit phase so scheduling 'after' it is actually likely to be 'before' it as all deferred comes before commits. – Christopher Painter Jan 15 '15 at 00:57
  • Setup is per system and I didn't have problem problem with message boxes in any other custom actions. I updated my question. – benderto Jan 15 '15 at 08:41
  • The issue is still that it's your code that is failing so you need to debug the actual point of failure in the code, the line that crashes. I would still suspect MessageBox because of what I said, so I would not brush it aside so quickly. If it's per system, does it elevate? If your MessageBox calls are really working then the simplest way to find a crash is to have a MessageBox call after every line of code in that method and see what happens. Also, personally, I would NOT use a string: I would use a StringBuilder. – PhilDW Jan 15 '15 at 18:39
  • The point is that method is never called from setup. Setup just can't find it. And I know it is in there, I looked. I solved it as I described at the end of the question, but I still cannot figure out why it is not working with single dll. – benderto Jan 18 '15 at 10:23
  • The original post says you get the error message reporting a problem - the Dll could not be run. So it IS getting called, or at least a call is attempted. That message does not typically mean it can't find it because Binary means it's in the MSI file. Either it can't load (because of missing dependencies) or it loads and crashes. – PhilDW Jan 19 '15 at 18:41
0

Not a real answer, but hopefully more than a comment.

Debug harder:

  1. Simplify your CustomAction CheckPrograms to just set a dummy-property and return ActionResult.Success. Then run msiexec with verbose logging to see if you reached the code setting the property.
  2. If 1) does show the setting of the dummy-property, add either a) displaying a MessageBox with a static string, or b) enumerating the processes (possibly, in a next mini-step) putting some info of these enumerated processes into the dummy-property to see whether you get expected values.
  3. If 1) does not show the setting of the dummy-property, try integrating the simplified CustomAction at another point (or anything else you come up with).

It all boils down to this: If you don't have any ideas regarding possible errors, try to simplify the offending code in differing areas, one by one.

Provide more info:

  1. Did you simplify your question to illustrate the problem? If so, does this simplified version still reproduce the error? (E.g. a very important point is: Did you omit some CustomActions?)
  2. As a last resort, come up with a minimalistic example triggering the error and make it accessible somewhere. Maybe somebody looks at it.
Hille
  • 4,096
  • 2
  • 22
  • 32
  • As I already state in another comment: The point is that custom action is never called from setup. Setup just can't find it. And I know it is in there, I looked. I solved it as I described at the end of the question, but I still cannot figure out why it is not working with single dll. - I tried to simplified it just to that one custom action. It didn't work. Creating new project for custom actions helped. – benderto Jan 28 '15 at 12:40
  • When writing "I tried to simplified it just to that one custom action" did you only omit the CA in the wix configuration (i.e. deleting the xml) or did you also remove it from the list of exported functions in `DriverCA.CA.dll` (e.g. by removing the `[CustomAction]` attribute)? I'm asking because of [WiX issue 4502](http://wixtoolset.org/issues/4502); for more details look at [this SO answer](http://stackoverflow.com/a/25299512/2300713). If you originally omitted some of your CAs for simplicity and now resolved the issue by moving some code to another CA-dll, this might be it. – Hille Jan 28 '15 at 13:02
  • Yes I removed `[CustomAction]` attribute and with that entire method as well. – benderto Jan 28 '15 at 15:18