Почему команды Windows, которые обращаются к C:\Windows\System32\, не работают в программе C?

Я запускаю программу c, предназначенную для автоматизации процесса, который «переупаковывает» установку Windows. Я делаю это по двум причинам. Первая причина — это изучение программирования на C, а вторая причина в том, что я запускаю Windows с MacBook Pro, у которого нет супердрайва. Я нашел учебник, в котором объясняется, как установить Windows на vbox, а затем скопировать его на другой жесткий диск. Я решил, что хочу попрактиковаться в программировании на C и автоматизировать этот урок, поэтому я написал код ниже. Когда я запускаю приведенную ниже программу, я получаю сообщение об ошибке, что bcdedit не является внутренней или внешней командой и что unnattend.xml копирует, но когда я проверяю, есть ли она, ее нигде не найти. Немного поэкспериментировав, я обнаружил, что код, который я использую в функциях System(), работает отлично, если я запускаю его прямо из командной строки с повышенными правами. Хотя это дает мне ошибки, о которых я упоминал ранее, когда я запускаю свою программу из командной строки с повышенными правами. Кажется, что exe не имеет доступа к папке System32 ?? Пожалуйста помоги! Я бьюсь головой о стену здесь

    #include <stdio.h>

    void part1 (void);
    void part2 (void);

    void part1 (void)
    {
        FILE *fp;
        //Run Switcheroo
        if ((fp=fopen("log.txt", "r")) == NULL)
        {
            //Run part 1.
            system("DISKPART /s resources\\diskpart\\DskPrtAssgn.txt");
            system("TIMEOUT /T 3");
            system("reg unload HKLM\\BCD00000000");
            system("TIMEOUT /T 3");
            system("robocopy s:\\ c:\\ bootmgr");
            system("TIMEOUT /T 3");
            system("robocopy s:\\Boot c:\\Boot /s");
            system("TIMEOUT /T 3");
            system("bcdedit /store c:\\boot\\bcd /set {bootmgr} device partition=C:");
            system("TIMEOUT /T 3");
            system("DISKPART /s resources\\diskpart\\DskPrtActv.txt");
            system("TIMEOUT /T 3");
            system("schtasks /create /tn 'Switcheroo' /tr %userprofile%\\Desktop\\Switcheroo\\Switcheroo.exe /sc onlogon");

            //Set up the log file that the computer will check upon reboot.
            char buffer[2] = {'0'};
            fp = fopen("log.txt", "wb");
            fwrite (buffer , 1 , sizeof(buffer) , fp );

            //Reboot.
            system("shutdown -r");
        }
        else if (fp = fopen("log.txt", "rt"))
        {
            part2();
        }
    }

    void part2 (void)
    {
        FILE *fp;

        //Read the log file from part1. 
        if (fp = fopen("log.txt", "rt"))
        {
            //Run part 2.
            system("DISKPART /s resources\\diskpart\\DskPrtRmv.txt");
            system("TIMEOUT /T 3");
            system("cd resources\\sysprep");
            system("copy unattend.xml C:\Windows\System32\Sysprep");
            system("TIMEOUT /T 3");     
            system("runas /user:%username% %userprofile%\\Desktop\\Switcheroo\\resources\\sysprep\\ sysprep.bat");
        }

        //If part one did not finish then print error.
        else if ((fp=fopen("log.txt", "r")) == NULL)
        {
            printf("Error.");
        }
    }

    int main ()
    {
        part1();
        return(0);
    }

person arynhard    schedule 31.05.2012    source источник
comment
какую версию винды вы используете?   -  person fduff    schedule 31.05.2012
comment
Это очень похоже на пакетный файл ... просто говорю;).   -  person FatalError    schedule 31.05.2012
comment
@fduff: Windows 8. @ FatalError: Я знаю, но это просто для того, чтобы узнать, как работает программа на языке c. Я новичок в этом. Если вы знаете какой-либо другой способ сделать его более похожим на C, пожалуйста, не стесняйтесь показать мне. На самом деле я надеялся, что смогу найти способ сделать его менее похожим на пакетный файл.   -  person arynhard    schedule 31.05.2012
comment
Если вы хотите, чтобы он меньше походил на пакетный файл, вы можете подумать о включении windows.h. Я не знаю специфики, так как я никогда не использовал его, но это начало.   -  person Colin D    schedule 31.05.2012
comment
@ColinD: Да, я слышал об этом, но не могу найти по нему никакой хорошей документации. Вы знаете какой-нибудь? Спасибо.   -  person arynhard    schedule 31.05.2012
comment
@AndrewRynhard: Просто имейте в виду, что каждый вызов system() происходит в совершенно новой оболочке. Таким образом, вызов system(), который просто меняет каталоги, не будет особенно полезен (поскольку он не повлияет на последующие вызовы).   -  person FatalError    schedule 31.05.2012
comment
Кстати, не у всех есть каталог Windows на диске C:, поэтому рассмотрите возможность замены C:\Windows\System32 на %windir%\system32.   -  person milleniumbug    schedule 31.05.2012
comment
@milleniumbug Спасибо за совет!   -  person arynhard    schedule 31.05.2012
comment
@FatalError, вы правы, спасибо!   -  person arynhard    schedule 31.05.2012


Ответы (4)


Вы не должны писать сценарии системного администрирования на C. Делайте это в пакетном режиме, на python или в PowerShell. C абсолютно не подходит для программы, которую вы пишете.

person MK.    schedule 31.05.2012
comment
@МК. Я модифицировал программу c для запуска командного файла с помощью команды bcdedit. Возникают те же проблемы. Я понимаю, что c может быть не лучшим выбором, но ради обучения я хочу найти ответ на свою проблему. - person arynhard; 31.05.2012
comment
О, во что бы то ни стало, попробуй разобраться. Но я подумал, что стоит упомянуть, что делать это на C - неправильная вещь (tm). - person MK.; 31.05.2012
comment
Спасибо. Я попробую powershell. Цените помощь. - person arynhard; 31.05.2012

Я не могу точно сказать, что это ваша проблема, но... мне кажется подозрительным, что у вас есть system() вызовы, которые просто cd относятся к новому каталогу. Поскольку каждый из них выполняется в новой оболочке, это не повлияет на последующие вызовы system(). Таким образом, если вы попытаетесь перейти в каталог, где существует файл, чтобы работать с ним, вы обнаружите, что на самом деле находитесь не в этом каталоге.

person FatalError    schedule 31.05.2012
comment
+1 - я считаю, что это одна из как минимум 3 проблем с кодом. - person dbenham; 31.05.2012

Возможно, вы компилируете с отключенными предупреждениями?

Потому что в строке system("copy unattend.xml C:\Windows\System32\Sysprep"); нужно экранировать обратную косую черту.

ИЗМЕНИТЬ

Это будет проблема с привилегиями, когда вам будет отказано в доступе к этой папке. Это должно работать, если вы запускаете .exe от имени администратора.

person acraig5075    schedule 31.05.2012
comment
Я не вижу, как изменение параметров компиляции поможет. Ошибка возникает только во время выполнения. - person dbenham; 31.05.2012
comment
@dbenham \ - это escape-символ внутри строк C. так что вы получили \w и \S. Вы не хотите этого. Вам нужна только обратная косая черта. Значит надо сделать C:\\Windows\\System32\\Sysprep - person nos; 31.05.2012
comment
Я понимаю это. Я просто говорю, что компилятор никогда не мог обнаружить проблему. Код должен нормально компилироваться, без ошибок. Это ошибка времени выполнения. - person dbenham; 31.05.2012

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

system("copy unattend.xml C:\\Windows\\System32\\Sysprep"); 

Я должен согласиться, что то, что вы делаете, безумно для программы C. Но это должно работать.

ИЗМЕНИТЬ

Также похоже, что у вас есть нежелательный пробел перед sysprep.bat в вашем последнем вызове System().

Кроме того, я согласен с FatalError в том, что ваш системный вызов cd не приносит никакой пользы. Отбросьте эту строку, а затем добавьте к префиксу «unattend.xml» полный путь к файлу в следующей строке.

Если bcedit не найден ни в одной из ваших папок PATH по умолчанию, вам, вероятно, потребуется указать абсолютный путь к файлу.

person dbenham    schedule 31.05.2012
comment
@AndrewRynhard - посмотрите мой отредактированный ответ, указывающий на ненужное пространство. - person dbenham; 31.05.2012
comment
Да вы правы. Спасибо за это. Я до сих пор не могу понять, почему bcdedit не работает. - person arynhard; 31.05.2012
comment
@AndrewRynhard - плюс добавлены еще две проблемы - person dbenham; 31.05.2012