Ir ao conteúdo
  • Cadastre-se

C Armazenar informações do sistema em um .txt


Ragnarbrody

Posts recomendados

Estou tentando pegar informações do sistema windows usando a biblioteca windows.h e tentando armazenar esses dados em um txt externo, mas o txt fica vazio,

segue meu código:

#include <stdio.h>
#include <stdlib.h>
#include <locale.h>
#include <windows.h>
#include <conio.h>

void main ()
{
    setlocale(LC_ALL, "portuguese");
    char sysinfo [300];
    GetNativeSystemInfo(&sysinfo);
    FILE *ponteiro;
    ponteiro = fopen ("Configurações do sistema.txt", "w");
    fprintf(ponteiro, "%s", sysinfo);
    fclose(ponteiro);
    getch ();
}

 

podem me dizer o que estou fazendo de errado e como arrumar?

Link para o comentário
Compartilhar em outros sites

@Ragnarbrody    em qual compilador você disse que esse código rodou ?  ,   pois aqui no codeblock e visual studio ele não rodou e nem compilou ,  e assim não  gerou nenhum txt , e quais as informações do sistema você quer pegar ?  ,  aqui nesse código que achei na internet , ele funciona bem no visual studio  e mostrar algumas informações , como Qual o sistema Operacional , que está instalado  :

#include <windows.h>
#include <stdio.h>
#include <VersionHelpers.h>
int
__cdecl
wmain(
    __in int argc,
    __in_ecount(argc) PCWSTR argv[]
)
{
    UNREFERENCED_PARAMETER(argc);
    UNREFERENCED_PARAMETER(argv);
    if (IsWindowsXPOrGreater())
    {
        printf("XPOrGreater\n");
    }
    if (IsWindowsXPSP1OrGreater())
    {
        printf("XPSP1OrGreater\n");
    }
    if (IsWindowsXPSP2OrGreater())
    {
        printf("XPSP2OrGreater\n");
    }
    if (IsWindowsXPSP3OrGreater())
    {
        printf("XPSP3OrGreater\n");
    }
    if (IsWindowsVistaOrGreater())
    {
        printf("VistaOrGreater\n");
    }
    if (IsWindowsVistaSP1OrGreater())
    {
        printf("VistaSP1OrGreater\n");
    }
    if (IsWindowsVistaSP2OrGreater())
    {
        printf("VistaSP2OrGreater\n");
    }
    if (IsWindows7OrGreater())
    {
        printf("Windows7OrGreater\n");
    }
    if (IsWindows7SP1OrGreater())
    {
        printf("Windows7SP1OrGreater\n");
    }
    if (IsWindows8OrGreater())
    {
        printf("Windows8OrGreater\n");
    }
    if (IsWindows8Point1OrGreater())
    {
        printf("Windows8Point1OrGreater\n");
    }
    if (IsWindows10OrGreater())
    {
        printf("Windows10OrGreater\n");
    }
    if (IsWindowsServer())
    {
        printf("Server\n");
    }
    else
    {
        printf("Client\n");
    }
}

 

Link para o comentário
Compartilhar em outros sites

@Ragnarbrody

3 horas atrás, Ragnarbrody disse:

podem me dizer o que estou fazendo de errado e como arrumar?

É só ver a documentação. Você está passando um ponteiro para sysinfo, que é uma string, como argumento, quando deveria estar passando um ponteiro para a estrutura SYSTEM_INFO.

São várias informações que você consegue chamando essa função, então você precisa de um formulário pra preencher, que no caso é essa estrutura aí.

2 horas atrás, Ragnarbrody disse:

Tenta usar void ao invés de int no main

Isso é proibido. O padrão C exige que a função principal seja do tipo inteiro, não faria sentido a mesma não retornar nada.

3 horas atrás, Ragnarbrody disse:

eu quero informações do hardware, cpu, ram, hd, fabricante, modelo e também o usuário que está conectado

Grande exigência... Dê uma olhada na estrutura que mencionei, veja se ela tem o que você precisa, mas acredito que não, pelo menos não tudo, afinal, o nome já diz: system info.

  • Curtir 1
Link para o comentário
Compartilhar em outros sites

2 horas atrás, Ragnarbrody disse:

Cara, eu compilei no codeblocks e gera o txt mas em branco, esse que você mandou não funcionou, e eu quero informações do hardware, cpu, ram, hd, fabricante, modelo e também o usuário que está conectado

 

Você tentou ao menos ler a documentação?

 

Muito do que você quer está em SysInfoAPI.h e documentado claro em https://docs.microsoft.com/en-us/windows/win32/api/sysinfoapi/

 

De volta ao seu programa...

 

void GetNativeSystemInfo(
  LPSYSTEM_INFO lpSystemInfo
);

 

Esse é o protótipo da função. Então você deve passar um endereço de algo do tipo o que?  SYSTEM_INFO, claro. É o que está escrito lá na documentação. Seu IDE --- sim, IDE é masculino, o IDE --- não mostra isso? Então mude para outro. E leia a documentação.

 

Eis SYSTEM_INFO
 

typedef struct _SYSTEM_INFO {
  union {
    DWORD dwOemId;
    struct {
      WORD wProcessorArchitecture;
      WORD wReserved;
    } DUMMYSTRUCTNAME;
  } DUMMYUNIONNAME;
  DWORD     dwPageSize;
  LPVOID    lpMinimumApplicationAddress;
  LPVOID    lpMaximumApplicationAddress;
  DWORD_PTR dwActiveProcessorMask;
  DWORD     dwNumberOfProcessors;
  DWORD     dwProcessorType;
  DWORD     dwAllocationGranularity;
  WORD      wProcessorLevel;
  WORD      wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;

 

E o que foi que você passou? um char[300]. O que faz você pensar que vai funcionar? Não vai. 

 

Há outras maneiras mais flexíveis de fazer isso e recomendo busca por algo chamado WMI, que é uma API de instrumentação para o Windows e faz de tudo.

 

Mas não há razão para não ter sucesso com essas coisas tipo GetXYZ(). Mas coisas como

 

    fprintf(ponteiro, "%s", sysinfo);

 

Não vão dar em nada. Você em que ler a estrutura e a partir daí gravar o que quer. Isso não é texto. C e essas cosias foram feitas para comunicar programas com programas e com dispositivos e o sistema, não para escrever arquivos de texto ou escrever para pessoas, O meio de campo é o seu programa...

 

Tire essa coisa de conio.h de seu programa. Isso é uma bobagem dos anos 80 (!) derivada de uma biblioteca inspirada em coisas dos anos 70. Não é possível que  programando em C em 2021 você precise de uma biblioteca de meia dúzia de funções b0b1nh@s, como getch().

 

Veja um exemplo mais completo na documentação em https://docs.microsoft.com/en-us/windows/win32/sysinfo/getting-system-information

 

EXEMPLO 

 

Esse arquivo é gerado pelo programa...

 

4 processadores
Pagina tem 4096 bytes
usuario = 'toninho'

 

Em C

 

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

int main(void)
{
    SYSTEM_INFO     info;
    WCHAR           usuario[1024]; // wchar
    char            userA[1024]; // char
    LPWSTR          p = &usuario[0];
    DWORD           tam = sizeof(usuario);
    GetNativeSystemInfo( &info );
    FILE*   texto = fopen("coisa.txt", "w");
    if (texto == NULL)  return -1;
    fprintf( texto, "%d processadores\n", info.dwNumberOfProcessors);
    fprintf( texto, "Pagina tem %d bytes\n", info.dwPageSize);
    if ( GetUserName( usuario, &tam ) == 0)
    {
        perror("GetUSerName() Falhou");
        fclose(texto);
        return -2;
    }
    tam = lstrlenW(usuario);
    wcstombs( userA, usuario, sizeof(userA));
    fprintf( texto, "usuario = '%s'\n", userA);
    fclose(texto);
    return 0;
}

 

 

Onde você pode ver a ideia geral... Escreva se não entendeu

 

 

 

1 hora atrás, Ragnarbrody disse:

conseguir , ainda, armazenar isso em um txt

 

gravar arquivos em C é trivial

  • Curtir 1
  • Obrigado 1
Link para o comentário
Compartilhar em outros sites

@arfneto Amigo, consegui fazer da maneira como mencionou, porém, quanto ao processador, tem alguma maneira de obter o modelo do processador? e sobre o disco rigído, consigo obter modelo e tamanho? sobre o sistema operacional eu vi algo na documentação, mas não sei se consigo obter o nome do sistema operacional de maneira direta. Seria possível, também, obter dados da fabricante do computador e o modelo? da fabricante eu gostaria de conseguir obter apenas o nome, e do modelo o nome. Tem como também obter a data de instalação do windows?

me perdoe o incomodo e minha relativa ignorância no assunto, segue meu código e muito obrigado:


 

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <locale.h>
#include <tchar.h>


int main(void)
{
    setlocale (LC_ALL, "portuguese");
    int opcao = 0;
    printf("\n                ======================================");
    printf("\n                =                                    =");
    printf("\n                =        Olá!! Seja Bem Vindo(a)     =");
    printf("\n                =                                    =");
    printf("\n                ======================================");
    printf("\n\n");
    printf("\n                  Este programa coletará alguns dados");
    printf("\n                  de seu computador para auditoria do");
    printf("\n                    mesmo, digite a opção desejada:  ");
    printf("\n                            [01 - Iniciar]           ");
    printf("\n                            [02 -   Sair ]           ");
    printf("\n");
    printf("\n                > ");
    Errado:
    scanf("%d", &opcao);
    if (opcao == 1)
    {
        SYSTEM_INFO     sysinfo; //obtem as informações do sistema
        GetNativeSystemInfo( &sysinfo );
        long memory; //crio uma variável do tipo inteira longa
        BOOL checar_ram; //é criada uma váriável booleana para armazenar o ponteiro

        checar_ram = GetPhysicallyInstalledSystemMemory(&memory); //os dados apontados são armazenados na variável "memory"

        #define INFO_BUFFER_SIZE 20000
        DWORD buffer = INFO_BUFFER_SIZE;
        TCHAR infoBuffer [INFO_BUFFER_SIZE];
        if (!GetUserName(infoBuffer, &buffer))
        {
            _tprintf(TEXT("GetUserName"));
        }

        FILE*  requisitos = fopen("Configurações do Computador.txt", "w"); //cria um arquivo se não existir, se existir, ele
        // será sobrescrito, o parametro "w" define que é para escrever o que tiver na variável requisitos dentro desse arquivo
        if (requisitos == NULL) // testa se o arquivo foi criado com sucesso
        {
            fprintf( requisitos, "Ocorreu um erro ao criar o arquivo");
            return -1;
        }
        fprintf( requisitos, "Na presente máquina se encontra a seguinte configuração: \n\n");
        fprintf( requisitos, "Nome de usuário: %s;\n", infoBuffer);
        fprintf( requisitos, "%d Processadores (Quantidade de núcleos);\n", sysinfo.dwNumberOfProcessors);
        fprintf( requisitos, "%lu Megabytes de memória RAM instalada na máquina;\n", memory/1024 );
        fprintf( requisitos, "\n\nObrigado por utilizar o programa :D\n");
        fclose(requisitos);
        return 0;
    }
    else if (opcao == 2)
    {
        return 0;
    }
    else
    {
        system ("cls");
        printf("\n                ======================================");
        printf("\n                =                                    =");
        printf("\n                = Opção Inválida !! Digite novamente =");
        printf("\n                =                                    =");
        printf("\n                ======================================");
        printf("\n\n");
        printf("\n                            [01 - Iniciar]           ");
        printf("\n                            [02 -   Sair ]           ");
        printf("\n\n                > ");
        goto Errado;
    }
}

 

sei que não é o ideal usar goto mas é um programa curto

 

desde já agradeço.

Link para o comentário
Compartilhar em outros sites

2 horas atrás, Ragnarbrody disse:

sei que não é o ideal usar goto mas é um programa curto

 

 

Não há nada especial em usar um goto. Mas nesse caso não vejo a razão. E por certo não tem a ver com o tamanho do programa.

 

Entenda que

  • um menu deve ser algo assim: mostra as alternativas, lê a opção e entra em uma seleção para executar o que foi pedido. Nada mais. 
  • Isso sugere um loop enquanto a opção não for encerrar. Enquanto sugere while, a palavra em inglês para... 🤔 enquanto. Isso quer dizer que um loop deve resolver.
  • para escolher a opção Sair o cara tem que ter visto a lista de opções então tem que mostrar a lista pelo menos uma vez, e aí então ler a opção. Um loop que executa ao menos uma vez, em C, tem um nome:
     
            do { } while ();

    que significa "faça o que está entre as chaves enquanto não acontecer o que está entre parenteses". Isso é o simples.
  • Em geral se usa uma função, tipo
     
        char    menu(); // que mostra o menu e devolve a opção...

     

        Um goto --- ir para --- nesse caso é mais complicado e não mais simples. Mas pode ser assim

 

 

printf() e um programa interativo

 

Não entendo a razão de escrever um programa interativo agora. Qual o propósito? Vai inclusive gravar um arquivo texto com o resultado. Escreva seu programa como eu mostrei. Depois que o arquivo texto tiver todas as opções que você quer aí em 10 minutos você coloca esse tal menu.

 

Isso não serve pra nada e só atrasa os testes. Um printf() é só um printf(). Um fgets() é só um fgets(). Nada acrescenta. Não vai aprender nada. E a cada vez que quiser testar o programa, e está testando as chamadas a funções do Windows que você nem conhece ainda, pra que vai ficar em frente ao menu digitando 1 e 2 e 3 e depois abrindo um arquivo texto? Esqueça isso.

 

Não escreva programas interativos. C  nem é pra isso. Ao final você acrescenta a interatividade, se preciso. Ao final

 

Como eu te disse antes, é muito mais fácil usar arquivos no disco em C do que a tela e o teclado.

 

Veja isso:
 

    printf("\n                ======================================");
    printf("\n                =                                    =");
    printf("\n                =        Olá!! Seja Bem Vindo(a)     =");
    printf("\n                =                                    =");
    printf("\n                ======================================");
    printf("\n\n");
    printf("\n                  Este programa coletará alguns dados");
    printf("\n                  de seu computador para auditoria do");
    printf("\n                    mesmo, digite a opção desejada:  ");
    printf("\n                            [01 - Iniciar]           ");
    printf("\n                            [02 -   Sair ]           ");
    printf("\n");
    printf("\n                > ");

 

Sua dúvida presente é como identificar por exemplo a marca do HD e a versão do Windows. Que diferença faz tem "Olá" com acento em um menu proporcionado por nada menos que 13 chamadas a printf() ?  Notou que é um inferno ficar alinhando isso? E nada tem a ver com seu programa afinal...

 

Exemplo
 

    printf("\n\
                ======================================\n\
                =                                    =\n\
                =        Olá!! Seja Bem Vindo(a)     =\n\
                =                                    =\n\
                ======================================\n\
\n\
                  Este programa coletará alguns dados\n\
                  de seu computador para auditoria do\n\
                  mesmo, digite a opção desejada:  \n\
                            [01 - Iniciar]           \n\
                            [02 -   Sair ]           \n\
                > "
                );

 

Esse comando faz a mesma coisa, mas chama printf() uma vez só e fica mais fácil de alinhar o texto e de ver o que vai sair na tela. Mas ainda é bobagem.

 

Exemplo
 


                ======================================
                =                                    =
                =        Olá!! Seja Bem Vindo(a)     =
                =                                    =
                ======================================

                  Este programa coletará alguns dados
                  de seu computador para auditoria do
                  mesmo, digite a opção desejada:
                            [01 - Iniciar]
                            [02 -   Sair ]
                > 

 

Que tal isso em um arquivo menu.txt?  Você abre e põe na tela. Usa o próprio IDE para digitar o menu. Depois que o programa estiver ok você grava o menu como constante no programa....

 

Recomendo não perder tempo com essas coisas

Link para o comentário
Compartilhar em outros sites

@arfneto Certo, entendo seu ponto sobre toda as vezes ficar acessando entre o menu, eu vou deixar de lado no momento o menu e talvez no final implemente ele com um switch ao invés de um do while ou while.

Obrigado.

 

Outra coisa, poderia me dizer qual o comando para obter o modelo do processador e o tamanho do disco?

 

Link para o comentário
Compartilhar em outros sites

3 horas atrás, Ragnarbrody disse:

e talvez no final implemente ele com um switch ao invés de um do while ou while

 

Escreva logo uma função e use em TODOS os programas chatos que tem menu. E leia o menu a partir de uma constante ou um arquivo texto. Não perca tempo com isso.

 

3 horas atrás, Ragnarbrody disse:

Outra coisa, poderia me dizer qual o comando para obter o modelo do processador e o tamanho do disco?

 

Terá lido a parte em que eu te falei para ler sobre WMI? É toda uma tecnologia desenvolvida apenas para isso, que no geral se chama de instrumentação.


Mas isso está claro em várias estruturas do sistema. Pode pegar o processador em

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Environment

no registro.

 

Também em 

Computador\HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor

 

Tem uma entrada para cada processador do sistema. E lá dentro tem o valor ProcessorNameString que acho que é o que você quer... Um Octa-core tem 8 entradas :) pouco útil já que serão iguais.

 

E para o nome 'comercial' dele pode ver em ACPI também, logo depois no nome que estava em environment vem depois do hífen o modelo dele.

 

A questão do disco é mais difícil porque tem discos físicos, lógicos, removíveis, o d1@b0....

 

Mas pode navegar em ACPI também... E talvez precise rodar como administrador para poder rodar isso. Lá tem a lista dos discos. Deve ter algo mais mas não me lembro agora.

 

 

 

Link para o comentário
Compartilhar em outros sites

Crie uma conta ou entre para comentar

Você precisa ser um usuário para fazer um comentário

Criar uma conta

Crie uma nova conta em nossa comunidade. É fácil!

Crie uma nova conta

Entrar

Já tem uma conta? Faça o login.

Entrar agora

Sobre o Clube do Hardware

No ar desde 1996, o Clube do Hardware é uma das maiores, mais antigas e mais respeitadas comunidades sobre tecnologia do Brasil. Leia mais

Direitos autorais

Não permitimos a cópia ou reprodução do conteúdo do nosso site, fórum, newsletters e redes sociais, mesmo citando-se a fonte. Leia mais

×
×
  • Criar novo...

 

GRÁTIS: ebook Redes Wi-Fi – 2ª Edição

EBOOK GRÁTIS!

CLIQUE AQUI E BAIXE AGORA MESMO!