December 30, 2008

UI-less Self-Extracting EXE

Filed under: self-extracting EXE — Tags: — admin @ 2:12 pm

The most common question regarding Chilkat self-extracting EXE’s is: How do I create a silent extractor that runs a “setup” program after extracting?

Answer:
Here is a sample command line that creates a silent self-extracting EXE:

ChilkatZipSE -u unlockCode -a -sm -sp -nowait -r setup.exe -exe a.exe a.zip
  1. The “-r” option is used to specify the name of a setup program found within the .zip that is being converted to a self-extracting EXE.
  2. The “-a” option is for creating a self-extracting EXE that will automatically extract to an automatically-chosen temp directory. If “-a” is used but “-r” is NOT USED, then the resulting EXE *will* display a dialog. The reason is that it makes no sense to extract to some unknown temp directory unless there is a setup program that can do something with the extracted files.
  3. The “-sm” option is for creating a self-extracting EXE that suppresses the main dialog.
  4. The “-sp” option is for creating a self-extracting EXE that suppresses the progress dialog.
  5. The “-nowait” option allows the self-extracting process to exit before the setup.exe program completes.
  6. The “-exe” option specifies the name of the self-extracting EXE to be created. If omitted, the EXE produced has the same name as the .zip but with a .exe extension.

Some Important Notes: If the embedded setup EXE does not run, try running the self-extracting EXE with a “-log” runtime option to see what happened. For example:

a.exe -log whatHappened.log

December 26, 2008

Inflate from Zip to memory in C++

Filed under: zip — Tags: , , — admin @ 2:17 pm

This example demonstrates how to inflate in-memory from a Zip in C++:

    CkZip zip;

...

    // Assume we have a CkZip object and a .zip has been loaded.
    // It may have been loaded from a file by calling OpenZip, or from an
    // in-memory image of a .zip by calling OpenFromMemory.
    // (or any of the other CkZip.Open* methods)
    CkString strXml;
    CkByteData gifData;

    // Find the file within the zip containing the data we want to access...
    CkZipEntry *entry = zip.FirstMatchingEntry("*hamlet.xml");
    if (entry)
	{
	// Found it.  This is a text file that may be inflated to a null-terminated
	// string.
	const char *xmlText = entry->inflateToString2();

	// Copy the text to a safe place.  Once the CkZipEntry object is deleted,
	// it is no longer a valid pointer:
	strXml.append(xmlText);

	delete entry;
	}

    // Get the data for a binary file:
    entry = zip.FirstMatchingEntry("*dude.gif");
    if (entry)
	{
	entry->Inflate(gifData);
	delete entry;

	// The binary bytes may be accessed like this:
	const unsigned char *gifBytes = gifData.getData();
	unsigned long numGifBytes = gifData.getSize();
	}

Updating an ActiveX DLL

Filed under: ActiveX — Tags: — admin @ 8:31 am

Question:
I have several of your programs installed on many machines. The problem is that some of these are older file DLL’s that need updating. What is the easiest way to update a DLL? If I run the .msi install, I just end up with two version of the DLL when I go into add/remove programs of the DLL.

Any suggestions would be appreciated. I am doing this for many machines remotely and would like to be able to script it.

Answer:
Having a fundamental understanding of ActiveX registration will answer all of your questions (in fact, the answers will be obvious). Spending 15 minutes reading this page ( http://www.chilkatsoft.com/p/p_177.asp ) will save you many hours in the long run and you’ll seem like a genius to others… ;-)

I’ll boil the contents of that page down even further: In a nutshell, the purpose of ActiveX registration is to associate a name with a DLL file. When your source code contains some form of CreateObject(”Chilkat.MailMan”), the underlying software (VB runtime, ASP runtime, whatever…) needs to lookup “Chilkat.MailMan” in the Windows registry to find the DLL file it should load. Simply knowing this answers all sorts of questions:

  1. Does my DLL need to be located in system32? No. Because the registry entry may point to a DLL located anywhere in the filesystem. (Any software that installs DLLs into system32 is a clear indication that the application developer doesn’t have an inkling of an understanding of ActiveX registration.)
  2. Can I change the name of my DLL after registering it? No, because the registry entry is pointing to the DLL file. If you change the name, you better change the registry entry (i.e. re-register the DLL with regsvr32)
  3. How do I update the DLL? Simple: Copy over the old DLL. The registry entry is still pointing to it so there’s no worry there… It’s possible that a process (such as IIS) has a lock on the DLL such that you cannot copy over the existing DLL. In that case, restart IIS (or whatever process is holding the lock) and then copy.

Non-English String Literals in C++ Source Code

Filed under: Encoding, VC++ — Tags: , , , — admin @ 7:43 am

When a C++ compiler compiles a C++ source file, it must process the bytes according to a character encoding and that is typically ANSI.  ANSI is not a character encoding, it is simply a keyword that says “Use the default multi-byte character encoding for this computer based on its current locale.”   Therefore, if your program is originally written in Poland and contains string literals (i.e. character string constants in double-quotes) with Polish characters, the same source when compiled on a typical computer in France will not produce the same results.  The bytes for the Polish characters will instead be interpreted as Latin1 characters and the string will be different.  This example demonstrates a technique you may use to embed string literals using quoted-printable so that the C++ source may be compiled on any computer without character encoding issues caused by the locale.   Chilkat provides a free tool to quoted-printable encode a string (which may contain characters in any language):

Quoted-Printable Encoding Tool Download

Here is a screenshot:

Quoted-Printable Encoder

The quoted-printable encoder is a very simple C# program that uses the Chilkat.CkString class.   Here is the complete source code:

        private void button1_Click(object sender, EventArgs e)
        {
            Chilkat.CkString str = new Chilkat.CkString();
            str.append(textBox1.Text);
            str.qpEncode(comboBox1.Text);
            textBox2.Text = str.getString();
        }

Using Quoted-Printable String Literals in C++

Use the tool to convert your string to quoted-printable using the utf-8 character encoding.  (utf-8 is the multi-byte encoding for Unicode, so it is able to mix characters of any language in a single NULL-terminated string.  A “multibyte” encoding is a character encoding such that each character is represented by one or more bytes, and there are no NULL bytes.)

Use the quoted-printable encoded string in your C++ source code like this:
(This example constructs an IMAP mailbox name using Vietnamese characters)

    CkImap imap;
    bool success;
...

    CkString str;
    str.append("C=C3=B4ng c=E1=BB=99ng");
    str.qpDecode("utf-8");
    str.prepend("Inbox.");

    imap.put_Utf8(true);
    success = imap.CreateMailbox(str.getUtf8());
    if (success != true) {
        printf("%s\n",imap.lastErrorText());
        return;
    }

December 16, 2008

FTP - 553-Can’t open that file: Invalid argument (in htdocs)

Filed under: FTP — Tags: — admin @ 12:55 pm

This post describes a strange error on one type of FTP/web server if FrontPage extensions are installed. The error message provided by the FTP server is very misleading. Here is an explanation:

When FrontPage Extensions are installed on a domain, FTP access to the
htdocs folder, and all of its child folders, is limited to read and list
only. There are no write permissions.
These permissions apply to all FTP accounts, and are applied to ensure that
FrontPage Extensions cannot be broken by using FTP.
Removing FrontPage Extensions from a domain will reset permissions, and
allow full file and directory access through FTP.

This is a segment of the FTP session log that shows the error:

CWD htdocs/temp
250 OK. Current directory is /htdocs/temp
.
PORT 192,168,1,30,6,16
200 PORT command successful
.
STOR test2.csv
553-Can't open that file: Invalid argument
553 Rename/move failure: No such file or directory

This is one possible solution: “I don’t know how other webspace is set up but I have found a workaround by creating a folder below the htdocs folder (where the website resides) and that works fine.”

December 9, 2008

FTP Timeout trying to Connect on Port 990

Filed under: FTP — Tags: — admin @ 2:33 pm

Question: What is the cause of this error?

ChilkatLog:
  Connect:
    DllDate: Dec  2 2008
    UnlockPrefix: Anything for 30-day trial
    Username: <username>
    Component: .NET 2.0
    Hostname: <hostname>
    Port: 990
    IdleTimeoutMs: 60000
    ConnectTimeout: 60
    HeartbeatMs: 0
    Timeout waiting to read socket or accept connection
    timeoutMs: 60000
    Failed to read FTP response line..
    initialStatus: -1
    initialResponse:
    Failed to connect to FTP server.

Here is my code:

            ftp.Hostname = "<ip>";
            ftp.Username = "<username>";
            ftp.Password = "<password>";
            ftp.Port = 990;
            ftp.AuthTls = false;
            ftp.AuthSsl = true;

            success = ftp.Connect();
            if (!success)
            {
                Console.WriteLine(ftp.LastErrorText);
            }
            else
            {
                ftp.Disconnect();
            }

Answer:
Port 990 is for implicit SSL/TLS, where the connection is SSL/TLS from the start. You would set both AuthTls and AuthSsl = false, but set the Ssl property = true. However, it looks like nothing is listening at port 990, so you probably want explicit SSL/TLS. With explicit SSL/TLS you connect on the normal unencrypted FTP port 21 and then the connection is immediately converted to SSL/TLS. In this case, you would set AuthTls or AuthSsl. In most cases it doesn’t matter which. Setting AuthTls causes the Chilkat FTP2 component to send the “AUTH TLS” command to initiate the handshake to convert to a secure channel, the AuthSsl property causes the “AUTH SSL” command to be sent. Some FTP servers require one, some require the other, some accept both (just another annoyance to make FTP more complicated than it needs to be…)

December 8, 2008

SSH - Multiple Commands w/out Reconnect

Filed under: SSH — Tags: — admin @ 7:00 am


Question:

Hi, I’m evaluating Chilkat C++ SSH Library for My VC 9.0 Projects.
I have a question: Your examples send only one command.
I want to send several commands without reconnect.
I experimented and found SendReqShell handles multiple commands execution, not SendReqExec.
Can I have a more detailed sample about this?

Answer:
You may call SendReqExec multiple times on the same open channel.

No X-UIDL header found

Filed under: pop3 — Tags: — admin @ 6:55 am

The following mailman methods use the X-UIDL email header as the means to identify the email to be downloaded or deleted from a POP3 server:

GetFullEmail
DeleteEmail
DeleteBundle

If no X-UIDL header is found within the email, then it is not possible to determine the sequence number of the email to be downloaded or deleted. (POP3 commands to fetch or delete an email require a sequence number. The sequence number is unique only to the POP3 session. The POP3 UIDL command is used to get a list of UIDLs and their corresponding sequence numbers — allowing a UIDL to be mapped to a sequence number. The methods listed above use the X-UIDL header field value to find the sequence number to be deleted.)