Запуск программы завершается с ошибкой с кодом 1

Я сделал приложение и dll, которые работают так: мне нужно зарегистрировать dll. После регистрации dll, если я щелкну правой кнопкой мыши файл .exe, появится всплывающее меню, и я вставил в это меню одну строку («Запустить MyApp»), и если я щелкну там, он должен запустить MyApp. MyApp имеет один параметр, который представляет собой полный путь к выбранному файлу .exe. После запуска MyApp с этим путем он должен создать процесс с CreateProcessWithLogonW(). Это приложение считывает имя пользователя, пароль и домен из файла .ini. Моя проблема в том, что после запуска MyApp всегда происходит сбой, потому что он не может найти файл ini. Код ошибки: 1 (неверная функция). Если я запускаю MyApp вручную, он работает нормально.

Кто-нибудь знает, почему это так, и как я могу решить эту проблему?

Заранее спасибо!

кампи

Обновление1:

Вот код, который читает из ini-файла.

int main ( int argc, char *argv[] )  
{    
  int i, slash = 0, j;  
  char application[size];  
  wchar_t wuser[65], wdomain[33], wpass[129];  

  memset( user, 0, sizeof ( user ) );
  memset( password, 0, sizeof ( password ) );
  memset( domain, 0, sizeof ( domain ) );

  file_exists( "RunAs.ini" );
  readfile( "RunAs.ini" );  
  ....
  ....
  ....
}  
void file_exists( const char * filename )  
{  
  if (FILE * file = fopen(filename, "r"))  
  {  
      fclose(file);  
  }  
  else   
  {  
      printf("\nCan't find %s!\n",filename);  
      getch();  
      exit(1);  
  }   
}//file_exists    

void readfile( char * filename )
{  
     FILE *inifile;  
    char tmp[256], buf[256], what[128];  
    int i, j;  

    inifile = fopen( "RunAs.ini", "r" );  

    while ( fgets(tmp, sizeof tmp, inifile) != NULL )  
    {     
        if ( tmp[ strlen(tmp) - 1 ] == '\n' )  
         {  
            tmp[ strlen(tmp) - 1 ] = '\0';  
        }//if  

        memset ( buf, 0, sizeof( buf ) );  

        for ( i = 0; tmp[i]!= '='; i++ )  
         {  
             buf[i] = tmp[i];  
         }  
        buf[i] = '\0';  
        i++;  

    //  memset ( what, 0, sizeof( what ) );  
        SecureZeroMemory( what, sizeof(what) * 128 );  

        for ( j = 0; i != strlen(tmp); i++ )   
         {  
             what[j] = tmp[i];  
            j++;  
         }  
        what[j] = '\0';  
        upcase( buf );  
        removespace( what );  

        if ( strcmp( buf, "USERNAME" ) == 0 )  
        {  
            strcpy( user, what );  
        }  
        if ( strcmp( buf, "PASSWORD" ) == 0 )  
        {  
            strcpy( password, what );  
        }  
        if ( strcmp( buf, "DOMAIN" ) == 0 )  
        {  
            strcpy( domain, what );  
        }  
    }//while  
    fclose (inifile);  

}//readfile  

person kampi    schedule 29.12.2009    source источник
comment
Вам нужно показать свой код, который открывает/читает из ini-файла. Без него вы не предоставили никакой информации, которая могла бы помочь в поиске проблемы.   -  person Ken White    schedule 29.12.2009
comment
@Ken: Код опубликован :) Но я должен сказать, что если я запускаю приложение напрямую, например, myapp.exe c:\totalcmd\totalcmd.exe, оно работает нормально. Оно не работает только тогда, когда я запускаю его из контекстное меню.   -  person kampi    schedule 30.12.2009


Ответы (5)


Как уже говорили другие, ваша проблема здесь:

file_exists( "RunAs.ini" );
readfile( "RunAs.ini" );  

Ни один из вызовов функций не предоставляет путь. Вы ожидаете, что текущим рабочим каталогом будет папка, в которой находится ваше приложение, но это не обязательно (на самом деле вы никогда не должны предполагать, что это так). Контекстное меню не устанавливает рабочий каталог в первую очередь.

Безопаснее всего получить путь к вашей папке, используя путь, указанный в argv[] (0-й элемент — это полный путь и имя самого приложения, и вы можете извлечь путь из него). После этого вы будете точно знать, где находится файл, и сможете добавить имя файла ini к этому пути.

person Ken White    schedule 29.12.2009
comment
@Кен: Ты прав! Это была ошибка. Мне нужен был путь извлечения, а не только имя файла. Однако это было в том же каталоге. Я не совсем понимаю, почему так, потому что до этого я использовал только вышеуказанную форму, и она всегда работала отлично. Большое тебе спасибо! - person kampi; 30.12.2009
comment
Нет никакой гарантии, что первый элемент argv является полным путем к чему-либо вообще. Поскольку мы знаем, что это только для Windows, вызовите GetModuleFileName, как рекомендует Microsoft: msdn.microsoft .com/en-us/library/88w63h9k.aspx - person Rob Kennedy; 30.12.2009
comment
@Rob: Ну, какой компилятор в +Windows+ не возвращает полный путь к приложению в первом элементе argv (для дальнейшего использования). Я также предположил, что, поскольку OP не использовал WritePrivateProfileString или какие-либо другие функции API, была причина не рекомендовать GetModuleFileName. - person Ken White; 30.12.2009

Я подозреваю, что вы ищете файл ini не в той папке. Я бы попробовал изменить имя файла ini в приложении на полное имя файла ini. (т.е. с "foo.ini" на "c:\\temp\\foo.ini")

(Обратите внимание, что я удвоил обратную косую черту, потому что без этого одиночная обратная косая черта может изменить значение следующего символа или обратная косая черта может быть проигнорирована.)

person David Harris    schedule 29.12.2009
comment
@David: я пробовал оба способа, Runas.ini и d:\kampi\runas.ini, но ни один из них не работал. Но если я запускаю этот exe вручную, то он работает нормально, и я понятия не имею, почему это так. - person kampi; 30.12.2009
comment
@Kampi: вы пробовали d:\\kampi\\runas.ini или если вы находитесь в С# (я не знаю, работает ли это в С++) @d:\kampi\runas.ini - person Scott Chamberlain; 30.12.2009
comment
@kampi: обратите внимание на мое последнее предложение, где указано, что вы должны удвоить обратную косую черту. Имя файла должно выглядеть так: d:\\kampi\\runas.ini. В противном случае первый символ \ может быть проигнорирован, а второй и r заменены на возврат каретки (0x0d) (я отредактировал свой исходный пост, чтобы сделать это более понятным). - person David Harris; 30.12.2009
comment
@Dave: я написал двойную обратную косую черту в коде, я забыл только здесь удвоить их - person kampi; 30.12.2009

Вы указываете абсолютный путь или относительный путь? Ваш CWD может отличаться при запуске.

person Noctis Skytower    schedule 29.12.2009

При непосредственном запуске приложения текущим путем является путь, по которому установлено ваше приложение.

Однако при запуске из этого контекстного меню текущий путь — это что-то другое.

Есть два способа решить эту проблему. Во-первых, не используйте ini-файл. Вместо этого сохраните свою информацию в реестре. Таким образом, вам все равно, откуда запускается программа.

В качестве альтернативы вашему приложению придется найти каталог, в котором оно было фактически установлено, а затем загрузить оттуда файл ini.

Очевидно, что первый выбор — самый простой путь.

person NotMe    schedule 29.12.2009

Вы проверили, действителен ли путь к файлу для ini?

person Ashish    schedule 29.12.2009
comment
@Mac: Да, я проверил и попытался указать абсолютный и реальный путь. - person kampi; 30.12.2009