Facing issue while listing file contents in cygwin

173 views Asked by At

Context: I want to install ".msi" file on remote windows machine via python script.

I have installed cygwin on remote windows machine and ssh service is running. I execute the command via ssh on remote windows machine from Linux host using python script. For installation of msi file i have used below command:

msiexec /package "msi file name" /quiet /norestart /log "log file name (say instlog.log)"

Now, to verify that installation is successful i list the contents of log file (instlog.log) and checks for string "Installation success or error status: 0".

Problem:

"type" command does not work in cygwin. So i tried "cd {0}; cat {1} | tail -5".format(FileLocation, FileName) to list file contents but i am getting output in different format and python script is unable to match above mentioned string in output. This is want i want to display on console:

MSI (s) (64:74) [18:03:51:360]: Windows Installer installed the product. Product Name: pkg-name. Product Version: 0.2.24-10891. Product Language: 1033. Manufacturer: XYZ Company. Installation success or error status: 0.

And what i am actually getting is:

M S I ( s ) ( 6 4 : 7 4 ) [ 1 8 : 0 3 : 5 1 : 3 6 0 ] : W i n d o w s I n s t a l l e r i n s t a l l e d t h e p r o d u c t . P r o d u c t N a m e : p k g - n a m e . P r o d u c t V e r s i o n : 0 . 2 . 2 4 - 1 0 8 9 1 . P r o d u c t L a n g u a g e : 1 0 3 3 . M a n u f a c t u r e r : X Y Z C o m p a n y . I n s t a l l a t i o n s u c c e s s o r e r r o r s t a t u s : 0 .

So somehow an extra space is introduced after each character in output. I want to know how can i get output in a normal way rather than space separated format. Thank you.

2

There are 2 answers

1
CristiFati On

The problem is that msiexec saved its log file in Unicode format. In Windows Unicode consists of 2 chars (meaning that each character that you see is stored in memory as 2 bytes or chars): the first is the codepage number and the second is the entry of the character in that codepage (that is the character itself). Because you're running on an English version the codepage number is 0 (or \0 or \x00 or NULL). Some popular editors are smart enough to figure the encoding out and only display the characters (leaving the interleaved NULL chars aside). Now there are some ways to get through this.

  • Upgrade cygwin. On my computer (I also have Cygwin installed) I don't experience this problem (my Cygwin is using: GNU coreutils 8.15 - this can be seen for example by typing tail --version). Here are some outputs (I included the hexdump at the end to show you that the file is in unicode format):

    cat unicode.txt
    

    yields: unicode chars

    tail unicode.txt
    

    yields: unicode chars

    hexdump unicode.txt
    

    yields:

    0000000 0075 006e 0069 0063 006f 0064 0065 0020
    0000010 0063 0068 0061 0072 0073 000d 000a
    000001e
    
  • Convert the msiexec logs to ASCII format. I am not aware of any native tool that does that but you can Google search for unicode to ascii converter and download such a tool; or as I mentioned earlier there are editors that understand unicode, one that i've already tried and is able to convert files from unicode to ascii is Textpad; or you can write the tool yourself.

  • If you're reading the msi log file from python you could handle the unicode files from the script. I assume that you have some code that reads the file contents like (!!! I didn't include any exception handling !!!):

    f = open("some_msi_log_file.log", "rb")
    text = f.read()
    f.close()
    

    and you're doing the processing on text. If you modify the code above to:

    f = open("some_msi_log_file.log", "rb")
    unicode_text = f.read()
    f.close()
    text = "".join([char for char in unicode_text if char != '\x00'])
    

text won't contain the \x00s anymore (and will also work with regular ASCII files).

1
szkj On

The log file should be converted to a 8 bit wide format like UTF8. This could be achieved with iconv command. You should install it with cygwin installer, and after that use the following command:

iconv -f ucs2 -t utf8 instlog.log > instlog2.log