我创建了一个C程序,它将运行一些system()
命令并将输出保存到C驱动器的特定文件夹中的.txt
文件(程序将在具有启动权限的域客户端上运行) ,我将从那里过滤数据并在输出控制台屏幕上显示它。
一切都运行良好,但我无法为那些在其他驱动器中安装了操作系统的PC(例如 D:
,E:
等)设计它,因为它们在C:
驱动器中不会包含此特定文件夹。由于组策略,我无法在其他任何地方写入临时.txt
文件。
有没有方法可以将这些数据直接传输到任何数组变量中?我经历了popen()
函数,但它需要定义一个非常大的不可预测大小的数组(因为system()
命令的输出可能非常大)。例如,将HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\uninstall
的注册表项导出到.txt
文件中。它的大小可能高达50KB或更大。
reg export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\uninstall C:\\..(somewhere)....\\reg_output.txt
还有一些类似的命令具有大输出。我还不知道Win API编程,因此我使用的是系统命令。写作.txt
可以有一个简单的替代方法吗?
@Megharaj! 正如您使用
char line[100];
fp = popen("ifconfig eth0", "r");
fgets(line, 100, fp);
我必须使用
char reg_output[100000];
fp=popen("reg export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\uninstall ????","r");
fgets(line,100000,fp);
我在哪里导出注册表值? (由于用于导出它的DOS命令需要将其写入文件),与我正在使用的以下代码相比。
分配100000的空间不确定它是否容易出错。并且分配太高的值也会影响启动时的内存(我不确定但是这样猜测)。
使用文件处理时,我将其作为:
char line[5000]; FILE* fp_reg; int ch,n=0;
system("reg export HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\uninstall c:\\registries.txt");
fp_reg=fopen("c:\\registries.txt","r");
while((ch=fgetc(fp_reg))!=EOF)
{
if(isalnum(ch) || ch=='\n') //allow only alpha numeric & '\n' to pass to array
{ line[n]=ch;
if(ch=='\n')
{ filter_for_software(line,n); //Send the array for filtering function
n=0; // Reset the array 'line'
}
n++;
}
}
(我没有从源代码复制代码,因为我坐在不同的PC上。但代码几乎与此类似。如果您复制此代码并运行,可能会出现一些错误。) 这样,我从文件中取出每一行并发送它以进行过滤以获得“已安装软件的名称”。我怎么用'popen()'来做,这样我就可以拿起一条线并将它扔到一个函数上。 Plz也为此编写了一些代码。
答案 0 :(得分:1)
在linux中使用系统命令中的值我使用popen,我只是给出了一段时间我写的代码示例,通过系统命令“ifconfig eth0”获取pc的ip地址字符串/文件。见例子
void get_my_ip(char *ip_mac_address)
{
FILE *fp,*output;
char *start=NULL;
char *end=NULL;
char line[100];
output=fopen("my_ip_address.txt", "w");
if(output == NULL) {
printf("error creating outputfile\n");
return -1;
}
printf("program to self query the ip address\n");
fp = popen("ifconfig eth0", "r");
fgets(line, 100, fp);
start=strstr(line, CHECK_STRING_MAC);
start = start + 7;
fwrite(start, 1, 17, output); start = NULL;
fgets(line, 100, fp);
start=strstr(line, CHECK_STRING_IP);
start = start + 10;
fwrite(start, 1, 14, output);
fclose(output);
pclose(fp);
if( access("my_ip_address.txt", F_OK ) != -1 ) {
printf("found file having ip address\n");
output=fopen("my_ip_address.txt", "r");
fgets(ip_mac_address, 32, output);
}
else
printf("unabe to find file with ip address\n");
fclose(output);
printf("my ip and mac address adress is %s \n",ip_mac_address);
}
答案 1 :(得分:1)
如果要将输出存储在数组中,则必须分配适当大小的数组。没有办法解决这个问题。
但如果使用popen
,则无需执行此操作。你得到一个FILE *
句柄,只需要读取小部分的输出并随时处理它。
从那里我将过滤数据并在输出控制台屏幕上显示它。
你是怎么做到的?用shell还是用C?如果在C中,那么您将读取system
ed命令的输出,就像读取txt文件一样。唯一的区别是您需要使用pclose
而不是fclose
来关闭它,因此使用文本文件进行关闭只会有好处。
如果在shell中,那么你可以启动你使用的程序,再次调用popen
,这次是"w"
(写入)方向,并将一个管道的输出写入另一个管道的输入。但是,在这种情况下,您可能首先使用匿名管道调用shell。 ; - )
<强> 编辑: 强>
您自己的回答清楚地表明您的要求与您的想法完全不同。如果它坚持写入文件,则无法通过管道和reg export
读取popen
的输出。
您可以尝试将文件写入临时文件夹;您应该被允许在那里创建文件,否则Windows将无法正常工作。只需将“%TEMP%\ reg.out”之类的内容指定为文件,然后从那里读取数据。
如果这不起作用,那么reg export
就不顺利了。但您可以使用某些Windows API函数直接查询注册表。这是starting point。
或者,您可能希望了解使用PowerShell的可能性。您可能会感兴趣question。
答案 2 :(得分:0)
您可以使用Windows中的某些API创建临时文件,并将数据存储在其中。
http://msdn.microsoft.com/en-us/library/windows/desktop/aa363875(v=vs.85).aspx
链接中有一个C ++示例,您应该能够根据您的情况进行调整。
答案 3 :(得分:0)
所以,我准备了代码,以便在读取模式下将DOS命令的输出流式传输到文件指针并逐行检查:
char array_sys[200]; FILE *fp_sys; int ch,n=0;
fp=popen("systeminfo","r"); //runs a DOS command & read it with a file pointer
if(fp_sys==NULL) printf("can't open file\n");
while((ch=fgetc(fp_sys))!=EOF) //READ CHARACTERS FROM FILE POINTER UNTIL FILE ENDS
{
array_sys[n]=ch; //ASSIGN CH TO EACH ELEMENT OF ARRAY
n++; //INCREMENT ELEMENTS OF ARRAY:-arr_sys
if(ch=='\n') //IF ELEMENTS MEET A NEW LINE CHARACTER
{
disp_date(array_sys,n); //PASS ARRAY TO FUNCTION:-disp_date
n=0; //RESET THE ARRAY
}
}
现在,这就是我在函数中处理数组以获取操作系统名称的方法。
void disp_date(char array_sys[],int ind)
{
char os_name[9]={"OS Name:"};
if(strstr(array_sys,os_name)) //IF 'OS NAME' IS PRESENT IN ARRAY
{
printf("%s",array_sys); //PRINT THE ARRAY
}
}