Automatyczny folder

Poszukuje prostego sposobu jak zrobić automatyczny folder (tzn. taki do którego wrzucając dany plik z konkretnym rozszerzeniem [np.mp3] folder będzie automatycznie wysyłać ten plik dalej na zdefiniowany folder)

Przykład: Wrzucam jakiś film do automatycznego (albo magicznego jak kto woli) folderu i automatycznie zostaje on przekierowany na partycje z filmami.

Czy jest jakiś prosty sposób na to ? (Np. dopisanie czegoś do elementu docelowego w skrócie folderu). Na programowaniu raczej się nie znam więc nie proponujcie zbyt wyszukanych rozwiązań :stuck_out_tongue:

PS: Nie wiem czy dobrze umieściłem temat, ale wg. mnie jest to jakis sposób programowania …

Najprościej to chyba umieścić skrót do takiego folderu. Bo jeśli coś przeniesiesz/skopiujesz do “folderu skrótowego” to automatycznie znajdzie się w folderze oryginalnym, a “folder skrótowy” nie zwiększy swojego rozmiaru.

Tak tylko właśnie chodzi o to aby to był jeden skrót do wszystkiego :stuck_out_tongue:

Nie bardzo rozumiem. Chcesz żeby z jednego folderu pliki przenosiły się w różne miejsca??? A skąd niby komputer ma wiedzieć gdzie ty chcesz je umieścić??? Takich cudów to chyba nie ma. Przecież kompek chyba nie umie czytać w myślach…

Czytaj ze zrozumieniem … wrzucałby pliki o danym formacie do zdefiniowanego wczesniej miejsca.

Dobrze rozumiem?

  1. Masz gdzieś “magiczny” katalog.

  2. Wrzucasz do niego plik mp3, i wtedy jest on przenoszony do katalogu z muzyką.

  3. Gdy wrzucisz np. jpg, to jest przenoszony do katalogu ze zdjęciami.

  4. Itd.

Jeśli tak, to trzeba napisać program, który będzie monitorował wskazany katalog, reagował na pojawienie się w nim nowego pliku, sprawdzał jego rozszerzenie i przenosił do określonego katalogu docelowego.

W sumie niegłupi pomysł :slight_smile:

Zadanie podejrzewam na jeden wieczór.

Tak dokładnie o to chodzi … bardzo byłoby to pomocne bo wystarczy mieć tylko te ikonke od tego folderu na pulpicie czy gdzie kolwiek i wrzucac masowo pliki a nie po kolei otwierac kazdy folder itp …

Więc teraz wystarczy, że napiszesz sobie taki program (w końcu to dział “Programowanie”). Jeżeli nie umiesz to poproś kogoś kogo znasz i wiesz, że potrafiłby.

Jak rozumiem to pod Windows ma być?

Tak … a konkretnie (jezeli ma to jakieś znaczenie) pod XP

Nawet ciekawy problemik, więc naskrobałem coś takiego: http://www.somekind.pl/_upload/AutoFileMove.exe

Po fazie testów pewno wrzucę na stronkę.

Do działania wymaga .NET Framework 2.0

Ściągnąłem i przetestowałem program przesłany przez somekind. DZIAŁA!

Na przykład, wrzucam plik o rozszerzeniu mp3 do folderu TEST na pulpicie, to przenosi do folderu Muzyka lub jak przenoszę plik o rozszerzeniu jpg lub bmp to przenosi do folderu Obrazy. :o :o :o

Wszystko sam sprawdzałem.

Brawo dla somekind za stworzenie tego ZNAKOMITEGO programu! =D> =D>

PS. Oczywiście folder TEST, to był mój przykład :smiley:

EDIT

Bardzo proszę somekind , żeby program miał takie funkcje, żeby innym było wygodnie:

  • Żeby aplikacja pracowała w tle

  • Dostępne funkcje po kliknięciu prawym przyciskiem myszy

  • Żeby chociaż ta aplikacja miała ikonkę w trayu (obok zegara)

No i jeszcze dodam, że aplikacja jest kompatybilna z systemami Microsoft Windows 2000/XP/Vista.

W systemie Windows 2000, trzeba wykonać kilka kroków, aby aplikacja działała:

  1. Ściągamy i zapisujemy do katalogu C:\WINNT\system32\ plik mscoree.dll.

  2. Instalujemy aktualizację Windows Installer 3.1 z rozszerzenia Windows Update.

  3. Uruchamiamy ponownie komputer.

  4. Instalujemy NET. Framework 2.0.

  5. No i znowu musimy ponownie uruchomić komputer.

  6. Próbujemy uruchomić aplikację.

Dziękować bardzo za programik :stuck_out_tongue: - działa tak jak powinien …

Mam tylko pytanie … czy jest możliwość aby uruchamiał się ze startem systemu jako proces w tle ? (Tak wiem że można manualnie dodaćdo autostartu, ale i tak trzeba będzie go uruchamiać poprzez “start” i minimalizować)

somekind mógłbyś wrzucić źródło?

A ja chcę takie coś: http://l.yimg.com/img.autos.yahoo.com/i/articles/most_coveted_cars/koenigsegg_ccx_o.jpg. Zafundujesz mi? :stuck_out_tongue:

Nie zawsze można mieć to, czego chcemy, ale jeśli czegoś naprawdę chcemy, to lepiej o to poprosić, a nie żądać ;]

Nie rozumiem… Przecież wszystko możesz sobie edytować, a także zaznaczyć każdy wiersz, wcisnąć Delete (na klawiaturze) i go skasować.

Ale jakie funkcje?

A co do reszty - masz rację, że tak będzie wygodniej i tak powinno być, ja tez o tym wiem, na razie skupiłem się na zrobieniu sprawnej, działającej wersji, bez zabawy w szczegóły. Jak będę miał chwilę czasu, to to dopracuję i wypuszczę wersję 2.0.

Bardzo intymna prośba, to tak jakbyś chciał moją szczoteczkę do zębów pożyczyć :smiley:

Tworzę raczej freeware niż open source, ale mogę pomyśleć… A powiedz, po co Ci? Do celów edukacyjnych, czy chcesz sobie w jakimś Mono odpalić? ;>

ja nie uważam źródeł za coś intymnego, jestem raczej z tych ekshibicjonistów którzy chcą pokazywać swój kod na wolnej licencji :slight_smile:

Oczywiście do celów edukacyjnych, ot jak to C# wygląda (bo pewnie w C# pisałeś prawda?), ile zajmuje linijek, ogółem rzucić okiem jak działa. No i porównać z wersją w Perlu która powstała w mojej głowie podczas pisania przed-poprzedniego wpisu :slight_smile:

Dzięki somekind , nie wiedziałem o tym i nie mogłem sobie poradzić ze skasowaniem wiersza. #-o Bardzo mi pomogłeś! :slight_smile:

OK. No to będziemy wszyscy czekać na wersję 2.0 twojego znakomitego programu! :smiley: :smiley:

Coś typu Załaduj ustawienia domyślne, Zapisz ustawienia (np. zapisuję ustawienia na nośniku wymiennym, przeszedłem format dysku, pobieram od ciebie jeszcze raz program, wczytuje swoje zapisane ustawienia i wtedy ustawienia są takie same jak sprzed formatu dysku).

Może być również funkcja “O programie” która pokazuje informacje o twoim programie.

Albo opcja “ikona widoczna w tray’u” bo nie kazdy lubi miec w nim duzo ikonek :stuck_out_tongue:

No dobra, to wersja 2.0 (instalacyjna) jest tutaj - proszę o testy: http://www.somekind.pl/_upload/AutoFileMoveSetup.exe

Tak, w C#. Pewno w Perlu kodu będzie mniej, za to bardziej zagmatwany :stuck_out_tongue:

Dobra, to daję kod wersji pierwszej (engine ten sam, tylko interfejs inny).

Na początek znaleziona w necie klasa która umożliwia serializowanie Dictionary (ten standardowy, nie wiadomo czemu, takiej opcji nie ma):

using System;

using System.Collections.Generic;

using System.Text;

using System.Xml.Serialization;


namespace AutoFileMove

{

    [XmlRoot("dictionary")]

    public class SerializableDictionary : Dictionary, IXmlSerializable

    {

        private string itemName = "entry";

        private string keyName = "extension";

        private string valueName = "directory";


        #region IXmlSerializable Members


        public System.Xml.Schema.XmlSchema GetSchema()

        {

            return null;

        }


        public void ReadXml(System.Xml.XmlReader reader)

        {

            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            bool wasEmpty = reader.IsEmptyElement;

            reader.Read();

            if (wasEmpty)

                return;

            while (reader.NodeType != System.Xml.XmlNodeType.EndElement)

            {

                reader.ReadStartElement(this.itemName);

                reader.ReadStartElement(this.keyName);

                TKey key = (TKey)keySerializer.Deserialize(reader);

                reader.ReadEndElement();

                reader.ReadStartElement(this.valueName);

                TValue value = (TValue)valueSerializer.Deserialize(reader);

                reader.ReadEndElement();

                this.Add(key, value);

                reader.ReadEndElement();

                reader.MoveToContent();

            }

            reader.ReadEndElement();

        }


        public void WriteXml(System.Xml.XmlWriter writer)

        {

            XmlSerializer keySerializer = new XmlSerializer(typeof(TKey));

            XmlSerializer valueSerializer = new XmlSerializer(typeof(TValue));

            foreach (TKey key in this.Keys)

            {

                writer.WriteStartElement(this.itemName);

                writer.WriteStartElement(this.keyName);

                keySerializer.Serialize(writer, key);

                writer.WriteEndElement();

                writer.WriteStartElement(this.valueName);

                TValue value = this[key];

                valueSerializer.Serialize(writer, value);

                writer.WriteEndElement();

                writer.WriteEndElement();

            }

        }


        #endregion


    }

}

Dalej klasa służąca do przechowywania konfiguracji:

using System.Windows.Forms;


namespace AutoFileMove

{

    public class ExtDirConfig

    {

        #region fields

        private string sourceDirectory;

        private SerializableDictionary extensionsDictionary;

        #endregion


        #region properties

        public string SourceDirectory

        {

            get { return sourceDirectory; }

            set { sourceDirectory = value; }

        }

        public SerializableDictionary ExtensionsDictionary

        {

            get { return extensionsDictionary; }

            set { extensionsDictionary = value; }

        }

        #endregion


        #region constructors


        public ExtDirConfig()

        {

        }


        public ExtDirConfig(TextBox _txt, DataGridView _dgv)

        {

            this.sourceDirectory = _txt.Text;

            this.extensionsDictionary = new SerializableDictionary();

            foreach (DataGridViewRow dgrv in _dgv.Rows)

            {

                if (dgrv.Cells["colExtension"].Value != null && dgrv.Cells["colTargetDirectory"].Value != null)

                {

                    string ext = dgrv.Cells["colExtension"].Value.ToString();

                    string dir = dgrv.Cells["colTargetDirectory"].Value.ToString();

                    this.extensionsDictionary.Add(ext, dir);

                }

            }

        }


        #endregion


    }

}

I wreszcie główna klasa okienka programu:

using System;

using System.Collections.Generic;

using System.Text;

using System.Windows.Forms;

using System.IO;

using System.Xml.Serialization;


namespace AutoFileMove

{

    public partial class Form1 : Form

    {

        #region constant fields

        const string chooseDirButtonTitle = "Wybierz...";

        #endregion


        #region fields

        //ścieżka do pliku konfiguracyjnego

        string configFilePath;

        //obiekt zwierający dane konfiguracyjne

        ExtDirConfig edConfig;

        //log sprawdzania danych wprowadzonych przez użytkownika

        StringBuilder checkingLog;

        #endregion


        #region form 


        public Form1()

        {

            InitializeComponent();

        }


        private void Form1_Load(object sender, EventArgs e)

        {

            this.configFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + "/AutoFileMove/config.xml";


            this.folderBrowser.RootFolder = Environment.SpecialFolder.DesktopDirectory;

            //jeśli istnieje plik konfiguracyjny

            if (File.Exists(this.configFilePath))

            {

                try

                {

                    //próba wczytania konfiguracji i wypełnienia interfejsu

                    this.ReadConfiguration();

                    this.FillInterface();

                }

                catch

                {

                    //w razie błędu

                    MessageBox.Show("Błędny plik konfiguracyjny!", "Błąd", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    this.dgvExtAndDirs.Rows[0].Cells["colChooseDir"].Value = Form1.chooseDirButtonTitle;

                }

            }

            //jeśli pliku konfiguracyjnego nie ma

            else

                this.dgvExtAndDirs.Rows[0].Cells["colChooseDir"].Value = Form1.chooseDirButtonTitle;

        }


        #endregion


        #region buttons 


        private void btnWybierz_Click(object sender, EventArgs e)

        {

            if (this.folderBrowser.ShowDialog() == DialogResult.OK)

            {

                this.txtSourceDir.Text = this.folderBrowser.SelectedPath;

            }

        }


        private void btnStart_Click(object sender, EventArgs e)

        {

            //jeśli tak, to 

            if (this.CheckConfiguration())

            {

                //utworzenie obiektu konfiguracji

                this.edConfig = new ExtDirConfig(this.txtSourceDir, this.dgvExtAndDirs);

                //zapisanie konfiguracji

                this.SaveConfiguration();

                //wyłączenie interfejsu

                this.ChangeControlState();

                //uruchomienie filesystemwatchera

                this.fsWatcher.Path = this.edConfig.SourceDirectory;

                this.fsWatcher.EnableRaisingEvents = true;

            }

            else

            {

                MessageBox.Show(this.checkingLog.ToString(), "Błąd konfiguracji", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }

        }


        private void btnStop_Click(object sender, EventArgs e)

        {

            //zatrzymanie filesystemwatchera

            this.fsWatcher.EnableRaisingEvents = false;

            //włączenie interfejsu

            this.ChangeControlState();

        }


        private void ChangeControlState()

        {

            foreach (Control c in this.Controls)

                c.Enabled = !c.Enabled;

        }


        #endregion


        #region datagridview 


        private void dgvExtAndDirs_CellContentClick(object sender, DataGridViewCellEventArgs e)

        {

            //jeśli to kolumna z przyciskiem wyboru

            if (e.ColumnIndex == 2)

            {

                if (this.folderBrowser.ShowDialog() == DialogResult.OK)

                {

                    //wpisanie wybranego katalogu do odpowiedniej komórki

                    this.dgvExtAndDirs[1, e.RowIndex].Value = this.folderBrowser.SelectedPath;

                }

            }

        }


        private void dgvExtAndDirs_UserAddedRow(object sender, DataGridViewRowEventArgs e)

        {

            //gdy pojawia się nowy wiersz, to przycisk w nim jest nazywany

            this.dgvExtAndDirs.Rows[e.Row.Index].Cells["colChooseDir"].Value = Form1.chooseDirButtonTitle;

        }


        #endregion


        #region configuration


        private bool CheckConfiguration()

        {

            this.checkingLog = new StringBuilder();


            bool result = true;

            List extensions = new List();


            //najpierw sprawdzenie, czy istnieje katalog źródłowy

            string sDir = this.txtSourceDir.Text;

            if (!Directory.Exists(sDir))

            {

                this.checkingLog.AppendLine("Wybrany katalog źródłowy nie istnieje: " + sDir);

                result = false;

            }

            //następnie dla każdego wiersza

            for (int i = 0; i < this.dgvExtAndDirs.Rows.Count; i++)

            {

                DataGridViewRow dgrv = this.dgvExtAndDirs.Rows[i];

                //jeśli nie jesteśmy w ostatnim wierszu i nie jest on pusty:

                if (!((dgrv.Index == this.dgvExtAndDirs.Rows.Count - 1) && (dgrv.Cells["colExtension"].Value == null)

                    && (dgrv.Cells["colTargetDirectory"].Value == null)))

                {

                    //jeśli nie podano rozszerzenia

                    if (dgrv.Cells["colExtension"].Value == null)

                    {

                        this.checkingLog.AppendLine("Nie podano rozszerzenia w wierszu: " + (i + 1).ToString());

                        result = false;

                    }

                    else

                    {

                        //jeśli rozszerzenie zawiera spację w nazwie

                        string ext = dgrv.Cells["colExtension"].Value.ToString().Trim();

                        if (ext.Contains(" "))

                        {

                            this.checkingLog.AppendLine("Rozszerzenie pliku nie może zawierać spacji: " + ext);

                            result = false;

                        }

                        //jeśli już jest takie rozszerzenie

                        if (extensions.Contains(ext))

                        {

                            this.checkingLog.AppendLine("Rozszerzenie pliku występuje kilkakrotnie: " + ext);

                            result = false;

                        }

                        extensions.Add(ext);

                    }

                    //jeśli nie podano katalogu

                    if (dgrv.Cells["colTargetDirectory"].Value == null)

                    {

                        this.checkingLog.AppendLine("Nie podano katalogu docelowego w wierszu: " + (i + 1).ToString());

                        result = false;

                    }

                    else

                    {

                        //jeśli katalog nie istnieje

                        string dir = dgrv.Cells["colTargetDirectory"].Value.ToString().Trim();

                        if (!Directory.Exists(dir))

                        {

                            this.checkingLog.AppendLine("Wybrany katalog docelowy nie istnieje: " + dir);

                            result = false;

                        }

                    }

                }

            }

            return result;

        }


        private void ReadConfiguration()

        {

            XmlSerializer ser = new XmlSerializer(typeof(ExtDirConfig));

            TextReader reader = new StreamReader(this.configFilePath);

            this.edConfig = (ExtDirConfig)ser.Deserialize(reader);

            reader.Close();

        }


        private void FillInterface()

        {

            this.txtSourceDir.Text = this.edConfig.SourceDirectory;

            foreach (KeyValuePair kvp in this.edConfig.ExtensionsDictionary)

            {

                string ext = kvp.Key;

                string dir = kvp.Value;

                this.dgvExtAndDirs.Rows.Add(new object[3] { ext, dir, Form1.chooseDirButtonTitle });

            }

            this.dgvExtAndDirs.Rows[this.dgvExtAndDirs.Rows.Count - 1].Cells["colChooseDir"].Value = Form1.chooseDirButtonTitle;

        }


        private void SaveConfiguration()

        {

            string confDirPath = Path.GetDirectoryName(this.configFilePath);

            //jeśli katalog nie istnieje

            if (!Directory.Exists(confDirPath))

                //to jest tworzony

                Directory.CreateDirectory(confDirPath);

            //serializacja konfiguracji

            XmlSerializer ser = new XmlSerializer(typeof(ExtDirConfig));

            TextWriter writer = new StreamWriter(this.configFilePath);

            ser.Serialize(writer, this.edConfig);

            writer.Close();

        }


        #endregion


        #region filesystemwatcher


        private void fsWatcher_Created(object sender, FileSystemEventArgs e)

        {

            while (true)

            {

                try

                {

                    this.MoveFile(e.FullPath);

                    break;

                }

                catch

                {

                    System.Threading.Thread.Sleep(100);

                }

                Application.DoEvents();

            }

        }


        private void MoveFile(string _filePath)

        {

            string ext = Path.GetExtension(_filePath).Remove(0,1);

            string targetDir = String.Empty;

            //wyszukanie katalogu docelowego

            if (this.edConfig.ExtensionsDictionary.TryGetValue(ext, out targetDir))

            {

                string targetFile = Path.Combine(targetDir, Path.GetFileName(_filePath));

                //przeniesienie, jeśli plik nie istnieje

                if(!File.Exists(targetFile))

                    File.Move(_filePath, targetFile);

            }

        }


        #endregion


    }

}

Miłej lektury :slight_smile:

Pliki wygenerowane automatycznie przez IDE też chcesz?

No i chętnie zobaczyłbym, jak to w Perlu wyglądałoby, jakbyś mógł pokazać?

bez urazy somekind , bo naprawdę odwaliłeś kawał dobrej roboty, ale Twój kod chyba nie nadaje się do celów edukacyjnych, bo trzymanie w jednej klasie (głównego okna) wszystkich metod, w tym operacji na plikach, nie jest raczej najlepszym przykładem dla uczących się

odnośnie tej najnowszej wersji:

  • gdy wybiorę z traya konfigurację, to obok aktualnego okna pojawia mi się kolejne, puste

  • nie wiem czy u mnie jest coś nie tak, ale w ciągu kilku minut nie przeniosło żadnego z trzech plików

  • System.ArgumentException: Path cannot be empty string or all whitespace z System.IO.Directory.CreateDirectory() takie coś mi się udało wygenerować, przy ścieżce C:\Documents and Settings\airborn\Pulpit\test\test_jpg która notabene już istniała