Share via


Custom Action to place [TargetDir] in a text file

Question

Thursday, April 9, 2009 3:32 AM

Does anyone have, and wouldn't mind sharing, a sample of a custom action that writes the TargetDir to a new text file in the target dir?

I have never created a custom action and, frankly, have no idea where to start. My program is written in VB.net and I'm using VS 2005 (.net 2.0) to build the setup project.

Any sugestions or samples are greatly appreciated.

Thanks,
Scott

All replies (9)

Thursday, April 9, 2009 2:43 PM ✅Answered

A quick and [very] dirty would be to add a Type 34 Custom Action to execute cmd.exe and pass it the command line "/c echo [TARGETDIR]>[TARGETDIR]targetdir.txt" and then add a sequence record to one of the sequence tables (Execute or UI) to call the CA at the appropriate time.

CustomAction Table Record:
caExecuteCmd 34 SystemFolder [SystemFolder]cmd.exe /c echo [TARGETDIR]>[TARGETDIR]TargetDir.txt

The above will create "TargetDir.txt" in the [TARGETDIR] folder with a single line displaying the value of [TARGETDIR] at the time the custom action is executed.


Thursday, April 9, 2009 8:16 PM ✅Answered | 1 vote

Forget custom actions for a moment. Write a program that takes a command line containing a directory value (I'll assume for now that you know where you want to create the text file). After you've got that working, have it run as an install custom action passing [TARGETDIR] in the Arguments. Don't be sloppy with case. It's not TargetDir, it's TARGETDIR and it's case-sensitive.

Phil Wilson


Friday, April 10, 2009 5:53 AM ✅Answered | 1 vote

Hi Scott_54935,

I guess the CustomActionData format is not set right. It should be something like this:/name="[TARGETDIR]\.  For more details, you can refer to CustomActionData .

The second thing you need to know is add code in the Commit method since you put the custom action under the Commit node.

Here is the C# code, you can translate it to VB.NET if you have difficulty in understanding it.

    [RunInstaller(true)]
    public partial class MyCustomAction : Installer
    {
        public MyCustomAction()
        {
            InitializeComponent();
        }
        public override void Install(IDictionary stateSaver)
        {
            base.Install(stateSaver);

        }
        public override void Commit(IDictionary savedState)
        {
            base.Commit(savedState);
            
            string targetPath=base.Context.Parameters["name"].ToString()+"aa.txt";
            if (!String.IsNullOrEmpty(targetPath))
            {
                using (FileStream fs = new FileStream(targetPath, FileMode.CreateNew, FileAccess.ReadWrite))
                {
                    StreamWriter sr = new StreamWriter(fs);
                    sr.WriteLine("test succeed");
                    sr.Close();
                }
            }
        }
        
    }

**
** From the code, you can also get to know how to get the TAGETDIR programmatically.**
**
If you have futher problem, please feel free to let me know.

Best regards,
Bruce Zhou**
**


Please mark the replies as answers if they help and unmark if they don't.


Friday, April 10, 2009 11:23 PM ✅Answered

If you use an installer class instead of an exe then yes, you'll get an installate file. I'll repeat that you don't need an installer class, just an exe that you can test outside the install environment to make sure it works when passed an argument list containing the locations of whatever you want to update.  Installer classes are much more complex than a standalone program you can launch from the install. Programs are easier to debug before you put them in the install, and installer classes have no extra functionality compared with just running your program passing data via the Arguments.

It's not {TARGETDIR] it's [TARGETDIR] 

The most likely reason it fails is that it can't find the file. You need to tell the program the absolute path to the file. Don't be lazy with error reporting either. If it can't find the file then show a message box describing exactly where it's looking for the file.

The issue with a command line program is that you'll see a cmd prompt window pop open and close. It works best as a Windows program.
 Phil Wilson


Friday, April 10, 2009 3:28 AM

Hi Scott_54935,

In case you need the detail step, here is the Walkthrough on creating custom action which might help you in achieving the goal.

Best regards,
Bruce ZhouPlease mark the replies as answers if they help and unmark if they don't.


Friday, April 10, 2009 4:46 AM

I created a console app that takes a parameter (TARGETDIR) and creates the text file in the TARGETDIR. When I test the console app, it works fine. When I run the installer with the custom action,  it does not create the text file.

I created a custom action under Commit.
Then, I set the argument to {TARGETDIR]
No Conditions
No CustomActionData
InstallerClass - I tried true & false but it didn't seem to matter either way.

Sorry if these questions seem basic but I have done only simple stuff with the installer - copy files around, specify launch conditions, reg search, etc.

Thanks,
Scott


Friday, April 10, 2009 5:52 AM

Okay, here's an update. I followed the Walkthrough example posted above and tweaked it to get my desired results. So far everything is fine. One thing I noticed right away, I now have a .InstallState file in my directory with the assembly containing the custom action. How do I get rid of the .installstate file or prevent it from being created?

BTW, in my installer class, I used Path.GetDirectoryName(Context.Parameters("AssemblyPath")) to get the TARGETDIR and then wrte some code to build my text file in that location.

Thanks,
Scott


Friday, April 10, 2009 6:43 AM

Hi Scott_54935,

The .installstate file is brought in by custom action. You can't prevent it from being created unless you don't ship the custom action in the installer.

Best regards,
Bruce ZhouPlease mark the replies as answers if they help and unmark if they don't.


Saturday, April 11, 2009 10:35 PM

Right now everything is working. I did use an installer class, experimented a bit with one of the tutorials list above, and eventually got it to work. I also created a console app that accepts an argument but the installer class is in my installer app.

Thanks for everyone's help and suggestions.
Scott