Press "Enter" to skip to content

Personalizacja systemu windows – level piatkosia

Przypomniało mi się coś z mojego okresu dojrzewania – że zawsze byłam skuteczna tylko, gdy się poważnie wkurzyłam.
Dopiero totalne wyprowadzenie mnie z równowagi dawało mi kopa do działania. Nie będę się rozwodzić na tym, co, albo raczej raczej kto mnie wkurzył tym razem;). Tak czy inaczej, rozmawiając z ukochanym wyrzuciłam mu, że równie jak moja współlokatorka, wkurza mnie jak mi się rozpakuje paczka tworząc folder a w nim content, zamiast się rozpakować w roboczym. Mówią, „nie ma co płakać nad rozlanym mlekiem, ile to przenieść”. No ale mam tego inżyniera i wypadałoby rozwiązać problem programowo, idąc za zasadą „jeśli coś robisz raz, zrób to ręcznie, jeśli znowu ci się to zdarza, zastanów się czy aby nie warto tego oskryptować i zrób to”. Jako że ostatnio mam fazę na windę 7 (tzn częściej ją uruchamiam i robi mi za główny OS), postanowiłam sobie dopisać małego liba (serverek comowski), który mi sprawę załatwi jednym kliknięciem PPM.

No to „dawaj naliwaj”, modem, connect, przeglądarka, jakiś google, szukam, nie da się z .net, trza winapi, omg ale to brzydkie brr… oooo jest rozwiązanie. Ano jeden z codeplex (aka szybciej wstanie niż się położył) userów postanowił poratować wszystkich toolowindoklepaczy i zrobił sharpshella. Projekt jest w nugecie, więc odpalam package manager console, wklepuję jak człowiek Install-Package SharpShell, tworzę klasę która dziedziczy po czym trzeba i mam co chciałam:)
Całość wygląda mniej więcej tak:

using System.Runtime.InteropServices;
using System.Windows.Forms;
using SharpShell.Attributes;
using SharpShell.SharpContextMenu;
using System.IO;

namespace MyExt
{
   [ComVisible(true)]
  [COMServerAssociation(AssociationType.Directory)]
    public class Extractor : SharpContextMenu
    {
        protected override bool CanShowMenu()
        {
            return true;
        }

        protected override System.Windows.Forms.ContextMenuStrip CreateMenu()
        {
            var menu = new ContextMenuStrip();
            var mymenuitem = new ToolStripMenuItem {Text = "Extract"};
            mymenuitem.Click +=mymenuitem_Click;
            menu.Items.Add(mymenuitem);
            return menu;
        }

        public static bool IsDirectoryEmpty(DirectoryInfo directory)
        {
            FileInfo[] files = directory.GetFiles();
            DirectoryInfo[] subdirs = directory.GetDirectories();

            return (files.Length == 0 && subdirs.Length == 0);
        }
        public static bool IsDirectoryEmpty(string path)
        {
            return IsDirectoryEmpty(new DirectoryInfo(path));
        }
        private void mymenuitem_Click(object sender, System.EventArgs e)
        {
            foreach (var VARIABLE in SelectedItemPaths)
            {
                FileAttributes attr = File.GetAttributes(VARIABLE);
                if ((attr & FileAttributes.Directory) == FileAttributes.Directory)
                {
                    var tmppath = Path.GetDirectoryName(VARIABLE);
                    var files = Directory.GetFiles(VARIABLE);
                    foreach (var file in files)
                    {
                        File.Move(file, tmppath + "\\" + Path.GetFileName(file));
                        if (IsDirectoryEmpty(VARIABLE))
                        {
                            Directory.Delete(VARIABLE);
                        }
                    }
                }
            }
        }
    }
}

i co tu się po kolei dzieje.
Funkcję która pyta o pojawieniu się menu zbyłam „return true;”, bo tak mi było wygodnie. Odsiewam ziarno od plew dalej.
Funkcja tworząca menu to tylko sprawa dodania elementu i zwrot zawartości- bardziej mnie interesi zawartość, czyli funkcja obsługująca kliknięce. Działa ona tak, że bierze pliki z folderu, wrzuca je do folderu w którym znajduje się folder w którym pliki były i wyrzuca go jeśli jest pusty. Dobra, namotałam, może łatwiej będzie obrazkiem
było
d:\dupa\dupa2\aa.txt
d:\dupa\dupa2\z1.txt
d:\dupa\dupa2\na.txt
to teraz jest
d:\dupa\aa.txt
d:\dupa\z1.txt
d:\dupa\na.txt
a sam katalog dupa 2 pozbywa się plików aa.txt, z1.txt, na.txt. Jeżeli któryś z plików o takiej nazwie już był, to zostaje na swoim miejscu (przeniesienie się nie udało – normalna funkcja move). Jeśli się okaże, że wszystkie pliki zostały przeniesione a folder pozostał pusty (co jest sprawdzane funkcją IsDirectoryEmpty), to go wywala (aka na co nam śmieci). Jak komuś to nie pasi, niech sobie przed kompilacją tego ifka z deletem w środku wywali.
Kompilujemy projekt (który był wybrany jako lib formsowy – nie aplikacja okienkowa – sam się z siebie nie uruchomi 🙂 ) i wrzucamy go. Hmm, tylko jak? srm install plik.dll -codebase, potem modyfikacja rejestru… no ej, laską jestem. Można prosić coś ludzkiego? I dostałam – ładnego toola pod nazwą Server Manager. Wybieram moją jeszcze ciepłą dllkę, testuje – działa jak chciałam. No to rejestruję, instaluję (dosłownie 1 button na operację) i mam. I używam. I cieszę się. I… kurka, muszę znaleźć zamiennik na linuxa. Albo sobie napisać:)
Jeszcze rzucę binarkami:
Moja gotowizna dostępna jest na tej stronce, zaś sam sharpshell jest dostępny na tej.

Obie zabawki są na wolnych licencjach.

3 komentarze

  1. Fajne. A cos na automatyzacje zadan o okresloneg godzinie minucie nie wiem otwarcie programu i wykonanie jakiejs czynności?

    • adminka adminka

      Automatyzacja o określonej godzinie i minucie? Do tego wystarczy zwykle dołączenie akcji do harmonogramu zadań (Schtasks.exe dla windows, crontab dla linux). Jeżeli chcesz napisać wykonywaną czynność, możesz po prostu stworzyć usługę systemową (services) i ją z harmonogramu odpalić.

  2. vixlur vixlur

    @k0sM3n

    Taska odpalanego co jakiś czas możesz sobie stworzyć w powershellu chociażby (każdy wie, że przeklikiwanie się przez interfejs windowsa ssie). Jeśli masz Powershell 4.0 (Windows 8 i nowsze) to wystarczy użyć New-ScheduledTask (https://technet.microsoft.com/en-us/library/jj649810.aspx). Jeśli nie masz Powershell 4.0 to sprawa się nieco komplikuje, ale nadal w miarę łatwo idzie to zrobić, mały example: http://pastebin.com/xfRqz2wR (i 'wynik’ działania: http://i.imgur.com/g0GVTc3.png).

    Samo to co miałoby się zrobić też można napisać w Powershellu, czy chociażby AutoIt.

Comments are closed.