Sunday, October 24, 2010

Replace Files - v2.0

I've never mentioned this project on my blog before. This is based on the requirement when you have to place a file somewhere in a directory (maybe many locations) and you do not know where. This is a search and replace tool which will do the job for you, only in smarter way.

Short steps on how to use
  1. Select source folder where your new files are.
  2. Select destination folder where you want your files to be replaced to.
  3. If you don't know exact target folder, you may select "Recursive" option (it will search in sub-folders too).
  4. If you are worried about taking a backup before replacement, you can select that option too. The original file will be renamed to <original-name>.old. Just beware that if you replace the files again with backup feature on, the original old file will be overwritten.
  5. Select the type of files that you are operating on. eg. - *.exe, *I*don't*know*, H?ll*.txt, mspaint.exe [;)] etc. These patterns are based on normal DOS search wildcards.
  6. If there are some files that you want to avoid to be operated on, put them in Exclude list section. These do not use wildcards. eg. - if you want to avoid EXE files (search filter: *.exe) with name containing obsolete, then you add a filter by the same name. Hence, out of these files - abc.exe, aobsoletebc.exe, haha.obsolete.exe - only abc.exe will be searched and replaced.
  7. Click Find button. Wait for it to finish.
  8. Once done, the files which differ in target locations are highlighted in yellow color. You have option of deleting the list items, if you don't want them to be replaced.
  9. Click "Set up" button, and it's done. If you will run Find again immediately, then you can see that there will empty lists (unless you manually intervened.) This is a sign that your files are already placed.

Features:
  1. CRC32 based accurate checks for file content.
  2. Fast file search.
  3. Option available to use GAC Util (for assemblies to be put in ASSEMBLY folder in Windows). For this, for now, you have to run this tool from Visual Studio Command Prompt. That way, it locates the gacutil.exe. Supports Visual Studio 2005, 2008 and 2010.
  4. You can run external diff tools from inside the tool. It has been configured by default for Winmerge (still need some more testing on that), but if you use any other diff tool, provide the path in the Configure->Options menu.

Version 2.0 is the first public release. So don't worry, you have not missed earlier versions :)
Please report bugs here.
Download: Zipped Binaries

Tuesday, October 19, 2010

Auto Save in Paint - ver 1.7.0.1 - Patch Release

This is a small post to post a minor patch on top of release version 1.7

Fixes:
1. The "Options" dialog pops-up "The file [] doesn't exist! Please enter a valid file path." message even when the "Use custom application to save images" is unchecked. This message should only pop-up when the aforementioned checkbox is selected and the file path provided leads to invalid file path.

I'm only uploading the binary+source for the patch, instead of the whole package. Please download ver 1.7 first and then apply the patch.

Download links for Auto Save in Paint v1.7.0.1 patch:
Binary
Source

Saturday, October 16, 2010

Auto Save in Paint - ver 1.7

Auto Save in Paint is back! :)

In the last post, I said that I was out of ideas on how to go further on with this project. Thanks to the users of this tool (special thanks to tflamb!) I got some nice inputs. Seems like I am not the only one who likes it :)

So, what is new in this version? Here is the list:
  1. Options menu - Tflamb and I discussed on the behavior of MS Paint in different OS version. The tool was originally created on Windows XP. MS Paint of XP has different save algorithm than that in Windows 7. In Windows 7, default MS Paint seems perform both ways - sometimes it will bloat up an image, other times, it will shrink it good. Now with option available to choose an application which can do the save part, you can use your own tool. For example: you have MS Paint from Windows XP copied on Windows 7 in some folder, and you want XP Paint to run with this tool rather than Win 7 Paint. Now, you can do it. Just browse to the file location where your tools is kept and you're done.
  2. Don't ask again option - If the constant pop-us bother you, you can disable them. This information goes into a .config file which is created in the folder where your application resides. It's XML file.
  3. Some minor segregation of the projects (source code) - I am providing source code of the "main" tool in this version. This is by demand too! :) But remember that I've not provided all the source files. There are some custom libraries that I have created (as DLLs) and they can be used for building up the code. You can set them in references, and I hope you'll be able to build the code. (I'll not go into details here on how to configure projects and all.)
If there is any bug that you have found, or are unable to build the code, please let me know.

Thanks again for using Auto Save in Paint! :)

Download links for Auto Save in Paint v1.7:
Release Binaries
Source Code

Sunday, October 3, 2010

Are we smart or what

I have been developing application in more than 7 computer languages for about 7-8 years. Sometimes I wonder how many people out there are truly passionate about technology and have dedicate some part of their life for self-improvement.

Most of the coders hired by big companies are freshers. Anybody can code, true. Then there are people like me who have to study each and everything in order to maintain that soggy piece of software.

But this post is not about criticizing ways of the world. I'm highlighting how much a readable code means to a maintenance/sustenance team. One of the tip is this -

If you have see a function having a boolean argument, do not use it, if possible. Try to break that function down in two functions with readable names which depict their intentions clearly.

Why do I say so? I say because boolean parameters are not made for readability. They are just a type to differentiate two ways of processing. For example:

void Greet(string message, bool world)
{
    if (world)
        Console.Writeln(message + " world!");
    else
        Console.Writeln(message + " me!");
}

Now, using it seems strange:

Greet("Hello", false);
Greet("Hello", true);

If we break it down to two functions, namely, GreetWorld and GreetMe, then it becomes more readable and understandable.

void GreetWorld(string message)
{
    Console.Writeln(message + " world!");
}

void GreetMe(string message)
{
    Console.Writeln(message + " me!");
}

//Usage
GreetWorld("Hello");
GreetMe("Hello");


There are many standards set for coding. But most of them are same old crap. Think differently.

Sunday, May 2, 2010

Dispose Complete Hierarchy


While working with a family hierarchy of a class, I was trying to optimize the memory usage because there was a case reported in one of the tools that worked on that the data loaded in memory was using up all the RAM. I worked on the case and found that the custom classes that were written for the project were not disposable. This leaves memory freeing job to Garbage Collector, and its not best decision sometimes.

I wrote two classes for making disposing of objects easy. NayanTools.Dispose method is the core of disposing engine.

One thing that you need to keep in mind while using this function, it will dispose the member objects of the object you pass to it, as well as, it will go in recursion - provided all those classes are implemented from AbstractDisposingClass.

So, the implementation of a disposable class using AbstractDisposingClass should look like -

01 class A : AbstractDisposingClass {
02 ~A() {
03 dispose(false);
04 }
05 };


The usage is simple, as you dispose any other class-
A n = new A();
n.Dispose();


A bit more complex example will be -
01 class A : AbstractDisposingClass {
02 List<string> jjj = new List<string>();
03 ~A() {
04 dispose(false);
05 }
06 };
07
08 class B : AbstractDisposingClass {
09 string test = string.Empty;
10 List<string> hello = new List<string>();
11 List<A> allo = new List<A>();
12 Dictionary<int, int> ddd = new Dictionary<int, int>();
13 public B() {
14 allo.Add(new A());
15 }
16 ~B() {
17 dispose(false);
18 }
19 };
20
21 ...
22
23 private void destroyExample () {
24 B n = new B();
25 n.Dispose();
26 }


Here is the code for the classes and methods.


01 using System.Collections;
02 using System.Reflection;
03 ...
04 public static class NayanTools {
05 public static bool IsList (object obj) {
06 IList list = obj as IList;
07 return list != null;
08 }
09
10 public static bool IsCollection (object obj) {
11 ICollection coll = obj as ICollection;
12 return coll != null;
13 }
14
15 public static bool IsDictionary (object obj) {
16 IDictionary dictionary = obj as IDictionary;
17 return dictionary != null;
18 }
19
20 public static void Dispose (bool bNotDisposed, object _object) {
21 if (bNotDisposed && _object != null) {
22 Type type = _object.GetType ();
23 FieldInfo[] arrayFI = type.GetFields (BindingFlags.FlattenHierarchy|BindingFlags.GetField|BindingFlags.Instance|BindingFlags.NonPublic|BindingFlags.Public);
24 foreach (FieldInfo fieldInfo in arrayFI) {
25 object fieldObject = fieldInfo.GetValue (_object);
26 if (fieldObject != null) {
27 if (NayanTools.IsDictionary (fieldObject)) { //key-value type collection?
28 IDictionary dictionary = fieldObject as IDictionary;
29 foreach (object _ob in dictionary.Values) {
30 if (_ob is IDisposable && _ob != null) {
31 IDisposable _disposeableObj_ = _ob as IDisposable;
32 _disposeableObj_.Dispose ();
33 }
34 }
35 dictionary.Clear ();
36 }
37 else {//normal collection
38 if (NayanTools.IsCollection (fieldObject)) {
39 ICollectioncoll = fieldObject as ICollection;
40 foreach (object _ob in coll) {
41 if (_ob is IDisposable && _ob != null) {
42 IDisposable _disposeableObj_ = _ob as IDisposable;
43 _disposeableObj_.Dispose ();
44 }
45 if (NayanTools.IsList (fieldObject)) {
46 IList list = fieldObject as IList;
47 list.Clear ();
48 }
49 }
50 }
51 }
52 if (fieldObject is IDisposable) {
53 IDisposable _disposeableObj = fieldObject as IDisposable;
54 _disposeableObj.Dispose ();
55 }
56 fieldInfo.SetValue (_object, null);
57 }
58 }
59 }
60 }
61 }
62
63 [Serializable]
64 public abstract class AbstractDisposingClass : IDisposable {
65 [field:NonSerialized]
66 protected bool m_IsDisposed = false;
67
68 public virtual void Dispose () {
69 dispose (true);
70 GC.SuppressFinalize (this);
71 }
72
73 protected virtual void dispose (bool bNotDisposed) {
74 if (!m_IsDisposed) {
75 m_IsDisposed = true;
76 NayanTools.Dispose (bNotDisposed, this);
77 }
78 }
79 }

Auto Save in Paint - ver 1.6

This is latest version of AutoSavePaint application. Nothing major, but some fixes.

Fixes
  1. Busy icon was not properly showing. Fixed now.
  2. The icons to show the job status (red, green, orange) were not properly showing sometimes. Fixed.

The next version will take some time as there is nothing much to be fixed right now. And I have to think about new features (I don't have any idea!) =)

If you would like to see some better changes, please provide feedback.

Updated Download Link: Auto Save in Paint 1.6

Update 1-Aug-2010:
I have tested and experimented this tool on Win XP, and it works great. But after trying it on Win 7, it seems that the Paint application of Win 7 works differently. The results can be opposite. I observed a 41 KB JPEG file turning to 62 KB after saving it.

This tool works fine. Since it is dependent on external application (Paint here), the saving algorithm may vary, and so do the results.

Monday, February 22, 2010

Auto Save in Paint - ver 1.5

Good news! The application just got simpler!! :)

I feel that a small tool should not be complex. Even if its filled will complex algorithms, the user should not feel intimidated by it.

In this version, 1.5, of AutoSavePaint, I have removed two lists to show the input and output. Rather, you just load file on one list and there it gets processed. Drag and drop and other features are still maintained.

Read more details about the tool here.

Features Added:
1. Recursion - If you wish to select images from a folder and its sub-folders, you can do that now. No need to go into each and every directory and add images. How to use? When you select a folder, just make sure that the 'Recurse' check-box is selected. That's it!
2. Progress report - Now you can see how much work has the tool done in a progress bar. Looks good too!
3. Toolbar - I removed the buttons on side and moved the functionality in the toolbar buttons. Clearer and compact interface.
4. Reduced Size - The file size of the application got smaller. This helps in loading it faster!
5. Icons - :)

For programmers, the news is - I wrote 3 custom controls and one generic animation class!! It was not easy, believe me. I'm glad they are bug free to max extent.

I'll be putting up the controls' info on Codeproject soon.

Download the new version 1.5 of AutoSavePaint here. Password is same, "Paint" (without quotes). It will remain same for all releases of this project.

Feedbacks are welcome. :)

Friday, February 19, 2010

Auto Save in Paint

[Update Start - 19-Feb-10]
  • It also supports drag and drop feature. Drop folders with images or just drop JPEG images on the list (named "Select") area, and they are queued for processing. Note - the list will be added with the data you are dropping subject to the option that you have selected (Folders or Files).
  • Sorry, but I missed out this - if your images are huge, and by that I mean, like 30 MB+ (an estimated figure), then obviously Paint will take long time to load the image. The time taken by Paint to load an image also depends on how much RAM your PC has and what is the speed of your processor. More RAM and faster processor will probably help in loading the images quickly.
  • The thing is, if it takes more than 30 secs to load an image in Paint, AutoSavePaint will ask you if wish to kill it. If you say yes, then it will move on to the next image in the list. Idea is that if an image takes that long, probably your PC is not fast enough or you have insufficient RAM. =D
  • Updated to v1.1 - Download link
[Update End]

I am very much into photography. But with digital images you have a problem - high resolution images take lot of space. Unless you want to ruin them, you do not modify them by reducing their size or content quality.

These images, if JPEG format, are mostly uncompressed (or poorly compressed) by the cameras. This is the reason why each one of them can be so huge in file size. If you are professional photographer, you must be already having hard disks of many tera-bytes of space to keep these pictures.

I accidently found out that 'Paint' application (on Windows platform, which supports JPEGs(!)) is the cheapest way to compress these images. Yes, I know that there are hundreds of applications which do so much better. But consider these facts -
1. MS Paint is light weight.
2. It doesn't lose the quality of JPEG fed to it (unless you are converting an image from another format).
3. The file size reduction is between 20% to 80% (as observed).

I have already recovered gigabytes of space from my previously saved images using Paint.

Now ask the question:
What is the problem then?

Answer: You have to open each file in Paint and save them individually. Paint doesn't open multiple images. And, opening multiple Paint instances can take up lot of memory. This is a big pain!

Till now. :)

I created a tiny application, 'Auto Save in Paint' (AutoSavePaint) which automates the above procedure. So, you feed it a list of JPEG images or a folder in which you might have thousands of JPEG images. Then, ask it to process them. The application will open each image in MS Paint, save it, and then close that image. This will go on till all the images have been processed.

You might say that you already have seen some tools which can process multiple files. To this I would say that they are mostly not free, shareware, ad-ware, eat up loads of memory themselves while loading, or are command line based. Even then, (so far) I have not seen any tool which compresses the JPEGs better than MS Paint - in simplest way. Sure, you can tweak the options in tools like GIMP and Photoshop to give you smallest file size output, but try doing that to 2000 pictures :)

Yes, if you are geek enough, you would be running some scripts or command line programs which can take care of automating the tasks. But, unfortunately, not everyone can deploy such solution easily.

Benefits of AutoSavePaint -
1. Small memory footprint (in layman's terms, very small in size)
2. Loads up quickly
3. Uses third party tool to do the dirty work (MS Paint in this case). Hence, lesser chances of introducing its own bugs =D
4. Automatically detects errors if Paint could not open any image. It happens too :-/ (blame Microsoft)
6. Provides report of what has been done.

Steps to use -
1. Start it.
2. Provide it folder(s) where JPEG images are kept, or give it list of files individually.
3. Press start button and sit back. Use stop button if you want to interrupt the process.

Points to note -
Do not use your PC while AutoSavePaint is working =D or you will see weird things happening.
Since MS Paint doesn't provide any convenient way to automate, I have used some programming tactics to achieve the result. Best time to use this utility will be when you are going to sleep or are stepping away from your PC for a while. Let it work on its own.

Cons or dependencies -
1. It needs .NET 2.0 framework. Most of the Windows OS these days already have it. If you do not have it (?!!) then you can download it from MS's website. Here is the link.
2. It works only on Windows OS.
3. Uses MS Paint. If you have uninstalled MS Paint by any chance (?!!) then you can not use this tool.

Please try it if you like, and do provide feedback :)
The link is http://www.datafilehost.com/download-d1ad5e29.html (look in the updates). The file name is AutoSavePaint.zip and its password is "Paint" (without quotes).


PS - Its in early phase, so please bear with me if you find any bug :) Send those bug details to me along with a little description of what happened exactly.