Adobe Creative Cloud Update Fails With Error Code 50 (and Others)

Adobe Creative Could Desktop is the software that runs on your computer and allows you to keep your Adobe software (Photoshop, Illustrator, Dreamweaver, etc.) up-to-date. Creative Cloud notifies you when an update is available for those programs and lets you download and install the new versions.

Error 50

So far so good. The problem is when an update for Creative Could itself is available and you try to install it, it fails with esoteric error codes, in my case Error 50. The Adobe forums are full of users complaining about this problem and Adobe seem to either not knowing how to fix the problem or not being interested in fixing that problem.

This despite the fact that we are paying them a lot of money every month to have the privilege to use their software. But anyway I digress.

Adobe’s Solution

Adobe recommends to download and run the Creative Cloud Cleaner Tool to properly uninstall Adobe Creative Cloud (and possibly uninstall ALL Adobe software before), reboot, then retry to install Creative Cloud.

Well, this worked neither on my work PC nor on my home PC. Congratulations Adobe!

The Real Solution

Well, a clever guy named Michael found the solution: Boot your PC in Safe Mode with Networking to update the Creative Cloud application.

Here’s how to boot your PC in safe mode with networking:

  • From Windows XP to Windows 7, initiate a restart, and press repeatedly F8 while Windows is starting. You should get a so-called boot menu which allows you to chose the boot mode, e.g. Safe Mode with Networking.
  • Starting with Windows 8, Microsoft decided that this procedure was definitely to simple and so they implemented a convoluted scheme to start a PC in Safe Mode.

Once your PC is running in Safe Mode with Networking, just run the Creative Cloud application, and let it update itself. Hopefully this will now work without a problem. Then reboot in normal mode and let the Creative Cloud application update the other programs as usual.

Voilà, problem solved!

C# – Linq To Sql – Handle a Transaction Deadlock

When using Linq To SQL, here’s the pattern I use to retry an operation after it failed because a deadlock occured in a SQL Database:

while (true) {
    try {
        using (var scope = new TransactionScope()) {
            using (var db = new MyDataContext()) {

                // Do what you need to do on the DB...

                db.SubmitChanges();
            }
            scope.Complete();
        }

        break;
    }
    catch (SqlException e) {
        if (e.Number == 1205) {
            Thread.Sleep(new Random.Next(1000));
        }
        else {
            throw;
        }
    }
}

C# – Linq to Sql – Reattach and Update an entity

If you’d listen to Microsoft, you’d believe than in Linq to SQL, you can’t reattach a changed entity to a new DataContext and submit the changed entity to the database. Well this isn’t true. It can be done with a little bit of foresight.

The first step is to make sure that the underlying table has a timestamp column. Then you need to make sure that the entity object takes this into account. For this you should only create the entity in Visual Studio’s designer after the timestamp column has been added. If it already exists, delete it from the designer, then drop it from the Server Explorer to the designer again.

Now that this basic infrastructure is in place, you only need to make sure that when you get an entity from a DataContext, and that entity will be updated and reattached to another DataContext later, the initial DataContext should have the EnableDeferredLoading set to false. You can then reattach to the second DataContext with the Attach(T entity, bool isUpdated) method and submit the object.

Example:

Product product;

using (var db = new MyDataContext())
    db.DeferredLoadingEnabled = false;
    product = db.Products.SingleOrDefault(p => p.Id = "1");
}

product.Name = "Updated Name";

using (var db = new MyDataContext())
    db.Attach(product, true);
    db.SubmitChanges();
}

Voilà, you are done!

C# : How to Wrap Winword COM InterOp Methods

If you have ever used the Microsoft Office COM Interop classes to automate Word (or any other Office Application), you know those methods often take a lot of parameters, which can be tedious.

Note: This was written a while ago before .Net 4.0 was available. .Net 4.0 introduces the dynamic keyword which makes COM Interop much easier.

For example, the Word.Documents.Open() method takes 16 parameters in the Interop v 12 classes. You don’t want to have to specify all those parameters at each method call.

So what can you do? Well, starting with .Net 3.0, you can use a nice feature called extension methods. You will leverage those to give you nice methods to call with few parameters.

So you define a static class that will contain the extension methods of the various COM Interop classes you are interested in. For example, for the Open method discussed above, see how I wrap it with my extension method:

using Microsoft.Office.Interop.Word;

namespace MyWordNamespace {

    public static class ExtensionMethods {

        public static Document Open(
                this Documents documents, 
                string fileName) {

            Object filename                 = fileName;
            Object confirmConversions       = Type.Missing;
            Object readOnly                 = Type.Missing;
            Object addToRecentFiles         = Type.Missing;
            Object passwordDocument         = Type.Missing;
            Object passwordTemplate         = Type.Missing;
            Object revert                   = Type.Missing;
            Object writePasswordDocument    = Type.Missing;
            Object writePasswordTemplate    = Type.Missing;
            Object format                   = Type.Missing;
            Object encoding                 = Type.Missing;
            Object visible                  = Type.Missing;
            Object openConflictDocument     = Type.Missing;
            Object openAndRepair            = Type.Missing;
            Object documentDirection        = Type.Missing;
            Object noEncodingDialog         = Type.Missing;
            Object xmlTransform             = Type.Missing;

            return documents.Open(
                ref filename,
                ref confirmConversions,
                ref readOnly,
                ref addToRecentFiles,
                ref passwordDocument,
                ref passwordTemplate,
                ref revert,
                ref writePasswordDocument,
                ref writePasswordTemplate,
                ref format,
                ref encoding,
                ref visible,
                ref openAndRepair,
                ref documentDirection,
                ref noEncodingDialog,
                ref xmlTransform
            );
        }
    }
}

Which you can then call like this (I’ve also added wrappers for Documents.Close and Application.Quit):

using Microsoft.Office.Interop.Word;
using MyWordNamespace;

namespace MyApplication {

    class Program {

        static void Main(string[] args) {

            Application application = new Application();
            try {
                application.Visible = true;

                Document document = application.Documents.Open(
                    @"c:\temp\Document.docx"
                );
                Thread.Sleep(5000);

                application.Documents.Close();
            }
            finally {                
                application.Quit(WdSaveOptions.wdDoNotSaveChanges);
            }
        }
    }
}

Nice, isn’t it?

Happy programming!

Python Programming – Photo Web Gallery Generator

Introduction

After some time learning Python and tinkering with it, I decided that it was time to use it in a “real world” application. After some thinking, I came up with the idea to program a web gallery generator, which would not be a too big project to work on my spare time and would also be useful to maintain my web site.

Requirements

So I took some time to brainstorm about the functionality to put into the application and came up with the following list:

  • Able to process jpeg files
  • Generate an index page with thumbnails and a main page for each picture
  • The generated html files should be based on templates
  • The settings should be persistent and stored in an xml file
  • A first version should work with the command line, a second one should have a gui
  • The gallery generation should be asynchronous and cancelable at any time

Looking at these requirements, it became quickly obvious that a standard Python distribution would be able to handle most of these requirements, except the image manipulation part. After some research on the net, I found that the Python Imaging Library would be the ideal candidate for this part. For the graphical interface, I decided to stick with Tkinter, which is a defacto standard for Python Gui’s.

Design and Coding

The design phase revealed the need for about a dozen classes and coding was rather straightforward, except for some problems that will be described in the next section.

Even if the application is a small project, it displays some interesting techniques with Python:

  • Image manipulation
  • XML processing
  • Tkinter gui’s
  • Multithreading

Problems encountered

Minidom’s Parse

A first annoying problem I encountered was that the xml.dom.minidom.parse(file) function seems to add empty elements when the xml stored in the file is stored on multiple lines.

This seems odd as the minidom is the standard DOM implementation delivered with Python. Anyway, the workaround was to read the file line for line in memory, to remove the line endings and then to concatenate it into a string. The string is then parsed using the xml.dom.minidom.parseString() function

f = file(Configuration.__xmlFileName, "r")
try:
    # We don't use xml.dom.minidom.parse() because it has a bug that
    # inserts empty elements if the xml files contains spaces and \n's. 
    # So we need to workaround this :-(
    stringConfig = ""
    for line in f.readlines():
        line = line.strip()
        stringConfig += line
	
    self.document = xml.dom.minidom.parseString(stringConfig)
finally:
    f.close()

Validating numeric input in Tkinter Entry fields

I encountered a second annoying problem when I tried to validate numeric input in TKinter Entry fields. This is no standard Tkinter functionality and you have to know the underlying Tk toolkit to know what to do. So I tried to recall the little Tk knowledge I possessed and after some googling and Python/Tk voodoo came up with a solution that subclasses the Tkinter Entry class:

class IntEntry(Entry):
    """
    Class that validates that an entry is an integer.
    Put together after much hacking :-(. These are really low level Tkinter and
    TCL details...
    """
    def __init__(self, master, **kwargs):
        kwargs['validate'] = 'key'
        kwargs['vcmd'] = master.register(self.validatecommand) + ' %P'
        kwargs['invcmd'] = self.invalidcommand
        Entry.__init__(self, master, kwargs)
        
    def validatecommand(self, new):
        try:
            int(new)
            return True
        except:
            return False
    
    def invalidcommand(self):
        return True

Now don’t ask me why it exactly works all I can say is that it works 😉

Image quality

Even if the quality of the resized images is good, it is still below the quality of images resized with other tools, for example BreezeBrowser. In comparison the images generated with PIL are a little bit more blurry, even at the best JPEG quality available. I think the quality is good enough to generate Web Galleries, but an improved quality would be welcome nevertheless.

Screenshots

Main window

KecGalleryGenerator1

Generate gallery dialog

KecGalleryGenerator2

Download

The Gallery Generator was coded using Python 2.4.3, PIL 1.1.6 and wxPython 2.8.4. You need to install those (or a later version) to use the Gallery Generator

Download Kec’s Gallery Generator: Version 0.6.1

Extract the zip file into a folder, then execute WxGui.py to start the WxPython GUI. If you wish to start the Tkinter GUI, execute TkGui.py. Note that the Tkinter GUI is not up-to-date and will be dropped in the future.

The archive also contains two sample template folders, one with very simple templates and on with the actual templates I use for my web site.

Future improvements

Currently the Gallery Generator has already a good level of functionality and suits my needs well, however I’m thinking on adding the following things to improve the generator:

  • Delivery as a stand-alone executable or installable on Windows platforms
  • Option to keep image proportions when resizing

Conclusion

This small project has shown me that Python is much more than a simple scripting language but must be seen as a full-blown programming language that incidentally happens to be interpreted. It provides an extensive standard library and modules for many application domains can easily be found on the net.

However, it also has its quirks as we have seen above which can be annoying. I my opinion, the productivity claims of some Python evangelists must be seen as wishful thinking, and this for the following reasons:

  • The language is not simpler than for example Java. It has operator overloading, lambdas, modules, advanced metaprogramming, generators, etc…
  • Dynamic typing. In my opinion, dynamic typing has the following drawbacks which lead to decreased productivity:
    • It forces the programmer to play the role of the compiler to check for obvious programming errors.
    • Less readable code as type information is not always obvious in function or method signatures.
    • Less intelligent development environments because type information is not available when you write the code (refactorings, intellisense, code navigation, etc…).
  • The documentation is only average for the standard library and sometimes bad or non-existent for add-in modules. A standard documentation format and documenter tool à la Javadoc would be a huge step forward
  • Code quality of libraries seems a little bit below the quality of the libraries of commercial languages
  • The gui library delivered with the language has only a basic level of functionality and it is better to use other ones for serious development.

That being said, Python is a fun language to work with but like any languages it has its learning curve which must not be underestimated. 🙂