应用程序及配置文件的生产自动拷贝

 2018-11-12 15:54:08     作者:刘乾坤    
文章标签:C/C++

  为了帮助用户提高生产测试效率,我们提供了代为客户拷贝应用程序的服务,在主板出厂之前我们会将用户提交的所有程序和文件拷贝到用户指定的系统目录中,用户拿到主板后可直接装机测试,大大节省了生产测试时间。客户也可参考此方法,在自己的整机生产中实现应用程序及配置文件的自动拷贝。本文以下介绍在CE平台实现应用程序及配置文件自动拷贝的具体步骤。


  英创主板处于调试模式启动时,会查询系统的usbdisk根目录下是否有名为autotest.txt的配置文件,如果配置文件存在则会执行文件中指定的exe程序,程序的拷贝正是利用系统的这一功能自动实现的。


  实现程序的自动拷贝需要以下几个步骤:


  1、编写autotest.txt配置文件

  配置文件中需要指定要启动的exe完整路径,同时可配置系统网口1的网络参数,下面是示例配置。


[LOCAL_MACHINE]
DefaultGateway="192.168.201.19"
IPAddress="192.168.201.220"
SubnetMask="255.255.255.0"
 
[USER_EXE]
Name="\usbdisk\autocfg.exe"
Parameters=""
 
[SYSTEM]
Store="25"


  2、编写自动配置程序

  配置程序autocft.exe一般需要实现将应用程序拷贝到主板指定目录的功能,同时也可完成用户自定义的一些配置功能,比如增加特定注册表、烧写开机画面等。下面是一些示例代码可供用户参考。


  AutoCopy函数实现将当前执行的配置程序所在目录的全部文件拷贝到系统的nandflash目录中。


DWORD AutoCopy( )
{
       DWORD dwResult;
       TCHAR szCurrentDir[MAX_PATH];
       TCHAR szLocalFile[MAX_PATH];
       TCHAR szNewFile[MAX_PATH];
       TCHAR szDisFolder[MAX_PATH];
       CHAR  localFile[MAX_PATH];
       CHAR  newFile[MAX_PATH];
       int     i1, diskType;
 
       dwResult = GetModuleFileName( NULL,szCurrentDir, sizeof( szCurrentDir ) );
       if( 0 == dwResult )
       {
              printf("GetModuleFileName failure!\r\n" );             
              return -1;
       }     
       TCHAR *pch = _tcsrchr( szCurrentDir, '\\' );
       *(pch+1) = '\0';  
       _tcslwr(szCurrentDir);      
       pch = _tcsstr( szCurrentDir, _T("usb") );
       if(  NULL != pch )
       {
              _tcscpy( szLocalFile, szCurrentDir );
              _tcscat( szLocalFile, _T("*.*"));
 
              diskType = 1;   
              GetFolderName(diskType, szDisFolder);
 
              HANDLE hFind;
              WIN32_FIND_DATA FindFileData;
              BOOL     BFind;
              hFind = FindFirstFile( szLocalFile, &FindFileData);
              if(hFind != INVALID_HANDLE_VALUE)
              {
                     BFind = TRUE;
                     while( BFind )
                     {
                            if( FindFileData.dwFileAttributes != FILE_ATTRIBUTE_DIRECTORY )
                            {
                                   _tcscpy( szLocalFile, szCurrentDir );
                                   _tcscat( szLocalFile, FindFileData.cFileName );
                                   _stprintf(szNewFile, _T("\\%s\\"), szDisFolder);
                                   _tcscat( szNewFile, FindFileData.cFileName );
                                   dwResult = CopyFile( szLocalFile, szNewFile, FALSE );
 
                                   memset( localFile, 0, sizeof(localFile));
                                   i1 = wcslen( szLocalFile );
                                   wcstombs( localFile, szLocalFile, i1 );
 
                                   memset( newFile, 0, sizeof(newFile));
                                   i1 = wcslen( szNewFile );
                                   wcstombs( newFile, szNewFile, i1 );
                                   if( dwResult == 0 )
                                   {
                                          printf("Copy %s to %s failure!\r\n", localFile, newFile );                                           
             return -1;
                                   }
                                   else
                                   {
                                          printf("Copy %s to %s successful!\r\n", localFile, newFile );
                                   }
                            }
                            BFind = FindNextFile( hFind, &FindFileData );
                     }
              }
              FindClose( hFind );
       }
       return 0;
}
 
// Get "Folder" name from register.
//    type = 0:  SDMemory
//    type = 1:  Nand
//    type = 2:  USB
//      type = 3:  EMMC
//
void GetFolderName( int type, LPWSTR szName )
{  
       HKEY     hKey = NULL;       
       DWORD       dwType=REG_SZ;
       DWORD       size=100;
       DWORD       ret;
       TCHAR  szFolderPath[80];
 
       switch( type )
       {
       case 0:
              _tcscpy( szFolderPath, REG_SDFOLDER_PATH );
              break;
       case 1:
              _tcscpy( szFolderPath, REG_NANDFOLDER_PATH );
              break;
       case 2:
              _tcscpy( szFolderPath, REG_USBFOLDER_PATH );
              break;
       case 3:
              _tcscpy( szFolderPath, REG_EMMC_PATH );
              break;
       default:
              return;
       }
 
 
       //get the folder Name from registry in case BSP is using non-default name
       if (ERROR_SUCCESS == RegCreateKeyEx(HKEY_LOCAL_MACHINE, (LPWSTR)szFolderPath,
          0, NULL, REG_OPTION_NON_VOLATILE, 0, NULL, &hKey, NULL))
       {         
              ret=RegQueryValueEx(hKey, L"Folder", 0, &dwType, (BYTE*)szName, &size);
              if (ret!=ERROR_SUCCESS)
                     RETAILMSG(1,(L"RegQueryValueEx returned error %d dwType=%d size=%dbufSz=%d\r\n", ret,dwType,size,sizeof(szName)));
       }
 
       if( hKey!=NULL )
              RegCloseKey(hKey);
 
       return;
}


  英创主板支持开机画面在线更新,《WinCE工控主板在线更新开机画面(2017新版)》中提到的lu程序,用户也可以在配置程序中直接调用实现开机画面的自动更新,下面是利用lu更新U盘目录下usersplash800480.bmp图片的示例代码。


PROCESS_INFORMATION processInfo;
TCHAR szProgram[] = _T("lu.exe");
TCHAR szCmdLine[100] = _T("usbdisk\\usersplash800480.bmp");
 
BOOL result = CreateProcess( szProgram, szCmdLine,NULL, NULL, FALSE, CREATE_NEW_CONSOLE, NULL, NULL, NULL, &processInfo );
if( result == 0 )
{
     //执行失败...
}


  3、将autotest.txt放在U盘根目录,同时将配置程序autocft.exe和需要拷贝到主板上的应用程序及文件放在U盘指定目录中。


  4、将U盘连接到英创主板,主板在调试模式启动后会自动执行用户指定的配置程序,完成系统配置工作。


  系统默认只会执行一次查询autotest.txt启动配置程序的过程,如果希望这个功能总是有效,可在配置程序开始处增加一个清除注册表标志的工作,当系统注册表项HKEY_LOCAL_MACHINE\Emtronix或HKEY_LOCAL_MACHINE\Wstartup下的Count等于0时,系统在调试模式下就会查询U盘中的autotest.txt配置文件。下面是count清零代码。


HKEY     hKey;
DWORD       dwVal, dwRet;
DWORD       dwType = REG_DWORD;
DWORD       dwBufLen = sizeof(DWORD);
if((dwRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Emtronix"), 0, 0, &hKey))  != ERROR_SUCCESS)
{
       dwRet = RegOpenKeyEx( HKEY_LOCAL_MACHINE, _T("Wstartup"), 0, 0, &hKey);
}
if(dwRet == ERROR_SUCCESS)
{
       dwVal = 0;
       RegSetValueEx(hKey, _T("Count"), 0, dwType, (BYTE*)&dwVal, dwBufLen);
       RegCloseKey(hKey);         // close registry
}
文章标签:C/C++