DdoubleD 315 Posting Shark

Still missing definition for errorProvider1 object.. Is there another file I need to get this to compile?

DdoubleD 315 Posting Shark

I have not used a CrystalReportViewer control. I did try to replicate your issue with my project and database, but all I got was an empty view when I mimicked your code--no error, but no data either.

Can you zip up the project (include database)?

DdoubleD 315 Posting Shark

You need to post the designer code too: "Configuration.designer.cs" file.

Messy you say? I've seen much, much worse! No worries.

DdoubleD 315 Posting Shark

Post your code... Be sure to enclose in code tags.

DdoubleD 315 Posting Shark
public partial class Form1 : Form
    {
        int index = -1;
        List<Image> images;

        public Form1()
        {
            InitializeComponent();

            images = new List<Image>();
            // add images

        }

        private void btnNext_Click(object sender, EventArgs e)
        {
            index++;
            if (index < 0 || index >= images.Count)
                index = 0;
            pictureBox1.Image = images[index];
        }
    }
DdoubleD 315 Posting Shark

Hi all,

Now i dont remember what we say about this method, i am so sorry for that anyway... I want to write in textbox when i am writing on it, it shows similar info to me. For example if i write dan it must be show daniweb, dance, danny, dan brown, ... this informations are in my database. i want to use this method in combobox, textbox, etc.
Thank you for your all atent.

Are you referring to autocomplete?

If so, check out this link: Adding autocomplete
Also: Another example and download

DdoubleD 315 Posting Shark

This example is outlined in VB code, but it gets the point across very well I believe. I am too tired to pursue this transformation of the DB. Check this out: customizing-installation-using-transforms

Again, since you didn't answer any questions, I have made assumptions that you have a need similar to what is described in this article: Reuse a single MSI

I hope that helps you reach your goal.

Cheers!

DdoubleD 315 Posting Shark

facadie, if you will post the code you thus far, I will help you. Please add comments to the code in the areas that you still have questions about too.

DdoubleD 315 Posting Shark

According to the MS documentation (for what it is worth), you cannot change the value of a private property from the command line. Now, in trying to determine which were private, I kind of got lost in the endless freaken links MS has there, but I believe I read something about the public ones being all uppercase, which leads me to believe ProductName is a private property--bummer. Regardless, I could not get that command line option to work for my test with my defined property anyway.

I'm not sure why you want to do this, but I suspect you are wanting to use the same setup for multiple products?

I got sidetracked, but I have read that you can accomplish this by creating a "transform" and then launching with a transform to change the property. I haven't had a chance to figure out what that entails--do you have any idea what that's about?

DdoubleD 315 Posting Shark

That MSI Analyzer is pretty cool, but here is a simplified answer I whipped up for ya:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices; // Deploying a .NET component customization
using WindowsInstaller;
using System.IO;
using System.Collections;

namespace MSIDataBaseStuff
{
    public partial class Form1 : Form
    {
        [System.Runtime.InteropServices.ComImport(),
            System.Runtime.InteropServices.Guid
            ("000C1090-0000-0000-C000-000000000046")]
        class Installer { }

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            FileInfo msiFile = new FileInfo("setup1.msi");

            // open MSI database
            WindowsInstaller.Installer inst = (WindowsInstaller.Installer)new Installer();
            Database instDb = inst.OpenDatabase(msiFile.FullName,
                WindowsInstaller.MsiOpenDatabaseMode.msiOpenDatabaseModeReadOnly);

            // query the database
            WindowsInstaller.View view = instDb.OpenView
                ("Select `Property`,`Value` FROM `Property`");
            view.Execute(null);

            //fetch each record...
            Record record = view.Fetch();
            while (record != null)
            {
                int iRow = dataGridView1.Rows.Add();
                dataGridView1.Rows[iRow].Cells[0].Value = record.get_StringData(1);// property
                dataGridView1.Rows[iRow].Cells[1].Value = record.get_StringData(2);// value

                record = view.Fetch();
            }

            // close the database
            view.Close();
        }
    }
}
partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.Property = new System.Windows.Forms.DataGridViewTextBoxColumn();
            this.Value = new System.Windows.Forms.DataGridViewTextBoxColumn();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.SuspendLayout(); …
serkan sendur commented: havent checked yet but if works, oh man! +9
DdoubleD 315 Posting Shark

Could you please test it for me? if that works i will add to your reputation for ten days.

It did not work for me either!--sorry. I will investigate further...

DdoubleD 315 Posting Shark

have you tested it, did it work?

Microsoft said it would work so I'm sure it's fine--LOL. No, I did not test it.

DdoubleD 315 Posting Shark

Scratch that last reply--I couldn't even get it to compile. Here is a link that I compiled and played with a little: MSI Analyzer

DdoubleD 315 Posting Shark

Really?

Reading Data from MSI Database

Sorry buddy--I didn't realize it was C++. I can probably translate for you though if you need it.

DdoubleD 315 Posting Shark

msiexec /i A:\Example.msi ProductName=VALUE

DdoubleD 315 Posting Shark

I'm not sure what you are asking. Are you wanting a stack trace that allows you to navigate into the points (method calls) of execution?

DdoubleD 315 Posting Shark

I'm not good at math either...LOL. Check out this thread, and see if you can come up with the formula you need. Then, if you need help with coding it, come on back here--OK?

Calculate Radius from X Y coord

DdoubleD 315 Posting Shark

If the storage file does not need to be text, check out this IO Class: BinaryReader & BinaryWriter , which will simplify much of the data typing IO of your fields.

In addition, consider using the BinaryFormatter class:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace TestSerializer
{
    public class DataSerializer
    {
        [Serializable]
        public class Data : ArrayList
        {
            [Serializable]
            public struct Field
            {
                string s1;
                string s2;
                string s3;
                int i1;
                int i2;
                int i3;

                public Field(string s1, string s2, string s3, int i1, int i2, int i3)
                {
                    this.s1 = s1;
                    this.s2 = s2;
                    this.s3 = s3;
                    this.i1 = i1;
                    this.i2 = i2;
                    this.i3 = i3;
                }
            }

            public Data()
            {
                for (int i = 0; i < 100000; i++)
                {
                    Field fld = new Field(
                        "1 - Some Text " + i,
                        "2 - Some Text " + i,
                        "3 - Some Text " + i,
                        i * 1,
                        i * 2,
                        i * 3
                    );

                    Add(fld);
                }
            }
        }

        public DataSerializer()
        {
            Data data = new Data();

            BinaryFormatter bf = new BinaryFormatter();
            using (Stream stream = new FileStream("data.dat", FileMode.Create, FileAccess.Write))
            {
                bf.Serialize(stream, data);
                stream.Flush();
                stream.Close();
            }

            Data dataRead;
            using (Stream stream = new FileStream("data.dat", FileMode.Open, FileAccess.Read))
            {
                dataRead = (Data)bf.Deserialize(stream);
                stream.Flush();
                stream.Close();
            }
        }

        public static void Test()
        {
            DateTime dt = DateTime.Now;
            TimeSpan dtStart = dt.TimeOfDay;

            DataSerializer ds = new DataSerializer();

            dt = DateTime.Now;
            TimeSpan dtEnd = dt.TimeOfDay;

            TimeSpan dtTotal = dtEnd - dtStart;

            Console.WriteLine("DataSerializer Total …
DdoubleD 315 Posting Shark

Hey Danny, I played around with the example MSDN code for a little while this morning, tweaking here and there, and I couldn't find an easy way to make the existing code produce the desired behavior. I think what you would need to do to is override the default behavior of the DataGridViewTextBoxCell in the definition of:

public class CalendarCell : DataGridViewTextBoxCell

or, perhaps implement a customized version of: DataGridViewComboBoxCell that incorporates the DateTimePicker implementation and inherit from that instead.

I hope that someone will provide a reasonable solution, because I feel this is something that can be achieved without much overhead and I would like to see the necessary changes because I haven't spent much time with DataGridView's and am curious too.

In the MFC days, we would draw a combobox button in the cell right-justified and then monitor for a click in that region and produce the behavior that it was a combobox, or in your case, a DateTimePicker. However, things are simpler now and I just know someone will have a better suggestion to deal with this.

DdoubleD 315 Posting Shark

I have not figured out yet how to include more than one custom action, but I have figured out how to call my property [CustomAction]:

1) Must be only custom action in selected library (as far as I can figure it out)
2) Set EntryPoint to method name. In my case: CustomAction1
3) Set InstallerClass to False

A free website I found with good information and links on installers: http://www.installsite.org/

Person most likely to ask you questions about installers, but never answer any of yours: serkan;)

DdoubleD 315 Posting Shark

Or, Change its name to: blah blah

DdoubleD 315 Posting Shark

By the way i have a question for native english speakers : which one is correct
1) change its name as to be blah blah
2) change its name to be as blah blah

?

Neither: "change its name to be "blah blah"

DdoubleD 315 Posting Shark

The title basically says it all.

How would I include a DLL for use in another project?

If I have understood your question, you need to add a reference to the assembly/library in your project. Under ProjectName/References, right click and select Add Reference; then select the Browse tab and go to the location of the DLL and select it.

DdoubleD 315 Posting Shark

Why does your data contain such escape sequences and why not scrub them out first before adding them if you need to display in a ListView control?

DdoubleD 315 Posting Shark

I had the same concerns you guys did about what was being done in his ListView--it seems like a futile exercise to me.

DdoubleD 315 Posting Shark

ok DdoubleD, i investigated your demo application and unfortunately it didnt solve my problem. I know you can pass parameter values from setup project to custom installer project, my question was this : how do you pass the version information that is embedded in to setup project. for example you pass the target directory like this : /yourCustomParameter="[TARGETDIR]\" , like wise i want to be able to pass that embedded version information.

Thanks.

I think you should probably post this to YOUR thread instead of mine, so I am quoting it here.

Where exactly is your embedded product version being stored/set inside the setup prior to the custom install step?

DdoubleD 315 Posting Shark

Your next loop should look like:

for (int lCount = 0; lCount < ListView1.Items.Count; lCount++)
                MessageBox.Show(ListView1.Items[lCount].Text)

to replace:

Dim lCount As Integer
            For lCount = 0 To ListView1.Items.Count
                MsgBox(ListView1.Items(lCount).Text)
            Next

NOTE: Not sure how VB handles declaration of iterator inside the loop ( lCount (maybe you can't), but in C# the variable lCount (as I demonstrated it) will no longer be in scope outside the confines of the loop block (single statement in this case).

DdoubleD 315 Posting Shark

You left off the parenthesis: lcount.ToString() should eliminate that error message.

DdoubleD 315 Posting Shark

Thanks Scott! I tried that Debugger.Break() and it worked fine. Also, thanks much for sharing your past experience. That could save a whole lot of time for me or someone else that might run into that situation.

I have no plans to use the setup and really only started down this path to help figure out a question serkan had, but you never know when you might find yourself (perhaps forcibly) trying to do something like this so I don't mind learning it.

DdoubleD 315 Posting Shark

i hard coded the product version into custom installer class, so it is a work around for now.

Serkan, please look at the code I posted today regarding Context.Parameters : http://www.daniweb.com/forums/thread224137.html

I see no reason why you cannot use a parameter to pass in the product version from the setup.

DdoubleD 315 Posting Shark

Installer Portion

My progress thus far is I have figured out how to utilize the Install component added to my CustomAction1 project, as well as the limitations associated with it only being callable after the install has installed everything designated in the setup. I understand why this is. I am able to retrieve setup parameters and pass in user-defined parameters from the setup--mission accomplished here.

My only remaining question in this area is whether anyone knows a technique for substituting a debugger instance of the CustomAction1 library at runtime of Setup so that breakpoint debugging can occur when setup calls the Install override? Although the capability is more of a luxury than a necessity at this point, for this portion at least, I am still curious to know.

I am reposting this portion of the code for anyone who happens along this thread because I know how difficult it is to find information on this subject that is correct and up-to-date; and, although my contribution is by no means a complete one, it does provide some insight to things I would have liked to have run into during the research. I am also attaching the current project for the same purpose.

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Runtime.InteropServices; // Deploying a .NET component customization
using System.Windows.Forms;
//using Microsoft.Deployment.WindowsInstaller; // creates a conflict with "Install" def

namespace CustomAction1
{
    [RunInstaller(true)]
    public partial class Installer1 : Installer
    {
        // Only method …
DdoubleD 315 Posting Shark

See attached project. This is a very small test project so I can learn. Here are my questions:

1) I've overridden the Install and Uninstall in my Installer component based class, but they don't seem to get called...why? I am setting a breakpoint in the Install override and running in debugger--you can do that right?:

using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Configuration.Install;
using System.Linq;
using System.Runtime.InteropServices; // Deploying a .NET component customization

namespace CustomAction1
{
    [RunInstaller(true)]
    public partial class Installer1 : Installer
    {
        public Installer1()
        {
            InitializeComponent();
        }

        public override void Install(System.Collections.IDictionary stateSaver)
        {
            base.Install(stateSaver);
            RegistrationServices regSrv = new RegistrationServices();
            regSrv.RegisterAssembly(base.GetType().Assembly,
              AssemblyRegistrationFlags.SetCodeBase);
        }

        public override void Uninstall(System.Collections.IDictionary savedState)
        {
            base.Uninstall(savedState);
            RegistrationServices regSrv = new RegistrationServices();
            regSrv.UnregisterAssembly(base.GetType().Assembly);
        }
    }
}

2) How do I invoke the following CustomAction (see below)? It doesn't matter to me whether before or after install, though I would like to know how you tell the setup to do it both ways. I assume you cannot invoke a CustomAction while it performs the actual installation--is that correct assumption?

[CustomAction]
        public static ActionResult CustomAction1(Session session)
        {
            session.Log("Begin CustomAction1");

            string[] arguments = GetCustomActionDataArguments(session);

            string body = "Arguments:\n";
            foreach (string s in arguments)
                body += "\t" + s + "\n";
            MessageBox.Show(body, "CustomAction1");

            return ActionResult.Success;
        }

3) How or can I view the msi script directly to see declarations and logic in the IDE? I used to work with InstallShield and you could view and edit the script file directly, which was often easier to …

DdoubleD 315 Posting Shark

i hard coded the product version into custom installer class, so it is a work around for now.

I've been researching this for some time now, and I cannot figure out some things, so I'm going to create a new thread and post the project and maybe you can help me with my noob questions.

DdoubleD 315 Posting Shark

I started looking into this. I ran into this info and figured it was worthy of posting my progress. I just saved the relevant screenshot as a bmp because it had a property screen visual.

DdoubleD 315 Posting Shark

Anytime. Cheers!

DdoubleD 315 Posting Shark

Here are some changes I made based on the way you are using your list. NOTE: I didn't compile, but I believe is OK:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace TESTpractice
{
    class Program
    {
        static void Main(string[] args)
        {
            Program t = new Program();
            t.Run();
        }
        public void Run()
        {
            Insect insects = new Insect(8, 8, "Ugly Spider", "Arachnida"); // if need to use contsructor
            insects.Add (8, 8, "Black Widow", "Arachnida"); // add method
            insects.Add (8, 8, "Brown Spider", "Arachnida");

            insects.getInfoAll(); // print out entire list
        }
    }
    public class Insect
    {
        public List<Insect> insects = new List<Insect>();
        public int Eyes { get; set; }
        public int Legs { get; set; }
        public string Species { get; set; }
        public string Family { get; set; }

        public Insect()
        {
        }
        public Insect(int myEyes, int myLegs, string mySpecies, string myFamily)
        {
            Add(myEyes, myLegs, mySpecies, myFamily);
        }
        public void Add (int myEyes, int myLegs, string mySpecies, string myFamily)
        {
            Eyes = myEyes;
            Legs = myLegs;
            Species = mySpecies;
            Family = myFamily;
            insects.Add(this);
        }

        public void getInfo()
        {
            Console.WriteLine(" Species: {0} \n Family: {1} \n Number of eyes: {2}\n Number of legs: {3}",
            Species, Family, Eyes.ToString(), Legs.ToString());
        }

        public void getInfoAll()
        {
            foreach (Insect insect in insects)
            {
                insect.getInfo();
            }
        }
    }
}
DdoubleD 315 Posting Shark

Put it inside your Insect class.

DdoubleD 315 Posting Shark

I cant seem to edit my post... but I'm having a bit of trouble trying to loop through the objects.

So in my insect class I have List<Insect> but I want to some how display all the objects in my Main section. I have a method in insect class that displays the info of the insect.
for example. spider.GetInfo would tell me all about the insect. But I want the method to be able to be called in a foreach loop, display all the details about all the insects. This would require a static method, (so i could call just Insect.GetInfo()) but i have variables in my methods, so that won't work... any help?

I don't which one you used since you didn't post the code. Here is an example:

foreach (Insect insect in insects)//where insects is your list
    insect.GetInfo();

If that answers your questions, please mark as SOLVED. Otherwise, just ask another question.-- Cheers!

DdoubleD 315 Posting Shark

I found this code, but havn't tried it. It shows how to revoke registry privilege for software application, and I think it might be more of what you are looking for.

public static void RevokeRegKeyRights(RegistryKey regKey,
                                      NTAccount user,
                                      RegistryRights rightsFlags,
                                      InheritanceFlags inherFlags,
                                      PropagationFlags propFlags,
                                      AccessControlType actFlags)
{
    RegistrySecurity regSecurity = regKey.GetAccessControl();

    RegistryAccessRule rule = new RegistryAccessRule(user, rightsFlags, inherFlags,
                                                     propFlags, actFlags);
    regSecurity.RemoveAccessRuleSpecific(rule);

    regKey.SetAccessControl(regSecurity);
}

I believe that if you call the above with the RegistryRights.ExecuteKey option, it should prevent that user from launching the application:

NTAccount user = new NTAccount(@"WRKSTN\ST");

            using (RegistryKey regKey = Registry.LocalMachine.OpenSubKey(
                                    @"SOFTWARE\MyCompany\MyApp"))
            {
                RevokeRegKeyRights(regKey, user, RegistryRights.ExecuteKey,
                               InheritanceFlags.None, PropagationFlags.None,
                               AccessControlType.Allow);
             }
DdoubleD 315 Posting Shark

Not sure how you would do that by registered application, but here is a good link/example code showing how to add/revoke privileges to particular directory for user. You could change it also to use the File class objects instead of the Directory objects if you desire. I know it's probably not exactly what you are looking for, but maybe a workaround if needed:

Security Access Control

DdoubleD 315 Posting Shark

I still don't understand, but to search an entire drive for a file is not difficult to do:

DirectoryInfo di = new DirectoryInfo(@"c:\");
            FileInfo[] finfos = di.GetFiles("*.exe", SearchOption.AllDirectories);
            foreach (FileInfo fi in finfos)
                ; // do something with the file info
DdoubleD 315 Posting Shark

if you include List in your Insect class, you would just call the Add(T) method to add it:

public class Insect
    {
        List<Insect> insects = new List<Insect>();
        int legs, eyes;
        string species, family;

        public Insect(int legs, int eyes, string species, string family)
        {
            this.legs = legs;
            //....and so on  
            insects.Add(this);
        }
    }

If you inherit the List, then you could do this:

public class Insect : List<Insect>
    {
        //List<Insect> insects = new List<Insect>();
        int legs, eyes;
        string species, family;

        public Insect(int legs, int eyes, string species, string family)
        {
            this.legs = legs;
            //....and so on  
            Add(this); //insects.Add(this);
        }
    }
DdoubleD 315 Posting Shark
public static string System.Path.GetDirectoryName(string path);

where the path argument contains the fullname: path\filename.ext

DdoubleD 315 Posting Shark

And Extension methods brought to you by framework 3.x! :)

I had to +rep you for this example, which was my first exposure to usage of Extension Methods. The fist thing I did of course was drop the code into another class, which produced an error and forced me to read up on the subject a little. ;)

DdoubleD 315 Posting Shark

Why would you want your application to delete itself?

DdoubleD 315 Posting Shark

hello=) i think it run withins the form?
but how do i make it so like:

when i click BTNOK it will run the program which will a check if any textbox or any combo boxes[selecteditem] have change as compare to the data store. then it will run save program.

so it's like doing a check when BTN OK is click.

I wrote this for your button cancel, but you can apply this logic anywhere in your program:

private void btnCancel_Click(object sender, EventArgs e)
        {
            bool bEditChange = false;
            
            if ("whatever was read from text file" != (string)comboBox1.SelectedItem)
                bEditChange = true;

            if ("whatever was read from text file" != textBox1.Text)
                bEditChange = true;

            // etc.,etc.,etc.

            if (bEditChange)
            {
                if (DialogResult.Yes == MessageBox.Show("Save Changes?", "Cancel", MessageBoxButtons.YesNo))
                {
                    // do your file save stuff
                }
            }
        }
DdoubleD 315 Posting Shark

if you add a setup project to your windows application, you will have some properties shown when you hit f4 when you select your setup project in solution explorer, there you will see the version information for your product, i want to pass that information to custom installer.

Not to waste your time, but what I don't understand for sure is how you intend to call the custom installer. After reading all this, it sounds like you are writing a setup in which you want to pass the product version you have defined in this setup while it is running, via a call from same said setup, to "another" "custom installer" or setup that will be launched from your other setup. Is that what you want to do?

I have an appt and will be gone for a few hours, but will check back then...

DdoubleD 315 Posting Shark

hi guys,
i need to pass product version information from windows installer to custom installer, i am almost sure that you dont know the answer but that is fine, it is also important for me to show you what you dont know.
i will try to solve this thread later in time.

I am almost sure you are correct, but it is important for me to ask: what product is the custom installer is installing?

:cool:

DdoubleD 315 Posting Shark

This is what the event wiring for combobox selection change should look like in case you don't use VS designer:

// in form intialization:
            this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);

// then, just create this method for your form:
        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            // to retrieve it's index:
            int index = comboBox1.SelectedIndex;
            /// if your item is text, otherwise cast to proper type:
            string text = (string)comboBox1.SelectedItem;
        }
DdoubleD 315 Posting Shark

In your set statement, you create a new var of name "_Imge"--was that intended? And, you also call the property setter again with Imge = value --was that intended?

Maybe I've missed something, but I don't understand why you would return _Imge in your getter, but then call the setter again inside the set property, or why you would create, or attempt, what appears to be another instance for _Imge in the setter (and then not even use it).