none
Installing multiple CAB files on Smartphone RRS feed

  • Question

  • Hi,

    I am using the sample application on the Channel9 page (http://channel9.msdn.com/wiki/mobiledeveloper/installingmultiplecabfiles) for creating a multiple CAB installable. I was able to build it and use it on PocketPC phones without any problem. But when I tried to build it for Smartphone, it gave me  a bunch of errors:
    • fatal error LNK1112: module machine type 'THUMB' conflicts with target machine type 'ARM'    coredll.lib    CESetup
    • Unable to find source file [...] CESetup.exe located in '%InstallDir%, the file may be absent or locked.    
    • The Windows CE CAB Wizard encountered an error.  See the output window for more information. 

    These is the change to the project I did to build for Smartphone:

    Properties -> Configuration Manager -> Active Solution Platform changed to Windows Mobile 6 Standard SDK (ARMV4I)

    Can anyone please let me know what steps I need to take to build and run this on Smartphone devices.

     

    Thanks,

    Friday, October 2, 2009 2:34 AM

Answers

  • I think you are copying the 3 cabs during installation and then the installer cab launches CESetupDriver.exe which in turn installs the 3 cabs.

    This is what you can do to identify the code which is failing for smartphone:

    1. Build the CESetupDriver.exe in debug mode.
    2. Manually copy the 3 cabs into the device at the expected location.
    3. Deploy and Debug CESetupDriver.exe and find out where its failing. Put the breakpoint at the begininning of _tmain function.

    Regards,
    Onkar


    http://www.42gears.com
    [SureLock Studio: Locks down Enterprise Windows Mobile devices]
    Saturday, October 3, 2009 1:20 AM
  • You might not be able to install your cabs because they are not signed. To test this, use device security manager in VS2008 (Tools/Device Security Manager) to set security of your emulator to Off temporarily.
    Alex Feinman. MVP .NET Compact Framework
    Saturday, October 3, 2009 6:31 AM

All replies

  • What is the OS version on the smartphone? Looks like its earlier than WM 5.0.

    For linker error, change the /machine:THUMB to /machine:ARM and rebuild again.

    Other installation errors might be due to problems in INF file or due the version of CABWIZ.exe.

    - Onkar


    http://www.42gears.com
    [SureLock Studio: Locks down Enterprise Windows Mobile devices]
    Friday, October 2, 2009 4:03 AM
  • What is the OS version on the smartphone? Looks like its earlier than WM 5.0.

    For linker error, change the /machine:THUMB to /machine:ARM and rebuild again.

    Other installation errors might be due to problems in INF file or due the version of CABWIZ.exe.

    - Onkar


    http://www.42gears.com
    [SureLock Studio: Locks down Enterprise Windows Mobile devices ]

    I am using the Windows Mobile 6 Standard emulator for testing. This project was previously built for Windows Mobile 5.0 PocketPC. So I tried to change the target platform to Windows Mobile 5 Smartphone. And when I built the project, it builds ok without any errors now. But when I tried to run the app on the emulator, the app did not work as it did on the Windows Mobile 6 Professional emulator. This app is supposed to copy three CAB files into a folder and automatically install them. However it just copies the files and exits.

    Any idea why this could be happening?

    I have attached the code below:
    // CESetupDriver.cpp : Defines the entry point for the console application.
    //
    
    #include "stdafx.h"
    #include <windows.h>
    #include <commctrl.h>
    
    #define ARRAYSIZE(x) sizeof(x)/sizeof(x[0])
    
    void WaitOnLoader ()
    {
        const TCHAR c_szWceLoadClass[] = TEXT("MSWCELOAD");  // Loader class name
        const int c_iLoadStartupWait   = 250;                // 250 ms pause
        const int c_iMaxInstallWait    = 600000;             // 10 minutes
    
        TCHAR  szClass[MAX_PATH];
        HWND   hwnd;
        DWORD  dwProcessID = 0;
        HANDLE hProcess = NULL;
        
    	// Give everything time to start
    	Sleep(c_iLoadStartupWait);
    
        hwnd = GetWindow(GetDesktopWindow(), GW_HWNDLAST);
    
        do
        {
            // Look for the loader and if it is running wait for it to finish 
            GetClassName(hwnd, szClass, ARRAYSIZE(szClass));
            if (!_tcscmp(szClass, c_szWceLoadClass))
            {
                GetWindowThreadProcessId(hwnd, &dwProcessID);
                hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessID);
                WaitForSingleObject(hProcess, c_iMaxInstallWait);
                CloseHandle(hProcess);
            }
    
            hwnd = GetWindow(hwnd, GW_HWNDPREV);
        } while (hwnd);
    }
    
    BOOL HostExec(LPCTSTR lpszFilePath, HANDLE *phProcess)
    {
        BOOL bRet;
        SHELLEXECUTEINFO sei = {0};
    
        sei.cbSize = sizeof(sei);
        sei.nShow = SW_SHOWNORMAL;
        sei.lpFile = lpszFilePath;
    
        bRet = ShellExecuteEx(&sei);
    
        if (bRet)
        {
            *phProcess = sei.hProcess;
        }
    
        return bRet;
    }
    
    BOOL ExecuteCabInstall(LPCTSTR tszCabDirectory, LPCTSTR tszCabName)
    {
    	BOOL result;
    	DWORD dwResult;
    
    	TCHAR tszCabPathName[MAX_PATH];
    	StringCchPrintf(tszCabPathName, MAX_PATH, _T("%s\\%s"), tszCabDirectory, tszCabName);
    
    	SHELLEXECUTEINFO sei = {0};
    
        sei.cbSize = sizeof(sei);
        sei.nShow = SW_SHOWNORMAL;
        sei.lpFile = tszCabPathName;
    
        result = ShellExecuteEx(&sei);
    
    	if (result)
    	{
    		WaitOnLoader();
    	}
    
    	return TRUE;
    }
    int _tmain(int argc, _TCHAR* argv[])
    {
    	WaitOnLoader();
    
    	WIN32_FIND_DATA FindFileData ;
    	HANDLE hFind = INVALID_HANDLE_VALUE;
    	TCHAR foo[MAX_PATH];
    	BOOL bSuccess = true;
    
    	TCHAR tszPath[MAX_PATH];
    	StringCchPrintf(tszPath, MAX_PATH, _T("%s\\ApplicationCabs"), argv[1]);
    
    	TCHAR tszCabWildcard[MAX_PATH];
    	StringCchPrintf(tszCabWildcard, MAX_PATH, _T("%s\\*.*"), tszPath);
    
    	hFind = FindFirstFile(tszCabWildcard, &FindFileData);
    	while(bSuccess && hFind != INVALID_HANDLE_VALUE)
    	{
    		ExecuteCabInstall(tszPath, FindFileData.cFileName);
    		bSuccess = FindNextFile(hFind, &FindFileData);
    	}
    	FindClose(hFind);
    
    	return 0;
    }
    
    
    // CESetup.cpp : Defines the entry point for the DLL application.
    //
    
    #include "stdafx.h"
    #include "CESetup.h"
    #include <windows.h>
    #include <commctrl.h>
    
    BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
    					 )
    {
    	switch (ul_reason_for_call)
    	{
    	case DLL_PROCESS_ATTACH:
    	case DLL_THREAD_ATTACH:
    	case DLL_THREAD_DETACH:
    	case DLL_PROCESS_DETACH:
    		break;
    	}
        return TRUE;
    }
    
    codeINSTALL_INIT Install_Init(
        HWND        hwndParent,
        BOOL        fFirstCall,     // is this the first time this function is being called?
        BOOL        fPreviouslyInstalled,
        LPCTSTR     pszInstallDir
    )
    {
    	return codeINSTALL_INIT_CONTINUE ;
    }
    
    codeINSTALL_EXIT Install_Exit(
        HWND    hwndParent,
        LPCTSTR pszInstallDir,      // final install directory
        WORD    cFailedDirs,
        WORD    cFailedFiles,
        WORD    cFailedRegKeys,
        WORD    cFailedRegVals,
        WORD    cFailedShortcuts
    )
    {
    	SHELLEXECUTEINFO sei = {0};
    	// Need three level of quotes when passing as argument to ShellExecuteEx
    	TCHAR tszParameters[MAX_PATH];
    	StringCchPrintf(tszParameters, MAX_PATH, _T("\"\"\"%s\"\"\""), pszInstallDir);
    
    	TCHAR tszSetupDriverPathName[MAX_PATH];
    	StringCchPrintf(tszSetupDriverPathName, MAX_PATH, _T("%s\\CESetupDriver.exe"), pszInstallDir);
    
        sei.cbSize = sizeof(sei);
        sei.nShow = SW_SHOWNORMAL;
        sei.lpFile = tszSetupDriverPathName;
    	sei.lpParameters = tszParameters;
    
        BOOL result = ShellExecuteEx(&sei);
    
    	return codeINSTALL_EXIT_DONE;
    }
    
    codeUNINSTALL_INIT Uninstall_Init(
        HWND        hwndParent,
        LPCTSTR     pszInstallDir
    )
    {
    	return codeUNINSTALL_INIT_CONTINUE;
    }
    
    codeUNINSTALL_EXIT Uninstall_Exit(
        HWND    hwndParent
    )
    {
    	return codeUNINSTALL_EXIT_DONE;
    }
    
    

    Friday, October 2, 2009 9:51 PM
  • I think you are copying the 3 cabs during installation and then the installer cab launches CESetupDriver.exe which in turn installs the 3 cabs.

    This is what you can do to identify the code which is failing for smartphone:

    1. Build the CESetupDriver.exe in debug mode.
    2. Manually copy the 3 cabs into the device at the expected location.
    3. Deploy and Debug CESetupDriver.exe and find out where its failing. Put the breakpoint at the begininning of _tmain function.

    Regards,
    Onkar


    http://www.42gears.com
    [SureLock Studio: Locks down Enterprise Windows Mobile devices]
    Saturday, October 3, 2009 1:20 AM
  • You might not be able to install your cabs because they are not signed. To test this, use device security manager in VS2008 (Tools/Device Security Manager) to set security of your emulator to Off temporarily.
    Alex Feinman. MVP .NET Compact Framework
    Saturday, October 3, 2009 6:31 AM