C ++ Автообновление программы - PullRequest
0 голосов
/ 05 ноября 2010

У меня проблемы с моей программой автообновления

Предполагается загрузить и сохранить обновление с веб-сайта, но проблема в этом (и я уверен, что это случается уже многоне может сформулировать ключевые слова, которые позволят мне получить ответ в Google), он сохраняет полученные данные .exe не так, как предполагалось.Это сохраняет байты в ACSI ... позвольте мне проиллюстрировать, что:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   4D 5A 90 00 03 00 00 00  04 00 00 00 FF FF 00 00   MZ          ÿÿ  
00000010   B8 00 00 00 00 00 00 00  40 00 00 00 00 00 00 00   ¸       @       
00000020   00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00                   
00000030   00 00 00 00 00 00 00 00  00 00 00 00 B0 00 00 00               °   

Эти данные (которые являются правильными данными) выглядит в новой программе следующим образом:

Offset      0  1  2  3  4  5  6  7   8  9  A  B  C  D  E  F

00000000   0D 0A 34 44 35 41 39 30  30 30 30 33 30 30 30 30     4D5A9000030000
00000010   30 30 30 34 30 30 30 30  30 30 46 46 46 46 30 30   0004000000FFFF00
00000020   30 30 42 38 30 30 30 30  30 30 30 30 30 30 30 30   00B8000000000000
00000030   30 30 34 30 30 30 30 30  30 30 30 30 30 30 30 30   0040000000000000

Как вы можете видеть, он записывает кодовые байты как значения ascii ... Это код, который я использую

Принимающая часть:

char   szRecvBuff[10000] = "" ;
string szRecvHolder = "" ;      
int    iLastCharacter = 0;

    recv(Socket, szRecvBuff, sizeof(szRecvBuff), 0);

    szRecvHolder = szRecvBuff;

    iLastCharacter = szRecvHolder.find_last_of("\n");
    if(iLastCharacter < szRecvHolder.size() && iLastCharacter > 0 ){
    szRecvHolder.erase(iLastCharacter);
    }
  return szRecvHolder;
}
...
...
{
...
...
Recv();
string Edat = Recv();
std::ofstream put("Eprog.exe", ios::hex );
put <<  Edat.c_str();
put.close();

Кто-нибудь знает, как это сделать,Я пытался использовать Google, но не смог сформулировать вопрос, который дал бы мне правильные результаты

Ответы [ 3 ]

1 голос
/ 06 ноября 2010

Убедитесь, что вы открываете выходной файл в двоичном режиме:

std::ofstream put("Eprog.exe", ios::binary | ios::hex );
0 голосов
/ 06 ноября 2010

Я решил проблему, вместо того чтобы пытаться заставить компилятор интерпретировать значения как шестнадцатеричные, я просто создал таблицу поиска, содержащую все 256 возможных байтов.

unsigned char Table[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F, 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F, 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF, 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF, 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF, 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF, 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF };



int GetIndexNumber(string str){
unsigned long rint = NULL;
unsigned long size = str.size() - 2;
unsigned long fi[sizeof(str)];
unsigned long mul;

for( int i = 0; i != 2; i++){
    if( str.at(i+2) == '0' ) fi[i] = 0;
    if( str.at(i+2) == '1' ) fi[i] = 1;
    if( str.at(i+2) == '2' ) fi[i] = 2;
    if( str.at(i+2) == '3' ) fi[i] = 3;
    if( str.at(i+2) == '4' ) fi[i] = 4;
    if( str.at(i+2) == '5' ) fi[i] = 5;
    if( str.at(i+2) == '6' ) fi[i] = 6;
    if( str.at(i+2) == '7' ) fi[i] = 7;
    if( str.at(i+2) == '8' ) fi[i] = 8;
    if( str.at(i+2) == '9' ) fi[i] = 9;
    if( str.at(i+2) == 'A' ) fi[i] = 10;
    if( str.at(i+2) == 'B' ) fi[i] = 11;
    if( str.at(i+2) == 'C' ) fi[i] = 12;
    if( str.at(i+2) == 'D' ) fi[i] = 13;
    if( str.at(i+2) == 'E' ) fi[i] = 14;
    if( str.at(i+2) == 'F' ) fi[i] = 15;
}

for(int i = 0; i != 2 ; i++){
    mul = (1 * pow(16, (double)size-1));
    size--;
    rint += ( mul * fi[i]);
}
return rint;
}

Recv();
string Edat = Recv();
Edat += Recv();
cout<<Edat.c_str()<<endl<<endl;

unsigned char buffer[10000] = "";

for( int i = 0; i <= Edat.size(); i++){
    int PlaceHolder = Edat.find_first_of("0x");
    if(PlaceHolder <= Edat.size() && PlaceHolder > 0){ 
        string tmpstr = Edat.substr(PlaceHolder, 4);
        int TableNumber = GetIndexNumber(tmpstr);
         buffer[i] = Table[TableNumber];
    }
    Edat.replace(PlaceHolder, 4, "");
}

std::ofstream put("Eprog.exe", ios::binary);
put.write((char *)buffer, sizeof(buffer));
put.close(); 

return 0; 
}
0 голосов
/ 06 ноября 2010

Большая проблема, которую я вижу с вашим кодом, состоит в том, что когда вы звоните на Edat.c_str(), вы, вероятно, даете const char* потоку.Этот указатель не имеет информации о том, сколько нужно записать в поток, поэтому он должен по договоренности остановиться на первом '\0'.

Вместо этого следует использовать вызов write() исырой символьный буфер.

...