• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 300
  • Last Modified:

Arguments from the command line

I used argv[n] to get arguments are passed to the program from the command line. But I found if there were too many arguments, it only returned a ERROR box.
   (I used the code below in OnInitDialog() to get all files droped on my app, and put them into listbox.)

(  int n;
   for (n=1;n<__argc;n++){
       m_ListBox.InsertString(0,argv[n]);
   }
)
Why?
0
xiaoma
Asked:
xiaoma
  • 5
  • 3
  • 2
  • +4
1 Solution
 
NT_ProgrammerCommented:
Try either using AddString or m_ListBox.InsertString( -1, argv[ n ] );

AddString will cause them to be sorted.  If you are going to call InsertString you need to pass a different index each time or -1 to indicate to add to the end.
0
 
xiaomaAuthor Commented:
I try it, but it's no use.
I think the Key is argv[n].
0
 
GlennDeanCommented:
Does your code ever work?  It seems like you're mixing code from a console app and an MFC app?
0
Never miss a deadline with monday.com

The revolutionary project management tool is here!   Plan visually with a single glance and make sure your projects get done.

 
mikeblasCommented:
What's an "ERROR box"? What, specifically, is the error you're receiving?

How many files is too many files?

..B ekiM
0
 
chensuCommented:
In addition to mikeblas' questions, why don't you use __argv[n] rather than argv[n]?
0
 
ZoppoCommented:
Hi xiaoma,

I think the problem is that a command line length is limited (255 characters in NT excluding the application's path name). I unfortunately do not know how to solve this ...

ZOPPO
0
 
mikeblasCommented:
Zoppo> I think the problem is that a command line length is limited

No.

The command line that you can input from the command prompt is limited, yes. But the command line passed from one program to another (in this case, from the shell to the program being started) is not limited.

..B ekiM
0
 
Brain2000Commented:
Check to see if it's returning an error.

(  int n,x;
   for (n=1;n<__argc;n++){
       x=m_ListBox.InsertString(0,argv[n]);
       if(x==LB_ERR) ::MessageBox(NULL,"OH MY GOD!","CRAP",MB_OK);

       if(x==LB_ERRSPACE) ::MessageBox(NULL,"THEY KILLED KENNY!","DOUBLE CRAP",MB_OK);

   }
)
0
 
xiaomaAuthor Commented:
In fact, I want my app to capture all of the files dropped on it, and put them into a ListBox.
   
  1. The ERROR box said "Visit to specific equipment, directory or file is refused.
  2. As my statistics, if the length of command line(all names of files dropped) is up to 7XX charaters, the error returned, despite of the number of arguments(the number of files dropped).
0
 
ZoppoCommented:
to mikeblas: I do not agree. Compile the following simple app, select many files within explorer and drop them on the compiled exe in explorer:

int main(int /*argn*/, char* /*argv*/[])
{
 printf( "Number of args : %i\n", __argc );
 for ( int i = 0; i < __argc; i++ )
 {
  printf( "Arg #%i : '%s'\n", i + 1, __argv[i] );
 }
 printf( "'%s'\n", GetCommandLine() );
 getch();
}

You'll get some output similar to this (I've dropped 20 .cur files on it):

------------------------------------------------------------------------------------------------
Number of args : 11
Arg #1 : 'C:\boolt.exe'
Arg #2 : 'C:\WINNT\Cursors\3dgno.cur'
Arg #3 : 'C:\WINNT\Cursors\3dgmove.cur'
Arg #4 : 'C:\WINNT\Cursors\3dgnesw.cur'
Arg #5 : 'C:\WINNT\Cursors\3dgarro.cur'
Arg #6 : 'C:\WINNT\Cursors\3dgns.cur'
Arg #7 : 'C:\WINNT\Cursors\3dgnwse.cur'
Arg #8 : 'C:\WINNT\Cursors\3dgwe.cur'
Arg #9 : 'C:\WINNT\Cursors\3dsmove.cur'
Arg #10 : 'C:\WINNT\Cursors\3dsns.cur'
Arg #11 : 'C:\WINN?'
'"C:\boolt.exe" C:\WINNT\Cursors\3dgno.cur C:\WINNT\Cursors\3dgmove.cur C:\WINNT\Cursors\3dgnesw.cur C:\WINNT\Cursors\3dgarro.cu
r C:\WINNT\Cursors\3dgns.cur C:\WINNT\Cursors\3dgnwse.cur C:\WINNT\Cursors\3dgwe.cur C:\WINNT\Cursors\3dsmove.cur C:\WINNT\Curso
rs\3dsns.cur C:\WINN?'
------------------------------------------------------------------------------------------------

why is this when there's no limit ???

ZOPPO
0
 
mikeblasCommented:
> why is this when there's no limit ???

I'm afraid I can't repro that behaviour. I modified your code, slightly, to count the number of characters in the arguments. Then, I dragged a handful of files from the CURSORS directory:

0: "C:\line.exe"
1: "C:\WINNT\CURSORS\handns.ani", nTotLen = 27
2: "C:\WINNT\CURSORS\drum.ani", nTotLen = 52
3: "C:\WINNT\CURSORS\fillitup.ani", nTotLen = 81
4: "C:\WINNT\CURSORS\globe.ani", nTotLen = 107
5: "C:\WINNT\CURSORS\hand.ani", nTotLen = 132
6: "C:\WINNT\CURSORS\handapst.ani", nTotLen = 161
7: "C:\WINNT\CURSORS\dinosau2.ani", nTotLen = 190
8: "C:\WINNT\CURSORS\handnwse.ani", nTotLen = 219
9: "C:\WINNT\CURSORS\handwait.ani", nTotLen = 248
10: "C:\WINNT\CURSORS\handwe.ani", nTotLen = 275
11: "C:\WINNT\CURSORS\hourgla3.ani", nTotLen = 304
12: "C:\WINNT\CURSORS\hourglas.ani", nTotLen = 333
13: "C:\WINNT\CURSORS\metronom.ani", nTotLen = 362
14: "C:\WINNT\CURSORS\piano.ani", nTotLen = 388
15: "C:\WINNT\CURSORS\rainbow.ani", nTotLen = 416

Clearly, 416 is larger than the 256 byte limit you assert.

If I drag lots of files, I get an error like xaioma reports: "Access to the specified device, path, or file is denied". Emperically, it seems like the shell is enforcing an arbitrary limit at 512 bytes.

But, there's certainly no limit inherent in the operating system. You can use this application to spawn a copy of your test app and pass it more than 10000 bytes of command-line data:

-- begin file runline.cpp --

#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>

#pragma comment(lib, "user32.lib")

void main()
{
   char sz[10240];
   sz[0] = 0;

   char szTemp[20];
   int nTotal = 0;
   for (int n = 1; nTotal < 10200; n++)
   {
      nTotal += wsprintf(szTemp, "Argument#%d ", n);
      strcat(sz, szTemp);
   }

   STARTUPINFO startupInfo;
   PROCESS_INFORMATION procInfo;

   memset(&startupInfo, 0, sizeof(startupInfo));
   startupInfo.cb = sizeof(startupInfo);
   startupInfo.dwFlags = STARTF_USESHOWWINDOW;
   startupInfo.wShowWindow = SW_RESTORE;

   BOOL bWorked = CreateProcess("D:\\line.exe",
      sz,
      NULL, NULL,
      FALSE,
      0,
      NULL,
      NULL,
      &startupInfo,
      &procInfo);


   if (!bWorked)
   {
      printf("Failed!  %d\n", GetLastError());
   }

   getch();
}

-- end file runline.cpp --

Like I said, the shell may enforce a limit--but that limitation is strictly in the shell. It's not a limitation on the command line.

..B ekiM

0
 
ZoppoCommented:
Hmmm... somehow strange I think ... I even get the cut command line with none console application when calling GetCommandLine().
0
 
mikeblasCommented:
Here's the answer:

1) There's no limit to what can appear on the command line of an application. You can pass as much as you want via CreateProcess().

2) I've confirmed that simple drag-and-drop in the shell is limited to a static buffer; depending on the version of the shell, that might be as little as 256 bytes.

3) The way to work around this problem is to register your app as a drag-and-drop handler with the shell.

..B ekiM
0
 
Brain2000Commented:
How do you register your app as a drag-and-drop handler?  Registry entry?  Flag in the .EXE file set during compile?
0
 
mikeblasCommented:
> Registry entry?  

Yes. It is described in detail in the "Shell Extensions" section of MSDN.

..B ekiM
0

Featured Post

The new generation of project management tools

With monday.com’s project management tool, you can see what everyone on your team is working in a single glance. Its intuitive dashboards are customizable, so you can create systems that work for you.

  • 5
  • 3
  • 2
  • +4
Tackle projects and never again get stuck behind a technical roadblock.
Join Now