简易操作系统:使用Python 做的图形界面 C 做的内核

这篇具有很好参考价值的文章主要介绍了简易操作系统:使用Python 做的图形界面 C 做的内核。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

实验要求

一、文件管理和用户接口

⑴文件的逻辑结构

⑵磁盘模拟

⑶目录结构

⑷磁盘分配

⑸磁盘空闲存储空间管理

⑹用户接口

⑺屏幕显示

 代码部分

        python调用c的方法:

​编辑

c语言部分,文件名 Operating_System_C.c

python语言部分

运行实例:


实验要求

一、文件管理和用户接口

   文件管理和用户接口部分实现的主要是单用户的磁盘文件管理部分,包括文件的逻辑结构、物理结构、目录、磁盘分配回收、文件的保护和用户接口的实现。

文件的逻辑结构

  文件的逻辑结构采用流式结构;

   文件均采用文本文件;

   系统中有两种文件,一种是存放任意字符的文件,一种是可执行文件。可执行文件的内容就是模拟系统内进程的程序体。

文件中的“可执行”文件,包含的命令非常简单,包括:

x=?;  x 赋值一位数
x++;  x 1
x--;    x 1
!?? 第一个?为 A,B,C 中某个设备,第二个?为一位数,表示使用设备的时间(由于没有实际设备,所以无法知道设备何时工作完成,所以假定一个数,这个数随着系统时间增加而递减,减到 0 时,认为是设备工作完成)
end.   表示文件结束,同时将结果写入文件 out ,其中包括文件路径名和 x 的值。

磁盘模拟

    用一个文本文件disk模拟磁盘,磁盘的每个盘块64字节,模拟磁盘共有128块。第01块存放文件分配表,第2块存放根目录,其余存放子目录和文件。

目录结构

      目录结构采用树型目录结构。

        ①目录项内容(8个字节):

        目录名、文件名:3 个字节;
        扩展名:2 个字节(可执行文件扩展名为 e ,目录没有扩展名);
        目录、文件属性:1 字节;
        起始盘块号:1 个字节;
        文件长度:1 字节(目录没有长度)。

根目录

  根目录位置固定,占用模拟磁盘第2块,大小固定,共8项;

③子目录

  位置不固定,大小不固定。(至少建立一级子目录,最好支持多级子目录)

磁盘分配

       磁盘的分配采用链接结构(显式链接)的分配。

⑸磁盘空闲存储空间管理

    磁盘空闲存储空间管理采用位示图方法。

  位示图和显示链接的指针合在一起组成文件分配表,占用磁盘空间第01

用户接口

    用户接口提供用户命令接口,要求实现以下命令:

创建文件:create     拷贝文件:copy     

删除文件:delete     移动文件:move  

显示文件:type        改变文件属性:change  

建立目录:makdir     改变目录路径:chadir       

删除目录:deldir(deltree修改文件 edit

  运行可执行文件:可执行文件的文件名(创建进程)。

屏幕显示

    屏幕显示要求包括:

n 用户命令接口:用于系统运行时用户输入命令
n 磁盘目录显示:要求显示磁盘的树型目录结构
n 磁盘使用情况:显示磁盘每一个磁盘块的空间是占用还是空闲

 代码部分

c和python各1000多行

        python调用c的方法:

        python导入ctypes库,在pycham控制台输入

gcc Operating_System_C.c -shared -o Operating_System_C.dll

若提示

简易操作系统:使用Python 做的图形界面 C 做的内核

可能是你的路径不对,注意切换到.c文件的目录

简易操作系统:使用Python 做的图形界面 C 做的内核

若提示,没有gcc之类的,请去MinGW-w64 - for 32 and 64 bit Windows - Browse Files at SourceForge.netA complete runtime environment for gcchttps://sourceforge.net/projects/mingw-w64/files/

简易操作系统:使用Python 做的图形界面 C 做的内核

 下载

  • x86_64-posix-sehhttps://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/8.1.0/threads-posix/seh/x86_64-8.1.0-release-posix-seh-rt_v6-rev0.7z

这是我下载的文件,仅需1积分(友情链接) 

 并把压缩包解压,将含有g++.exe的文件路径添加到环境变量中

简易操作系统:使用Python 做的图形界面 C 做的内核

 简易操作系统:使用Python 做的图形界面 C 做的内核

 打开cmd 输入gcc --version 若弹出以下内容

简易操作系统:使用Python 做的图形界面 C 做的内核

表明安装完成

然后就可以用

Operating_System_C = ctypes.cdll.LoadLibrary('./Operating_System_C.dll')

 打开自己写的c文件,调用其中的函数了(函数默认返回值为ctypes.c_int类型,函数的输入也要转化为ctypes的类型才行,具体情况请自己去搜索ctypes教程)

c语言部分,文件名 Operating_System_C.c

需要在控制台输入

gcc Operating_System_C.c -shared -o Operating_System_C.dll

生成.dll文件才能被python调用

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


// 目录项
/*
目录名、文件名:3个字节;
扩展名:2个字节(可执行文件扩展名为e,目录没有扩展名);
目录、文件属性:1字节;
起始盘块号:1个字节;
文件长度:1字节(目录没有长度)。
*/
struct catalog_entry{
    char name[3];
    char extend[2];
    unsigned char attribute : 8;   // 1目录,2文件,0不存在
    unsigned char start : 8;
    unsigned char len : 8;
};



// 八位数据类型,主要用于位视图
union bit8{
unsigned char data : 8;
struct bits8{   // 注意排列 b0 b1 b2 b3 b4 b5 b6 b7
    unsigned char b7 : 1;
    unsigned char b6 : 1;
    unsigned char b5 : 1;
    unsigned char b4 : 1;
    unsigned char b3 : 1;
    unsigned char b2 : 1;
    unsigned char b1 : 1;
    unsigned char b0 : 1;
}bit8;
};



// 索引7*8
union index56{
unsigned char datas[7];
};



// 索引变量 记录索引的值
unsigned char index_variables[128];

// 位视图
union bit8 bitwise_view[16];


// 文件变量
FILE* file;


// 输出文件
FILE* fp;




// 保存位视图,给出块号,保存它,负数保存所有
void Save_Bitview(FILE* file,int position){
    if(position<0){
        fseek(file,0,SEEK_SET);    // 文件指针移动
        fwrite(bitwise_view,1,16,file);
    }else{
        char t[1] = {bitwise_view[position/8].data};
        fseek(file,position/8,SEEK_SET);    // 文件指针移动
        fwrite(t,1,1,file);
    }
}



// 从位视图中返回一个空块的位置失败返回-1
int Give_Empty_Block(){
    int i,j;
    for(i=0;i<16;i++){
        if(bitwise_view[i].bit8.b0 == 0)
            return i*8+0;
        if(bitwise_view[i].bit8.b1 == 0)
            return i*8+1;
        if(bitwise_view[i].bit8.b2 == 0)
            return i*8+2;
        if(bitwise_view[i].bit8.b3 == 0)
            return i*8+3;
        if(bitwise_view[i].bit8.b4 == 0)
            return i*8+4;
        if(bitwise_view[i].bit8.b5 == 0)
            return i*8+5;
        if(bitwise_view[i].bit8.b6 == 0)
            return i*8+6;
        if(bitwise_view[i].bit8.b7 == 0)
            return i*8+7;
    }
    return -1;
}



// 占用块,成功1,失败-1
int Occupy_Block(FILE* file,int i){
    switch(i%8){    // 挨个位看
        case 0:if(bitwise_view[i/8].bit8.b0==1){return -1;}else{bitwise_view[i/8].bit8.b0=1;}break;
        case 1:if(bitwise_view[i/8].bit8.b1==1){return -1;}else{bitwise_view[i/8].bit8.b1=1;}break;
        case 2:if(bitwise_view[i/8].bit8.b2==1){return -1;}else{bitwise_view[i/8].bit8.b2=1;}break;
        case 3:if(bitwise_view[i/8].bit8.b3==1){return -1;}else{bitwise_view[i/8].bit8.b3=1;}break;
        case 4:if(bitwise_view[i/8].bit8.b4==1){return -1;}else{bitwise_view[i/8].bit8.b4=1;}break;
        case 5:if(bitwise_view[i/8].bit8.b5==1){return -1;}else{bitwise_view[i/8].bit8.b5=1;}break;
        case 6:if(bitwise_view[i/8].bit8.b6==1){return -1;}else{bitwise_view[i/8].bit8.b6=1;}break;
        case 7:if(bitwise_view[i/8].bit8.b7==1){return -1;}else{bitwise_view[i/8].bit8.b7=1;}break;
    }
    // 保存更改
    Save_Bitview(file,i);
    char t[1];
    int j;
    // 清空原有块中的东西
    fseek(file,i*64,SEEK_SET);    // 文件指针移动
    t[0] = 0b00000000;
    for(j=0;j<64;j++)   // 0掩盖
        fwrite(t,1,1,file);
    return 1;
}



// 取消占用块
void Unoccupie_Block(FILE* file,int i){
    switch(i%8){    // 挨个位看
        case 0:bitwise_view[i/8].bit8.b0=0;break;
        case 1:bitwise_view[i/8].bit8.b1=0;break;
        case 2:bitwise_view[i/8].bit8.b2=0;break;
        case 3:bitwise_view[i/8].bit8.b3=0;break;
        case 4:bitwise_view[i/8].bit8.b4=0;break;
        case 5:bitwise_view[i/8].bit8.b5=0;break;
        case 6:bitwise_view[i/8].bit8.b6=0;break;
        case 7:bitwise_view[i/8].bit8.b7=0;break;
    }
    // 保存更改
    Save_Bitview(file,i);
}



// 返回索引最后一个块的编号
int Index_End(int x){
    if (index_variables[x] == 0){ // 末尾0,索引到了
        return x;
    }else{
        Index_End(index_variables[x]);    // 继续
    }
}



// 保存索引表,给出块号,保存它,负数保存所有
void Save_Index(FILE* file,int position){
    union index56 index_pointer[1];//索引指针,保存用
    int i,j;
    if(position<0){
        fseek(file,16,SEEK_SET);    // 文件指针移动
        for(i=0;i<16;i++){
            index_pointer[0].datas[6] = index_variables[i*8+7];
            for(j=6;j>=0;j--){
                index_pointer[0].datas[j] += index_variables[i*8+j]<<j+1;
                if(j!=0){
                    index_pointer[0].datas[j-1] = index_variables[i*8+j]>>7-j;
                }
            }
            fwrite(index_pointer,7,1,file);
        }
    }else{
        fseek(file,16+position/8*7,SEEK_SET);    // 文件指针移动
        i = position/8*8;
        index_pointer[0].datas[6] = index_variables[i+7];
        for(j=6;j>=0;j--){
            index_pointer[0].datas[j] += index_variables[i+j]<<j+1;
            if(j!=0){
                index_pointer[0].datas[j-1] = index_variables[i+j]>>7-j;
            }
        }
        fwrite(index_pointer,7,1,file);
    }

}



// 删除索引,连着删除这一块后面所有的索引,同时取消块占用
void Drop_Index(FILE* file,int x){
    if (index_variables[x] != 0){ // 不是最后一个
        Drop_Index(file,index_variables[x]);  // 往下走
        index_variables[x] = 0; // 删除该索引
        Save_Index(file,x);    // 保存索引表
    }
    Unoccupie_Block(file,x); //取消块占用
    // 末尾0,索引结束
}



// 保存位视图和索引表,
void Save_Start(FILE* file){
    union index56 index_pointer[1];//索引指针,保存用
    int i,j;
    fseek(file,0,SEEK_SET);    // 文件指针移动
    fwrite(bitwise_view,1,16,file);
    for(i=0;i<16;i++){
        index_pointer[0].datas[6] = index_variables[i*8+7];
        for(j=6;j>=0;j--){
            index_pointer[0].datas[j] += index_variables[i*8+j]<<j+1;
            if(j!=0){
                index_pointer[0].datas[j-1] = index_variables[i*8+j]>>7-j;
            }
        }
        fwrite(index_pointer,7,1,file);
    }
}



// 读取位视图和索引表
void Read_Start(FILE* file){
    fseek(file,0,SEEK_SET);    // 文件指针移动
    // 数据数组,每个元素字节,元素个数,输入文件位置
    fread(bitwise_view,1,16,file);
    int i,j;
    union index56 index_pointer[1];//索引指针,读取用
    for(i=0;i<16;i++){
        fread(index_pointer,7,1,file);
        index_variables[i*8] = index_pointer[0].datas[0]>>1;
        for(j=0;j<7;j++){
            index_variables[i*8+j+1] = (index_pointer[0].datas[j]<<(6-j))%128;
            if(j!=6){
                index_variables[i*8+j+1] += index_pointer[0].datas[j+1]>>(j+2);
            }
        }
    }
}



// 查看目录在块中文件是否存满,存满返回-1,否则返回第一个空的文件位置(字节位置)
// 带递归翻页
int Directory_Overrun(FILE* file,int start,int len){
    if(start==0){ // 空了,前面都没找到
        return -1;
    }
    fseek(file,64*start,SEEK_SET);    // 文件指针移动
    struct catalog_entry directory[8];  // 读取到的目录
    fread(directory,8,8,file);// 读取
    int i;
    for(i=0;i<8;i++)
    {
        if(directory[i].attribute==0)
        {
            return 64*start+8*i;
        }
    }
    return Directory_Overrun(file,index_variables[start],len-1);    // 到这里没有,看看下一页
}



// 输出位视图
void Printf_Bitwise_View(){
    int i;
    fprintf(fp,"\n位视图:");
    for(i=0;i<16;i++)
    {
        fprintf(fp,"\n%d",bitwise_view[i].bit8.b0);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b1);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b2);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b3);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b4);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b5);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b6);
        fprintf(fp,"  %d",bitwise_view[i].bit8.b7);
    }
    fprintf(fp,"\n");
}



// 输出索引阵列
void Printf_Index_variables(){
    int i,j;
    fprintf(fp,"\n索引变量\n");
    for(i=0;i<16;i++){
        for(j=0;j<8;j++)
        {
            fprintf(fp,"%5d",index_variables[i*8+j]);
        }
        fprintf(fp,"\n");
    }
}




// 输出目录
void Printf_Entry(struct catalog_entry entry){
    if(entry.attribute == 0){
        fprintf(fp,"\n目录不存在");
        return;
    }
    fprintf(fp,"\n名称:");
    int i;
    for(i=0;i<3;i++){
        if(entry.name[i]!='\0'){
            fprintf(fp,"%c",entry.name[i]);
        }
        else{
            break;
        }
    }
    if(entry.attribute > 1){
        fprintf(fp,"\n扩展名:");
        for(i=0;i<2;i++){
            if(entry.extend[i]!='\0'){
                fprintf(fp,"%c",entry.extend[i]);
            }else{
            if(i==0){
                fprintf(fp,"无");}
            break;
            }
        }
    }
    fprintf(fp,"\n属性:");
    switch(entry.attribute){
    case 0: fprintf(fp,"不存在");break;
    case 1: fprintf(fp,"目录");break;
    case 2: fprintf(fp,"文件");break;
    default:    fprintf(fp,"其他");break;}
    fprintf(fp," %d",entry.attribute);
    fprintf(fp,"\n起始块:%d\n长度:%d\n",entry.start,entry.len);
}



// 生成目录项
// 名字,扩展名,属性,起始块号,文件长度
struct catalog_entry Generate_Catalog_Entry(char* name,char* extend,int attribute,int start,int len){
    struct catalog_entry entry = {"","",attribute,start,len};
    entry.name[0]=name[0];entry.name[1]=name[1];entry.name[2]=name[2];
    entry.extend[0]=extend[0];entry.extend[1]=extend[1];
    return entry;
}



// 在块中按名查找文件或目录,返回目录项,同时最后一个数据指针的值更改为文件目录项字节位置,没有不会更改
struct catalog_entry LookUp(FILE* file,char* name,int start,int len,int *p){
    struct catalog_entry directory[8]; // 读取到的目录
    if(start==0){ // 空了,前面都没找到
        directory[0].attribute = 0;
        return directory[0];
    }
    fseek(file,64*start,SEEK_SET);    // 文件指针移动
    fread(directory,8,8,file);// 读取
    int i;
    for(i=0;i<8;i++){
        if(directory[i].attribute!=0){// 这个东西存的有
            // 开始名称匹配
            if(directory[i].name[0]==name[0]){// 第一个匹配
                if(name[0]=='\0'){// 结束了
                    *p = start*64+i*8;
                    return directory[i];
                }else{
                    if(directory[i].name[1]==name[1]){// 第二个匹配
                        if(name[1]=='\0'){// 结束了
                            *p = start*64+i*8;
                            return directory[i];
                        }else{
                            if(directory[i].name[2]==name[2]){// 第三个匹配
                                *p = start*64+i*8;
                                return directory[i];
                            }
                        }
                    }
                }
            }
        }
    }
    return LookUp(file,name,index_variables[start],len-1,p);    // 到这里没有,看看下一页
}



// 目录长度改变,要改变的目录,改变值
void Directory_Length_Chenge(FILE* file,struct catalog_entry entry,int change){
    char lend[1] = {entry.len+change};
    struct catalog_entry directory[1]; // 读取到的目录
    int t;
    int *p=&t;
    fseek(file,64*entry.start+7,SEEK_SET);    // 文件指针移动到当前目录的长度属性
    fwrite(lend,1,1,file);  // 改变
    fseek(file,64*entry.start+8,SEEK_SET);    // 文件指针移动到父目录
    fread(directory,8,1,file);// 读取
    if(LookUp(file,entry.name,directory[0].start,directory[0].len,p).attribute == 0){ // 查找目录字节位置
        fprintf(fp,"\n严重错误,对目录的父目录中未找到自己,目录长度改变失败");// 没找到
    }else{
        fseek(file,t+7,SEEK_SET);  // 移动到该目录项的长度位置
        fwrite(lend,1,1,file);  // 改变
    }
}



// 目录整理,整理参数中目录表指向的目录,顺便会删除空的目录项
// 带翻页,不整花活,直接暴力读取,排序,修改
int Catalog_Organization(FILE* file,struct catalog_entry entry){
    int i,j,k=entry.len-1,l=7,start=entry.start;
    struct catalog_entry directory[entry.len][8];
    for(i=0;i<entry.len;i++){   // 遍历每个块
        fseek(file,64*start,SEEK_SET);    // 文件指针移动
        fread(directory[i],8,8,file);// 读取
        start = index_variables[start]; // 下一块
    }
    i=0;j=entry.len*8-1;
    while(i!=j){// 撞上就停
        if(directory[i/8][i%8].attribute!=0){//i没指向一个空位
            i++;    // 前进
        }else{
            if(directory[j/8][j%8].attribute==0){//j没指向一个存在的位置
                j--;
            }else{// i指向空位,j指向一个存在的位置
                directory[i/8][i%8]=directory[j/8][j%8];    // 替换
                directory[j/8][j%8].attribute = 0;
            }
        }
    }
    i = (i-1)/8;// 看看指针停在第几块,就保存在前几块
    start=entry.start;
    for(j=0;j<=i;j++){// 遍历块保存新目录
        if(j==i){
            k = start;
        }
        fseek(file,64*start,SEEK_SET);    // 文件指针移动
        fwrite(directory[j],8,8,file);  // 保存
        start = index_variables[start]; // 下一块
    }
    if(start!=0){// 不是最后一块
        index_variables[k] = 0;
        Save_Index(file,k);    // 保存索引表
        Drop_Index(file,start);   // 删后面索引
    }
    Directory_Length_Chenge(file,entry,i-entry.len+1);   // 文件长度改变
}



// 重建根目录
void Rebuild_Root_Directory(FILE* file){
    // 根目录位置固定,占用模拟磁盘第2块,大小固定,共8项;
    // 目录都包含当前目录.和父目录..  采用.=..表示根目录。
    struct catalog_entry root_directory[2];
    char name[3]={'.','\0','\0'};
    char extend[2]={'\0','\0'};
    int i;
    // 只用一个struct catalog_entry更经济,但这么写更直观
    root_directory[0] = Generate_Catalog_Entry(name,extend,1,2,1); // 当前目录
    name[1] = '.';
    root_directory[1] = Generate_Catalog_Entry(name,extend,1,2,1); // 父目录
    fseek(file,64*2,SEEK_SET);    // 文件指针移动
    fwrite(root_directory,8,2,file);    // 保存两个特殊目录项
    name[0] = 0;
    for(i=16;i<128;i++){
        fwrite(name,1,1,file);
    }

}



void Reset_Disk()   // 重置磁盘,直接新建磁盘文件,删除之前所有记录
{
    FILE* file;
    file = fopen("disk.txt","w+");  // 创建磁盘文件
    fprintf(fp,"\n已重新创建磁盘文件 disk.txt ");
    // disk是模拟磁盘,开始生成模拟磁盘的数据
    // 磁盘的分配采用链接结构(显式链接)的分配。
    // 共有128块,每个盘块64字节,共8192字节
    // 第0、1块存放文件分配表,位示图和显示链接的指针合在一起组成文件分配表
    // 第2块存放根目录,其余存放子目录和文件
    // 位视图要有128位,即16字节
    // 初始第0、1、2块都在占用
    int i,j;
    bitwise_view[0].data = 0b11100000;// 前三块必定被占用,
    for(i=1;i<16;i++){
        bitwise_view[i].data = 0;   // 其余暂时置0
    }
    // 数据数组,每个元素字节,元素个数,输出到文件位置
    // 128个块,索引只需7位,刚好(7*128)/4+16=128占两个块
    for(i=0;i<128;i++){ //索引置0
        index_variables[i] = 0;
    }
    Save_Start(file);// 保存位视图和索引表
    Rebuild_Root_Directory(file);// 重建根目录
    // 填补剩下的磁盘
    char t[1] = {0b0};
    fseek(file,64*3,SEEK_SET);    // 文件指针移动
    for(i=192;i<8192;i++){
        fwrite(t,1,1,file);
    }
    fclose(file);
}



// 创建文件,成功返回块号,否则-1   文件名,扩展名,目录 ,文件属性(目录1,文件>1)
int Create(FILE* file,char* name,char* extend,struct catalog_entry entry,char attribute){
    if(attribute <= 0){
        fprintf(fp,"\n创建参数错误,创建失败");
        return -1;
    }
    int position = Directory_Overrun(file,entry.start,entry.len);  // 找找空位
    if(position == -1){// 没找到空位
        if(entry.start == 2){   // 是根目录
            fprintf(fp,"\n根目录已满,无法创建");// 根目录只能有1页
            return -1;
        }
        else{ // 否则可以新增一页
            int piece = Give_Empty_Block(); // 找一个新块
            if(piece==-1){  // 找不到
                fprintf(fp,"\n磁盘已满,无法创建");
                return -1;
            }else{ // 新增一页
                int iend = Index_End(entry.start);// 找到目录的末页
                Occupy_Block(file,piece);   // 占用新块,刚找到的新块,就不看在不在了
                index_variables[iend] = piece;    // 索引延申
                Save_Index(file,iend); // 改完索引要保存
                // 新增页了,文件长度需要+1
                Directory_Length_Chenge(file,entry,1);
                position = piece*64;    // 新的空位在新页的第一格
                // 由于都重置为0,里面的文件,目录属性也应该是0
            }
        }
    }
    // 找找有没有同名的,同名抛弃
    int t;
    int *p=&t;
    if(LookUp(file,name,entry.start,entry.len,p).attribute!=0){// 找到同名
        fprintf(fp,"\n发现同名,创建失败,位置在%d字节处",t);
        return -1;
    }
    // 到这里没返回就找到一个空位了
    int piece1 = Give_Empty_Block(); // 找一个新块
    if(piece1==-1){  // 找不到
        fprintf(fp,"\n磁盘已满,无法创建");
        return -1;
    }else{
        Occupy_Block(file,piece1);   // 占用新块,刚找到的新块,就不看在不在了
        struct catalog_entry directory[1];// 新目录项
        directory[0] = Generate_Catalog_Entry(name,extend,attribute,piece1,1);// 创建的目录项
        fseek(file,position,SEEK_SET);    // 文件指针移动
        fwrite(directory,8,1,file); // 目录的保存
        return piece1;
    }
}



// 删除文件,成功返回1否则-1   文件名,目录
// 拒绝删除目录文件
int Delete(FILE* file,char* name,struct catalog_entry entry){
    int t;  // 字节位置
    int *p=&t;
    char k[1];
    struct catalog_entry directory[1]; // 读到的目录项
    directory[0] = LookUp(file,name,entry.start,entry.len,p);// 找位置
    if(directory[0].attribute == 0){    // 不存在
        fprintf(fp,"\n未找到删除对象");
        return -1;
    }else{
        if(directory[0].attribute == 1){
            fprintf(fp,"\n拒绝使用文件删除来删除目录");
            return -1;
        }
        k[0] = 0;
        directory[0].attribute = 0;
        fseek(file,t+5,SEEK_SET);    // 文件指针移动,将属性改为不存在
        fwrite(k,1,1,file); // 目录更改完毕
        Drop_Index(file,directory[0].start);    // 删除索引表链接,同时取消块占用
        // 这里不做空白目录页的删除(目录整理,由用户手动执行)
    }
    return 1;
}



// 建立目录 成功返回块号 否则-1 文件名,目录,套用创建文件,不过微改一点地方
int Makdir(FILE* file,char* name,struct catalog_entry entry){
    // 目录都包含当前目录.和父目录..  采用.=..表示根目录。
    char extend[2]={'\0','\0'};
    int t=Create(file,name,extend,entry,1);   // 生成目录
    if(t == -1){
        return -1;}
    struct catalog_entry root_directory[2];
    char name1[3]={'.','\0','\0'};
    int i;
    root_directory[0] = Generate_Catalog_Entry(name1,extend,1,t,1); // 当前目录
    name1[1] = '.';
    root_directory[1] = Generate_Catalog_Entry(name1,extend,1,entry.start,1); // 父目录
    fseek(file,64*t,SEEK_SET);    // 文件指针移动
    fwrite(root_directory,8,2,file);    // 保存两个特殊目录项
    // 占用块时,会格式化0,所以不用管后面的
    return t;
}



// 删除目录,成功返回1否则-1   目录名,目录
// 拒绝删除根目录,会递归调用自己,删除所有子目录和文件。
int Deldir(FILE* file,char* name,struct catalog_entry entry){
    int t,i,j,start;  // 字节位置
    int *p=&t;
    char k[1];
    struct catalog_entry directory[1]; // 读到的目录项
    struct catalog_entry directory8[8];
    directory[0] = LookUp(file,name,entry.start,entry.len,p);// 找位置
    if(directory[0].attribute == 0){    // 不存在
        fprintf(fp,"\n未找到删除对象");
        return -1;
    }else{
        if(directory[0].start==2){
            fprintf(fp,"\n试图删除根目录,请求遭到拒绝");
            return -1;
        }
        if(directory[0].attribute != 1){
            fprintf(fp,"\n拒绝使用目录删除来删除文件");
            return -1;
        }
        // 开始递归删除要删除目录的所有内容
        start = directory[0].start; // 要读取目录的块
        for(i=0;i<directory[0].len;i++){
            fseek(file,start*64,SEEK_SET);    // 指针准备读取目录内容
            fread(directory8,8,8,file);// 读取
            for(j=0;j<8;j++){// 遍历块,根据类型来递归删除目录或者文件
                if(directory8[j].attribute==1&&(i!=0||j>1)){
                // 递归删除目录,不递归特殊目录项,因为特殊目录项都在第一块前两个,所以看i,j就行
                    Deldir(file,directory8[j].name,directory[0]);
                }else{
                    if(directory8[j].attribute>1){// 递归删除文件
                        Delete(file,directory8[j].name,directory[0]);
                    }
                }
            }
            start = index_variables[start]; // 准备读取下一块
        }
        Drop_Index(file,directory[0].start);    // 删除索引表链接,同时取消块占用
        // 在当前目录删除要删除的目录项
        k[0] = 0;
        directory[0].attribute = 0;
        fseek(file,t+5,SEEK_SET);    // 文件指针移动,将属性改为不存在
        fwrite(k,1,1,file); // 目录更改完毕
        // 这里不做空白目录页的删除(目录整理,由用户手动执行)
    }
    return 1;

}



// 显示文件 给出目录项块号和长度,显示目录项所包含的文件(目录文件和文本文件)无返回
void Type(FILE* file,int start,int len){
    struct catalog_entry directory[8]; // 读取到的目录
    if(start==0){ // 空了,结束
        return ;
    }
    fseek(file,64*start,SEEK_SET);    // 文件指针移动
    fread(directory,8,8,file);// 读取
    int i;
    for(i=0;i<8;i++){
        if(directory[i].attribute!=0){// 这个东西存的有
            Printf_Entry(directory[i]); // 输出目录项
        }
    }
    Type(file,index_variables[start],len-1);
}


// 给出文件所在的目录和文件名,将字符数组的值赋值给文件,成功1,否则-1
// len单位:字节;可以直接用data的长度。这里会自动+1来带上\0,strlen(data)
int Edit(FILE* file,struct catalog_entry entry,char* name,char* data,int len){
    len++;// 怕64个的时候,没有\0终结
    int t;
    int *p = &t;
    struct catalog_entry directory=LookUp(file,name,entry.start,entry.len,p); // 获取文件目录项
    if(directory.attribute==0){
        fprintf(fp,"\n文件不存在");
        return -1;
    }
    float lenf = ((float)len)/64;    // 计算所需块数
    int leni = (int)lenf;
    leni = lenf - leni > 1e-3 ? (leni+1) : leni;    // 向上取整
    int i,j;
    char m[1];
    if(leni>directory.len){// 比原来长,加几块
        int iend = Index_End(directory.start);// 找到目录的末页
        for(i=directory.len+1;i<=leni;i++)
        {
            int piece = Give_Empty_Block(); // 给一个空块
            if(piece==-1){
                fprintf(fp,"\n磁盘已满");
                return-1;
            }
            Occupy_Block(file,piece);   // 占用新块,刚找到的新块,就不看在不在了
            index_variables[iend] = piece;    // 索引延申
            Save_Index(file,iend); // 改完索引要保存
            // 新增块了,文件长度需要+1
            fseek(file,t+7,SEEK_SET);    // 文件指针移动到文件的长度属性
            m[0]=i;
            fwrite(m,1,1,file);  // 改变
            iend = index_variables[iend];
        }
    }
    else{
        if(leni<directory.len){// 比原来短,去几块
            j = directory.start;
            for(i=0;i<leni-1;i++){
                j=index_variables[j];   // 一直找,直到找到需要删除的索引位置
            }
            Drop_Index(file,index_variables[j]); // 删除索引,解除占用
            index_variables[j] = 0; // 删除该索引
            Save_Index(file,j);    // 保存索引表
            fseek(file,t+7,SEEK_SET);
            m[0]=leni;
            fwrite(m,1,1,file);  // 改变
        }
    }
    t = directory.start;
    for(i=0;i<leni;i++){    // 开始赋新值
        fseek(file,t*64,SEEK_SET);
        if(i==leni-1){  // 最后一块,小心行事
            fwrite(&data[i*64],1,len-i*64-1,file);  // 改变
            m[0]='\0';
            fwrite(m,1,1,file);  // 改变
        }else{
            fwrite(&data[i*64],1,64,file);  // 改变
        }
        t = index_variables[t];
    }
}




// 拷贝文件,将文件拷贝到目录中(不支持目录文件拷贝)
// 返回拷贝的目录项成功,内核是创建一个同名文件,再赋值
struct catalog_entry Copy(FILE* file,struct catalog_entry document,struct catalog_entry entry){
    struct catalog_entry new_document;
    new_document.attribute = 0;
    if(document.attribute == 1){
        fprintf(fp,"\n禁止拷贝目录文件");
        return new_document;
    }
    if(document.attribute == 0){
        fprintf(fp,"\n被拷贝的文件不存在");
        return new_document;
    }
    int t = Create(file,document.name,document.extend,entry,document.attribute);
    if(t == -1){
        return new_document;
    }
    int i,j;
    int *p =&j;// 凑参数
    char data[64*document.len+1];   // 拷贝的文件内容
    data[64*document.len+1]='\0';   // 最后一个赋值
    j = document.start;
    for(i=0;i<document.len;i++){
        fseek(file,j*64,SEEK_SET);
        fread(&data[i*64],1,64,file);  // 读取
        j=index_variables[j];
    }
    Edit(file,entry,document.name,data,strlen(data));
    return LookUp(file,document.name,entry.start,entry.len,p);
}


// 读取文件存到char*
void Read_File(FILE* file,struct catalog_entry entry,char* data){
    int i,j;
    j = entry.start;
    for(i=0;i<entry.len;i++){
        fseek(file,j*64,SEEK_SET);
        fread(&data[i*64],1,64,file);  // 读取
        j=index_variables[j];
    }
}


// 移动文件,将文件移动到目录中(支持目录文件移动)
// 返回移动的目录项成功,内核是移动目录项到指定目录中
struct catalog_entry Move(FILE* file,struct catalog_entry directory,char* name,struct catalog_entry entry){
    int t;
    int *p = &t;
    int d;
    int *q=&d;
    char k[1]={0};
    struct catalog_entry document = LookUp(file,name,directory.start,directory.len,p);// 文件的目录项
    struct catalog_entry new_directory[1];// 新目录项
    new_directory[0] = document;
    if(new_directory[0].attribute == 0){
        fprintf(fp,"\n被移动的文件不存在");
        return document;
    }
    directory.attribute = 0;
    int position = Directory_Overrun(file,entry.start,entry.len);  // 找找空位
    if(position == -1){// 没找到空位
        if(entry.start == 2){   // 是根目录
            fprintf(fp,"\n根目录已满,无法移动");// 根目录只能有1页
            return document;
        }
        else{ // 否则可以新增一页
            int piece = Give_Empty_Block(); // 找一个新块
            if(piece==-1){  // 找不到
                fprintf(fp,"\n磁盘已满,无法移动");
                return document;
            }else{ // 新增一页
                int iend = Index_End(entry.start);// 找到目录的末页
                Occupy_Block(file,piece);   // 占用新块,刚找到的新块,就不看在不在了
                index_variables[iend] = piece;    // 索引延申
                Save_Index(file,iend); // 改完索引要保存
                // 新增页了,文件长度需要+1
                Directory_Length_Chenge(file,entry,1);
                position = piece*64;    // 新的空位在新页的第一格
                // 由于都重置为0,里面的文件,目录属性也应该是0
            }
        }
    }
    // 找找有没有同名的,同名抛弃
    if(LookUp(file,name,entry.start,entry.len,q).attribute!=0){// 找到同名
        fprintf(fp,"\n发现同名,移动失败,位置在%d字节处",t);
        return document;
    }
    // 到这里没返回就找到一个空位了
    fseek(file,t+5,SEEK_SET);    // 文件指针移动,将属性改为不存在
    fwrite(k,1,1,file); // 目录更改完毕
    fseek(file,position,SEEK_SET);    // 文件指针移动
    fwrite(new_directory,8,1,file); // 目录的保存
    if(new_directory[0].attribute == 1){ //目录还需要更改目录中的父目录项
        fseek(file,new_directory[0].start*64+8+5,SEEK_SET);    // 文件指针移动
        char a[3]={entry.attribute,entry.start,entry.len};
        fwrite(a,1,3,file); // 目录的保存
    }
    return new_directory[0];
}


// 更改文件扩展名,简单的寻找+赋值,完成1否则-1
int Alter(FILE* file,char* name,char* extend,struct catalog_entry entry)
{
    int t;
    int* p=&t;
    int a = LookUp(file,name,entry.start,entry.len,p).attribute;
    if(a==0){// 未找到
        fprintf(fp,"\n未找到要更改扩展名的文件");
        return -1;
    }
    if(a==1){// 未找到
        fprintf(fp,"\n不能更改目录的扩展名");
        return -1;
    }
    fseek(file,t+3,SEEK_SET);    // 文件指针移动
    fwrite(extend,1,2,file); // 目录的保存
}



// 更改文件属性,简单的寻找+赋值,完成1否则-1
int Change(FILE* file,char* name,int attribute,struct catalog_entry entry)
{
    if(attribute<2){
        fprintf(fp,"\n不被允许的文件属性取值:%d,需要大于等于2",attribute);
        return -1;
    }
    int t;
    int* p=&t;
    int a = LookUp(file,name,entry.start,entry.len,p).attribute;
    if(a==0){// 未找到
        fprintf(fp,"\n未找到要更改属性的文件");
        return -1;
    }
    if(a==1){// 未找到
        fprintf(fp,"\n不能更改目录的属性");
        return -1;
    }
    fseek(file,t+5,SEEK_SET);    // 文件指针移动
    char m[1]={attribute};
    fwrite(m,1,1,file); // 目录的保存
}


// python 调用的打开磁盘文件,返回文件指针
FILE* Openfile()
{
    file = fopen("disk.txt","r+");  //打开磁盘文件
    if(file == NULL)    // 磁盘文件不存在
    {
        Reset_Disk();// 重建磁盘文件
        file = fopen("disk.txt","r+");  //打开磁盘文件
    }
    return file;
}



// python 调用的关闭磁盘文件
void Closefile()
{
    fclose(file);
}


// c输出到文件
void Openfp()
{
    fp = fopen("output.txt","w");  //打开磁盘文件
}


// 关闭输出文件
void Closefp()
{
    fclose(fp);
}


// 索引表
char* Index_Variables()
{
    return index_variables;
}

// 位视图
union bit8* Bitwise_View()
{
    return bitwise_view;
}



// 递归得到目录所有项的列表
void Get_ALL_Entry(FILE* file,struct catalog_entry* entry,int start,int len,int t){
    if(start==0){ // 空了
        return;
    }
    fseek(file,64*start,SEEK_SET);    // 文件指针移动
    fread(&entry[t*8],8,8,file);  // 读取
    Get_ALL_Entry(file,entry,index_variables[start],len-1,t+1);
}



// 得到目录所有非空项的列表
void Get_Entry(FILE* file,struct catalog_entry* entry,int start,int len){
    struct catalog_entry directory[len*8];
    Get_ALL_Entry(file,directory,start,len,0);
    int i,j;
    j=0;
    for(i=0;i<len*8;i++){
        if(directory[i].attribute != 0){
            entry[j]=directory[i];
            j++;
        }
    }
}




/*
int main()
{

    file = fopen("disk.txt","r+");  //打开磁盘文件
    if(file == NULL)    // 磁盘文件不存在
    {
        Reset_Disk();// 重建磁盘文件
    }
    file = fopen("disk.txt","r+");  //打开磁盘文件
    {
        int i,j;
        int t;
        int *p=&t;
        Read_Start(file);// 读取位视图和索引表
        struct catalog_entry entry[8];
        fseek(file,64*2,SEEK_SET);    // 文件指针移动
        fread(entry,8,8,file);// 读取
        char name[3]={'a','\0','\0'};
        char name1[3]={'b','\0','\0'};
        char extend[2]={'x','y'};
        char data[500]={0};
        int len = 65;
        for(i=0;i<len;i++){
            data[i] = 'o';
        }
        data[len] = '\0';
        len = strlen(data);
        //Create(file,name1,extend,entry[0],2);// 保存
        //Delete(file,name,entry[0]);//删除
        //Catalog_Organization(file,entry[0]);//整理
        //Makdir(file,name,entry[0]);//建立目录
        //Deldir(file,name,entry[0]);//删除目录
        //Edit(file,entry[0],name1,data,len);// 修改文件
        //Copy(file,LookUp(file,name1,2,1,p),LookUp(file,name,2,1,p));// 拷贝文件


        //Create(file,name1,extend,entry[0],2);// 保存
        //Makdir(file,name,entry[0]);//建立目录
        //Edit(file,entry[0],name1,data,len);// 修改文件
        //Move(file,entry[0],name1,LookUp(file,name,2,1,p));// 拷贝文件
        Change(file,name1,3,entry[0]);

        //Copy(file,LookUp(file,name1,2,1,p),LookUp(file,name,2,1,p));// 拷贝文件

        //Delete(file,name1,entry[0]);//删除
        //Deldir(file,name,entry[0]);//删除目录

        Printf_Entry(LookUp(file,name,2,1,p));//查找
        Type(file,2,1); // 输出根目录

        Type(file,4,1);
        Printf_Bitwise_View();  // 输出位视图
        Printf_Index_variables();   // 输出索引表
    }
    fclose(file);
    file = NULL;
    return 0;
}
*/
// gcc Operating_System_C.c -shared -o Operating_System_C.dll

python语言部分

需要四张图片,

文件夹图标.png简易操作系统:使用Python 做的图形界面 C 做的内核

 可执行文件.png简易操作系统:使用Python 做的图形界面 C 做的内核

空文件夹.png简易操作系统:使用Python 做的图形界面 C 做的内核

文本文件.png简易操作系统:使用Python 做的图形界面 C 做的内核

不想要图片了删除代码中的读取文件

None_directory_image = tk.PhotoImage(file="空文件夹.png")  # 空文件夹图标
directory_image = tk.PhotoImage(file="文件夹图标.png")  # 文件夹图标
text_image = tk.PhotoImage(file="文本文件.png")  # 文本文件图标
executable_image = tk.PhotoImage(file="可执行文件.png")  # 可执行文件图标

Establish_Current_Directory_Bar的判断

if len(item[i]) > 1:  # 是目录
    if len(item[i][1]) > 0:
        now_image = directory_image  # 文件夹
    else:
        now_image = None_directory_image  # 空文件夹
elif item[i][0].extend == b'e':  # 是可执行文件
    now_image = executable_image
else:
    now_image = text_image  # 是文本文件

以及Establish_Current_Directory_Bar的使用(删除这个别忘了右括号不能删)

image=now_image)
import ctypes  # 用来调用c
import re  # 正则匹配用
import sys  # 输出重定向
import tkinter as tk  # gui用
import tkinter.messagebox  # 弹出来的对话框
import tkinter.filedialog  # 文件相关窗口
from tkinter import ttk  # 仅仅用到了树视图
import time  # 记录时间和线程睡眠用
from threading import Thread  # 进程


# 用于重定向输出到文本框
class Redirect:
    # Redirect(文本控件)
    def __init__(self, text):  # 构造函数
        self.text = text
        # 备份
        self.stdout = sys.stdout
        self.stderr = sys.stderr

    def write(self, data):
        self.text.insert('end', data)
        self.text.see(tk.END)
        self.text.update()  # 更新显示的文本

    def restoreStd(self):
        # 还原
        sys.stdout = self.stdout
        sys.stderr = self.stdout


# 读取C的输出
def Out_Put_C():
    try:
        # 读取文件内容
        with open('output.txt', 'r', encoding='utf-8') as f:
            print(f.read())
    except FileNotFoundError:
        print('文件 output.txt 不存在')


# 目录项结构体
class catalog_Entry(ctypes.Structure):
    _fields_ = [("name", ctypes.c_char * 3),
                ("extend", ctypes.c_char * 2),
                ("attribute", ctypes.c_ubyte),
                ("start", ctypes.c_ubyte),
                ("len", ctypes.c_ubyte), ]


# 从byte中取第bit位(从右数)
def Byte_Bit(byte, bit):
    # 原理:
    # 11001000 & 00001000
    if byte & (1 << bit):
        return 1
    else:
        return 0


# 创建文件编辑窗口
def File_Editing(entry, directory, name):
    def Close_Callback():  # 关闭的回调函数
        user_interface_bar.input_entry['state'] = 'normal'  # 启用用户输入
        edit_window.destroy()  # 销毁窗口

    def Save_File():  # 保存+关闭
        content = edit_window.text.get('1.0', 'end-1c')  # 读取全部文本,不加-1末尾会多一个回车
        data = ctypes.c_char_p(content.encode())
        new_data = ctypes.cast(data, ctypes.POINTER(ctypes.c_char * len(content))).contents
        Operating_System_C.Edit(file, entry, name, new_data, ctypes.c_int(len(content)))
        # 保存数据
        Change_Disk_Bar()  # 位视图索引表更新
        Change_Current_Directory_Bar()  # 目录更新
        Close_Callback()

    # 已经判断过是文件了
    # Operating_System_C.Read_File(file,entry,char* data) # 读取文件内容
    edit_window = tk.Toplevel(main_window)  # 生成编辑窗口
    edit_window.title("文件编辑")
    edit_window.geometry("400x200")
    user_interface_bar.input_entry['state'] = 'disabled'  # 禁用用户输入
    edit_window.protocol("WM_DELETE_WINDOW", Close_Callback)  # 绑定关闭回调
    edit_window.scrollbar = tk.Scrollbar(edit_window, orient=tk.VERTICAL)  # 滚动条y
    edit_window.text = tk.Text(edit_window, yscrollcommand=edit_window.scrollbar.set, )  # 用户文本框
    edit_window.text.bind("<Control-s>", lambda g: Save_File())  # Ctrl+s回调
    data = (ctypes.c_char * (directory.len * 64 + 1))()
    Operating_System_C.Read_File(file, directory, data)  # 读取文件
    edit_window.text.insert('end', data.value.decode())
    edit_window.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满y
    edit_window.scrollbar.config(command=edit_window.text.yview)
    edit_window.text.pack(fill=tk.BOTH, expand=1)
    menubar = tk.Menu(edit_window)  # 菜单栏
    # 文件菜单是菜单栏的子菜单,且不能窗口化
    submenu_file = tk.Menu(menubar, tearoff=False)
    submenu_file.add_command(label='保存文件', command=Save_File)
    submenu_file.add_separator()  # 分割线
    submenu_file.add_command(label='关闭', command=Close_Callback)  # command为要调用的函数
    menubar.add_cascade(label='文件', menu=submenu_file)  # 菜单添加文件子菜单项
    edit_window.config(menu=menubar)  # 生成菜单栏,窗口与菜单关联
    pass


# 创建文件运行窗口
def Run_File(entry, way, directory):
    def Close_Callback():  # 关闭的回调函数
        run_window.destroy()  # 销毁窗口

    def Save_X(x, directory):
        # 从后往前按最后一个/分割一次
        route = directory.rsplit('/', 1)
        if not len(route) == 2:  # 如果长度不是2
            tkinter.messagebox.showerror('程序运行发生错误', "输出路径'" + directory + "'错误\n")
            Close_Callback()
            return
        entry = Get_Route(route[0])  # 目录
        dir = Get_Route(directory)  # 文件的目录项
        if not entry.attribute == 1 or dir.attribute < 2:
            tkinter.messagebox.showerror('程序运行发生错误', "输出路径'" + directory + "'错误\n", )
            Close_Callback()
            return
        name = (ctypes.c_char * 3)()
        # 将Python字符串赋值给数组
        String_C_char(name, route[1], 3)
        content = way + '  x=' + str(x.get())
        out_str = ctypes.c_char_p(content.encode())
        out_str = ctypes.cast(out_str, ctypes.POINTER(ctypes.c_char * len(content))).contents
        Operating_System_C.Edit(file, entry, name, out_str, ctypes.c_int(len(content)))
        # 保存数据
        Change_Disk_Bar()  # 位视图索引表更新
        Change_Current_Directory_Bar()  # 目录更新
        tkinter.messagebox.showinfo("文件保存完成", "代码的输出已经保存到" + way, )
        Close_Callback()

    def Get_Row(current_row):  # 返回下一行文本
        try:
            row_str = data_bar.text.get(f"{current_row[0]}.0", f"{current_row[0]}.end")  # 获得一行文本
            current_row[0] += 1  # 下次找下一行
            current_instruction.set(row_str)  # 文本赋值
        except:
            row_str = ""
        return row_str  # 返回文本

    def Execute(str):
        # 正则表达式,来匹配输入是不是要求的五种之一
        pattern = [r'^x=(-?\d+);', r'^x([+]){2};', r'^x([-]){2};', r"!([ABC])(\d+|x);", r'^end\.$']
        match = re.match(pattern[0], str)
        if match:  # x=?
            num = int(match.group(1))  # 得到数字部分
            x.set(num)  # 赋值
            return [0]
        elif re.match(pattern[1], str):  # x++
            x.set(x.get() + 1)  # 赋值
            return [1]
        elif re.match(pattern[2], str):  # x--
            x.set(x.get() - 1)  # 赋值
            return [2]
        else:
            match = re.match(pattern[3], str)
            if match:  # !??
                letter = match.group(1)
                number = match.group(2)
                number1 = re.match(r"^\d+$", number)  # 判断是不是正整数
                if number1:
                    return [3, letter, int(number)]  # 是正整数
                else:
                    return [3, letter, x.get()]  # 不是正整数

            elif re.match(pattern[4], str):  # end.
                return [4]
            else:  # 未匹配
                return [-1]

    def working():
        while 1:
            row_str = Get_Row(current_row)
            if row_str == "" or row_str is None:
                break
            mate = Execute(row_str)
            if mate[0] == -1:
                # 报错+回调关闭
                tkinter.messagebox.showerror('程序运行发生错误', "代码'" + row_str + "'匹配错误\n", )
                Close_Callback()
                break
            if mate[0] == 3:  # 使用机子并等待使用完毕
                for i in range(101):  # 相当于100秒
                    if i == 100:
                        # 报错+回调关闭
                        tkinter.messagebox.showerror('程序运行等待超时', "等待" + str(mate[1]) + "超时", )
                        Close_Callback()
                        break
                    if device[str(mate[1])].get() == 0:  # 没有被占用
                        # 使用设备
                        using_devices = Thread(target=lambda d=mate[1], t=mate[2]: Change_device_time(d, t))
                        device[str(mate[1])].set(mate[2])
                        using_devices.start()
                        using_devices.join()  # 等待运行结束操作系统阻塞展示
                        break
                    time.sleep(1)
            if mate[0] == 4:  # 运行完毕
                Save_X(x, directory)
            time.sleep(1)

    current_row = [1]
    run_window = tk.Toplevel(main_window)  # 生成运行窗口========================================================
    run_window.title("文件运行")
    run_window.geometry("600x400")
    run_window.rowconfigure(0, weight=1, minsize=100)  # row为0,缩放比为1
    run_window.rowconfigure(1, weight=1, minsize=100)  # row为1,缩放比为1
    run_window.rowconfigure(2, weight=1, minsize=100)  # row为2,缩放比为1
    run_window.columnconfigure(0, weight=1, minsize=300)  # column为0,缩放比为1
    run_window.columnconfigure(1, weight=1, minsize=200)  # column为1,缩放比为1
    data_bar = tk.LabelFrame(run_window, text="文件已加载")  # 文件显示框架========================================
    data_bar.grid(row=0, column=0, rowspan=3)  # 三行
    data_bar.scrollbar = tk.Scrollbar(data_bar, orient=tk.VERTICAL)  # 滚动条y
    data_bar.text = tk.Text(data_bar, yscrollcommand=data_bar.scrollbar.set)
    data_bar.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满y
    data_bar.scrollbar.config(command=data_bar.text.yview)
    data_bar.text.bind('<Key>', "break")
    data_bar.text.pack(fill=tk.BOTH)
    data = (ctypes.c_char * (entry.len * 64 + 1))()
    Operating_System_C.Read_File(file, entry, data)  # 读取文件
    data_bar.text.insert('end', data.value.decode())
    current_instruction_bar = tk.LabelFrame(run_window, text="当前指令")  # 当前指令框架===========================
    current_instruction_bar.grid(row=0, column=1)
    current_instruction = tk.StringVar()
    current_instruction.set("")
    current_instruction_bar.entry = tk.Entry(current_instruction_bar, exportselection=0, borderwidth=3,
                                             textvariable=current_instruction, relief='sunken')  # 当前指令文本框
    current_instruction_bar.entry.bind('<Key>', "break")
    current_instruction_bar.entry.pack(fill=tk.BOTH)
    x_price_bar = tk.LabelFrame(run_window, text="x的值")  # x的值框架============================================
    x_price_bar.grid(row=1, column=1)
    x = tk.IntVar()
    x.set(0)
    x_price_bar.entry = tk.Entry(x_price_bar, exportselection=0, borderwidth=3,
                                 textvariable=x, relief='sunken')  # x的值文本框
    x_price_bar.entry.bind('<Key>', "break")
    x_price_bar.entry.pack(fill=tk.BOTH)
    device_bar = tk.LabelFrame(run_window, text="设备")  # 当前设备框架============================================
    device_bar.grid(row=2, column=1)
    lable_A = tk.Label(device_bar, text="A")  # A标签
    lable_B = tk.Label(device_bar, text="B")  # B标签
    lable_C = tk.Label(device_bar, text="C")  # C标签
    device_A = tk.Entry(device_bar, textvariable=device["A"], relief='sunken')  # A的值文本框
    device_B = tk.Entry(device_bar, textvariable=device["B"], relief='sunken')  # B的值文本框
    device_C = tk.Entry(device_bar, textvariable=device["C"], relief='sunken')  # C的值文本框
    device_bar.rowconfigure(0, weight=1, minsize=10)
    device_bar.rowconfigure(1, weight=1, minsize=10)
    device_bar.columnconfigure(0, weight=1, minsize=30)  # column为0,缩放比为1
    device_bar.columnconfigure(1, weight=1, minsize=30)  # column为1,缩放比为1
    device_bar.columnconfigure(2, weight=1, minsize=30)  # column为2,缩放比为1
    device_A.bind('<Key>', "break")
    device_B.bind('<Key>', "break")
    device_C.bind('<Key>', "break")
    lable_A.grid(row=0, column=0)
    lable_B.grid(row=0, column=1)
    lable_C.grid(row=0, column=2)
    device_A.grid(row=1, column=0)
    device_B.grid(row=1, column=1)
    device_C.grid(row=1, column=2)
    working()


# 根据路径获得目录项
def Get_Route(str_in):
    entry = catalog_Entry()
    route = str_in.split("/")  # 按 / 分离
    if route[0] == '..':  # 父目录
        entry = user_interface_bar.up_entry.entry
    elif route[0] == '.':  # 当前目录
        entry = user_interface_bar.now_entry.entry
    else:
        if not route[0] == 'S':  # 初始不是根目录
            print("  格式错误,文件路径的表示: S 是根目录,S/A 是根目录下的文件或目录A, S/A/B 是根目录下的目录A中的B")
            entry.attribute = 0  # 不存在
            return entry
        entry.name = b'S'  # 根目录
        entry.start = 2
        entry.len = 1
        entry.attribute = 1

    t = ctypes.c_int()
    p = ctypes.pointer(t)
    for i in route[1:]:
        data = ctypes.c_char_p(i.encode())
        name = ctypes.cast(data, ctypes.POINTER(ctypes.c_char * len(i))).contents
        entry = Operating_System_C.LookUp(file, name, entry.start, entry.len, p)
    return entry


# 将str前l个给char(python 字符串给C字符串)
def String_C_char(char, str, l):
    for i in range(l):
        if i >= len(str):
            char[i] = b'\0'
            break
        char[i] = str[i].encode()


# 提示
def Prompt(word):
    print("    输入‘提示’了解更多,输入‘help’了解支持的函数。\n"
          "    左上角是位视图和索引表,颜色是绿色表示未占用,蓝色表示占用,上面的数字表示下一位的索引\n"
          "    右上角是是树形目录结构,修改目录结构后会更新\n"
          "    中间是当前目录和父目录,根目录时相同,可使用 . 和 .. 表示\n"
          "    文件路径的表示: S 是根目录,S/A 是根目录下的文件或目录A, S/A/B 是根目录下的目录A中的B"
          ""
          )


# 帮助
def Help(word):
    print(
        "支持的输入:\n"
        "-----------------------------------------\n"
        "提示\n"
        "help\n"
        "Printf_Bitwise_View-------------输出位视图\n"
        "Printf_Index_variables----------输出索引阵列\n"
        "Printf_Entry 路径----------------输出目录\n"
        "Catalog_Organization 路径--------目录整理\n"
        "Reset_Disk----------------------重建磁盘\n"
        "Create 目录路径 文件名 扩展名------创建文件\n"
        "Delete 路径----------------------删除文件\n"
        "Makdir 目录路径 目录名-------------建立目录\n"
        "Deldir 目录路径-------------------删除目录\n"
        "Type 路径------------------------显示文件\n"
        "Edit 路径------------------------修改文件\n"
        "Copy 文件路径 目标目录路径---------拷贝文件\n"
        "Move 文件路径 目标目录路径---------移动文件或目录\n"
        "Change 文件路径 属性--------------更改文件属性\n"
        "Alter 文件路径 扩展名-------------更改文件扩展名\n"
        "Run 文件路径 结果输出路径----------执行文件\n"
        "CD 路径--------------------------前往目录\n"
        "Release 设备名-------------------强行释放设备\n"
    )


# Printf_Bitwise_View-------------输出位视图
def Printf_Bitwise_View(word):
    if len(word) > 1:
        print(" ".join(word[1:]), "是多余的参数\n")
        print("函数用法:Printf_Bitwise_View-------------输出位视图")
        return
    Operating_System_C.Printf_Bitwise_View()


# Printf_Index_variables----------输出索引阵列
def Printf_Index_variables(word):
    if len(word) > 1:
        print(" ".join(word[1:]), "是多余的参数\n")
        print("函数用法:Printf_Index_variables----------输出索引阵列")
        return
    Operating_System_C.Printf_Index_variables()


# Printf_Entry 路径----------------输出目录
def Printf_Entry(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Printf_Entry 路径----------------输出目录")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Printf_Entry 路径----------------输出目录")
        return
    entry = Get_Route(word[1])
    Operating_System_C.Printf_Entry(entry)


# Catalog_Organization 路径--------目录整理
def Catalog_Organization(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Catalog_Organization 路径--------目录整理")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Catalog_Organization 路径--------目录整理")
        return
    entry = Get_Route(word[1])
    if not entry.attribute == 1:  # 不是目录
        print("路径不是目录")
        return
    Operating_System_C.Catalog_Organization(file, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Reset_Disk----------------------重建磁盘
def Reset_Disk(word):
    if len(word) > 1:
        print(" ".join(word[1:]), "是多余的参数\n")
        print("函数用法:Reset_Disk----------------------重建磁盘")
        return
    Operating_System_C.Reset_Disk()
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Create 目录路径 文件名 扩展名------创建文件
def Create(word):
    if len(word) > 4:
        print(" ".join(word[4:]), "是多余的参数\n")
        print("函数用法:Create 目录路径 文件名 扩展名------创建文件")
        return
    if len(word) < 4:
        print("参数过少")
        print("函数用法:Create 目录路径 文件名 扩展名------创建文件")
        return
    entry = Get_Route(word[1])
    if not entry.attribute == 1:
        print("路径错误")
        return
    # 将Python字符串赋值给数组
    name = (ctypes.c_char * 3)()
    String_C_char(name, word[2], 3)
    extend = (ctypes.c_char * 2)()
    String_C_char(extend, word[3], 2)
    Operating_System_C.Create(file, name, extend, entry, ctypes.c_char(2))
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Delete 路径----------------------删除文件
def Delete(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Delete 路径----------------------删除文件")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Delete 路径----------------------删除文件")
        return
    # 从后往前按最后一个/分割一次
    route = word[1].rsplit('/', 1)
    if not len(route) == 2:  # 如果长度不是2
        print("路径错误")
        return
    entry = Get_Route(route[0])  # 目录
    if not entry.attribute == 1:
        print("路径错误")
        return

    # 将Python字符串赋值给数组
    name = (ctypes.c_char * 3)()
    String_C_char(name, route[1], 3)
    # c中会拒绝删除目录
    Operating_System_C.Delete(file, name, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Makdir 目录路径 目录名-------------建立目录
def Makdir(word):
    if len(word) > 3:
        print(" ".join(word[3:]), "是多余的参数\n")
        print("函数用法:Makdir 目录路径 目录名-------------建立目录")
        return
    if len(word) < 3:
        print("参数过少")
        print("函数用法:Makdir 目录路径 目录名-------------建立目录")
        return
    entry = Get_Route(word[1])
    if not entry.attribute == 1:
        print("路径错误")
        return
    name = (ctypes.c_char * 3)()
    # 将Python字符串赋值给数组
    String_C_char(name, word[2], 3)
    Operating_System_C.Makdir(file, name, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Deldir 目录路径-------------------删除目录
def Deldir(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Deldir 目录路径-------------------删除目录")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Deldir 目录路径-------------------删除目录")
        return
    # 从后往前按最后一个/分割一次
    route = word[1].rsplit('/', 1)
    if not len(route) == 2:  # 如果长度不是2
        print("路径错误")
        return
    entry = Get_Route(route[0])  # 目录
    if not entry.attribute == 1:
        print("路径错误")
        return
    name = (ctypes.c_char * 3)()
    # 将Python字符串赋值给数组
    String_C_char(name, route[1], 3)
    Operating_System_C.Deldir(file, name, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Type 路径------------------------显示文件
def Type(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Type 路径------------------------显示文件")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Type 路径------------------------显示文件")
        return
    entry = Get_Route(word[1])
    if not entry.attribute == 1:  # 不是目录
        print("路径不是目录")
        return
    Operating_System_C.Type(file, entry.start, entry.len)
    pass


# Edit 路径------------------------修改文件
def Edit(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Edit 路径------------------------修改文件")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Edit 路径------------------------修改文件")
        return
    # 从后往前按最后一个/分割一次
    route = word[1].rsplit('/', 1)
    if not len(route) == 2:  # 如果长度不是2
        print("路径错误")
        return
    entry = Get_Route(route[0])  # 目录
    directory = Get_Route(word[1])  # 文件的目录项
    if not entry.attribute == 1 or directory.attribute < 2:
        print("路径错误")
        return
    name = (ctypes.c_char * 3)()
    # 将Python字符串赋值给数组
    String_C_char(name, route[1], 3)
    File_Editing(entry, directory, name)  # 创建文件编辑窗口


# Copy 文件路径 目标目录路径---------拷贝文件
def Copy(word):
    if len(word) > 3:
        print(" ".join(word[3:]), "是多余的参数\n")
        print("函数用法:Copy 文件路径 目标目录路径---------拷贝文件")
        return
    if len(word) < 3:
        print("参数过少")
        print("函数用法:Copy 文件路径 目标目录路径---------拷贝文件")
        return
    document = Get_Route(word[1])  # 文件的目录项
    entry = Get_Route(word[2])  # 目标目录
    if not entry.attribute == 1:
        print("路径错误")
        return
    Operating_System_C.Copy(file, document, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Move 文件路径 目标目录路径---------移动文件或目录
def Move(word):
    if len(word) > 3:
        print(" ".join(word[3:]), "是多余的参数\n")
        print("函数用法:Move 文件路径 目标目录路径---------移动文件或目录")
        return
    if len(word) < 3:
        print("参数过少")
        print("函数用法:Move 文件路径 目标目录路径---------移动文件或目录")
        return
    route = word[1].rsplit('/', 1)
    if not len(route) == 2:  # 如果长度不是2
        print("路径错误")
        return
    directory = Get_Route(route[0])  # 目录
    if not directory.attribute == 1:
        print("路径错误")
        return
    name = (ctypes.c_char * 3)()
    # 将Python字符串赋值给数组
    String_C_char(name, route[1], 3)
    entry = Get_Route(word[2])  # 目标目录
    if not entry.attribute == 1:
        print("路径错误")
        return
    Operating_System_C.Move(file, directory, name, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Change 文件路径 属性--------------更改文件属性
def Change(word):
    if len(word) > 3:
        print(" ".join(word[3:]), "是多余的参数\n")
        print("函数用法:Change 文件路径 属性--------------更改文件属性")
        return
    if len(word) < 3:
        print("参数过少")
        print("函数用法:Change 文件路径 属性--------------更改文件属性")
        return
    # 从后往前按最后一个/分割一次
    route = word[1].rsplit('/', 1)
    if not len(route) == 2:  # 如果长度不是2
        print("路径错误")
        return
    entry = Get_Route(route[0])  # 目录
    if not entry.attribute == 1:
        print("路径错误")
        return
    name = (ctypes.c_char * 3)()
    # 将Python字符串赋值给数组
    String_C_char(name, route[1], 3)
    try:
        attribute = int(word[2])
    except:
        print("属性的值存在问题,属性只能是大于1的正整数")
        return
    Operating_System_C.Change(file, name, attribute, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Alter 文件路径 扩展名-------------更改文件扩展名
def Alter(word):
    if len(word) > 3:
        print(" ".join(word[3:]), "是多余的参数\n")
        print("函数用法:Alter 文件路径 扩展名-------------更改文件扩展名")
        return
    if len(word) < 3:
        print("参数过少")
        print("函数用法:Alter 文件路径 扩展名-------------更改文件扩展名")
        return
    # 从后往前按最后一个/分割一次
    route = word[1].rsplit('/', 1)
    if not len(route) == 2:  # 如果长度不是2
        print("路径错误")
        return
    entry = Get_Route(route[0])  # 目录
    if not entry.attribute == 1:
        print("路径错误")
        return
    name = (ctypes.c_char * 3)()
    # 将Python字符串赋值给数组
    String_C_char(name, route[1], 3)
    extend = (ctypes.c_char * 2)()
    String_C_char(extend, word[2], 2)
    Operating_System_C.Alter(file, name, extend, entry)
    Change_Disk_Bar()  # 位视图索引表更新
    Change_Current_Directory_Bar()  # 目录更新


# Run 文件路径 结果输出路径----------执行文件
def Run(word):
    if len(word) > 3:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Run 文件路径 结果输出路径----------执行文件")
        return
    if len(word) < 3:
        print("参数过少")
        print("函数用法:Run 文件路径 结果输出路径----------执行文件")
        return
    entry = Get_Route(word[1])
    if entry.attribute < 2 or not entry.extend == b'e':  # 不是文件
        print("不是可执行文件")
        return
    directory = word[2]
    # 创建线程
    run_file_thread = Thread(
        target=lambda entry=entry, way=word[1], directory=directory: Run_File(entry, way, directory))
    # 运行文件
    run_file_thread.start()
    pass


# CD 路径--------------------------前往目录
def CD(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:CD 路径--------------------------前往目录")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:CD 路径--------------------------前往目录")
        return
    route = word[1].split("/")
    if route[0] == '..':  # 父目录
        str_in = user_interface_bar.up_entry.get() + word[1][2:]
    elif route[0] == '.':  # 当前目录
        str_in = user_interface_bar.now_entry.get() + word[1][1:]
    else:
        str_in = word[1]
    entry = Get_Route(str_in)  # 目标目录
    if not entry.attribute == 1:
        print("路径错误")
        return
    route = str_in.rsplit('/', 1)
    user_interface_bar.now_entry.set(str_in)
    user_interface_bar.now_entry.entry = entry
    user_interface_bar.up_entry.set(route[0])
    user_interface_bar.up_entry.entry = Get_Route(route[0])


# Release 设备名-------------------释放设备
def Release(word):
    if len(word) > 2:
        print(" ".join(word[2:]), "是多余的参数\n")
        print("函数用法:Release 设备名-------------------强行释放设备")
        return
    if len(word) < 2:
        print("参数过少")
        print("函数用法:Release 设备名-------------------强行释放设备")
        return
    if word[1] == 'A' or word[1] == 'B' or word[1] == 'C':
        device[word[1]].set(0)
    else:
        print(word[1], '设备不存在')


# 用于线程的设备到时归0
def Change_device_time(d, t):
    for i in range(t):
        if device[d].get() <= 0:  # 被强制结束了
            device[d].set(0)
            break
        time.sleep(1)  # 睡一下
        device[d].set(device[d].get() - 1)  # 减一下


def Function_Selection(word):
    if len(word) == 0:  # 没有输入
        return
    if word[0] in user_function:  # 输入的是函数
        user_function[word[0]](word)
    else:
        print(word[0], "不是可行的函数,请使用 help 查询可用函数")


# 分析用户输入
def Input_Analysis(user_input):
    word = user_input.split()  # 按空格分离
    print('>>>', " ".join(word))  # 输出你的输入
    Function_Selection(word)  # 按输入选择函数


# 输入框回车的执行内容
def Execute(event):
    user_input = user_interface_bar.input.get()  # 用户输入
    user_interface_bar.input.set("")  # 清空输入
    if len(user_input) > 0:
        if len(old_input[0]) > 20:  # 最多存20条
            old_input[0].pop()
        old_input[0].insert(0, user_input[:])
        old_input[1] = -1
    Operating_System_C.Openfp()  # c语言打开c的输出文件
    # 分析用户输入
    Input_Analysis(user_input)
    Operating_System_C.Closefp()  # c语言关闭c的输出文件
    Out_Put_C()  # python读取并输出C的输出
    pass


def Tab_input(event):
    now_input = user_interface_bar.input.get()  # 获得当前输入
    now_input = now_input.split()  # 按空格分离
    if not len(now_input) == 1:  # 不是长度为1,没反应
        return 'break'
    matched = []  # 匹配到的键
    for key in user_function:  # 遍历所有键
        if key.startswith(now_input[0]):
            matched.append(key)
    if len(matched) < 1:
        return 'break'
    elif len(matched) == 1:
        user_interface_bar.input.set(matched[0])  # 赋值
        # 将插入点设置为最后一个字符的位置
        user_interface_bar.input_entry.icursor(tk.END)
    else:
        print(matched)
    return 'break'

# 按下上键
def Up_input(event):
    if old_input[1] + 1 >= len(old_input[0]):  # 到头了
        return "break"  # 已经是最后的了,不动
    old_input[1] += 1
    user_interface_bar.input.set(old_input[0][old_input[1]])  # 赋值、
    # 将插入点设置为最后一个字符的位置
    user_interface_bar.input_entry.icursor(tk.END)


# 按下下键
def Down_input(event):
    if old_input[1] < 1:
        return "break"  # 已经是最后的了,不动
    old_input[1] -= 1
    user_interface_bar.input.set(old_input[0][old_input[1]])  # 赋值
    # 将插入点设置为最后一个字符的位置
    user_interface_bar.input_entry.icursor(tk.END)


# 更新磁盘框架的内容
def Change_Disk_Bar():
    for i in range(8):
        for j in range(16):
            disk_bar.index_variables[i * 16 + j].set('[' + str(index_variables[i * 16 + j]) + ']')
            disk_bar.label[i * 16 + j]['bg'] = 'blue' if Byte_Bit(bitwise_view[(i * 16 + j) // 8],
                                                                  7 - (i * 16 + j) % 8) else 'green',


# 生成磁盘框架的内容
def Generate_Disk_Bar():
    # 128个块,128个标签。
    for j in range(16):
        disk_bar.columnconfigure(j, weight=5)  # column为j,缩放比为1
    for i in range(8):
        disk_bar.rowconfigure(i, weight=1)  # row为i,缩放比为1
        for j in range(16):
            disk_bar.index_variables.append(tk.StringVar())
            disk_bar.index_variables[i * 16 + j].set('[' + str(index_variables[i * 16 + j]) + ']')
            # 父窗口, 文本内容关联的变量, fg 文字颜色, bg 背景颜色,borderwidth 边框大小,ridge 边框样式
            disk_bar.label.append(tk.Label(disk_bar, textvariable=disk_bar.index_variables[i * 16 + j],
                                           fg='white', bg='blue' if Byte_Bit(bitwise_view[(i * 16 + j) // 8],
                                                                             7 - (i * 16 + j) % 8) else 'green',
                                           borderwidth=5, relief='ridge'))
            disk_bar.label[i * 16 + j].grid(row=i, column=j, padx=1, pady=1)


# 获取当前的目录
def Obtain_Current_Directory_Bar(updict, start, len):
    directory = (catalog_Entry * (len * 8))()  # 目录大小
    Operating_System_C.Get_Entry(file, directory, start, len)  # 获取目录
    for i in range(2, len * 8):  # 不看父目录和当前目录(前两个)
        if directory[i].attribute == 0:  # 空了
            break
        updict[directory[i].name] = [directory[i]]
        if directory[i].attribute == 1:  # 是目录
            updict[directory[i].name].append({})
            Obtain_Current_Directory_Bar(updict[directory[i].name][1], directory[i].start, directory[i].len)


# 按item建立新树图
def Establish_Current_Directory_Bar(item, uptree):
    for i in item:
        if len(item[i]) > 1:  # 是目录
            if len(item[i][1]) > 0:
                now_image = directory_image  # 文件夹
            else:
                now_image = None_directory_image  # 空文件夹
        elif item[i][0].extend == b'e':  # 是可执行文件
            now_image = executable_image
        else:
            now_image = text_image  # 是文本文件
        now_tree = current_directory_bar.treeview.insert(uptree, tk.END, text=item[i][0].name,
                                                         values=(
                                                             item[i][0].name, item[i][0].extend, item[i][0].attribute,
                                                             item[i][0].start, item[i][0].len,),
                                                         image=now_image)
        if len(item[i]) > 1:  # 长度大于1是目录
            Establish_Current_Directory_Bar(item[i][1], now_tree)
    pass


# 更新当前目录框架的内容,时间有限,暴力更新,
def Change_Current_Directory_Bar():
    current_directory_bar.item.clear()  # 空置
    Obtain_Current_Directory_Bar(current_directory_bar.item, 2, 1)  # 获得当前的数据
    current_directory_bar.treeview.delete(*current_directory_bar.treeview.get_children())  # 清空之前的所有树图
    current_directory_bar.treeview.update()  # 刷新显示
    Establish_Current_Directory_Bar(current_directory_bar.item, "")  # 递归建立新树


# 生成当前目录框架的内容
def Generate_Current_Directory_Bar():
    # 创建style对象
    style = ttk.Style()
    # 设置文本大小
    style.configure("Treeview", font=("Arial", 12), rowheight=30)
    # 创建滚动条
    current_directory_bar.scrollbar_x = tk.Scrollbar(current_directory_bar, orient=tk.HORIZONTAL)  # 滚动条x
    current_directory_bar.scrollbar_y = tk.Scrollbar(current_directory_bar, orient=tk.VERTICAL)  # 滚动条y
    # 创建树视图,带滚动条,带标签
    current_directory_bar.treeview = ttk.Treeview(current_directory_bar, show="tree headings", displaycolumns="#all",
                                                  columns=('name', 'extend', 'attribute', 'start', 'len'),
                                                  xscrollcommand=current_directory_bar.scrollbar_x.set,
                                                  yscrollcommand=current_directory_bar.scrollbar_y.set,
                                                  style="Treeview")
    # column设定列宽,heading设定标题
    current_directory_bar.treeview.column("#0", width=100)
    current_directory_bar.treeview.heading("#0", text="目录")
    current_directory_bar.treeview.column("name", width=60)
    current_directory_bar.treeview.heading('name', text="名称")
    current_directory_bar.treeview.column("extend", width=60)
    current_directory_bar.treeview.heading('extend', text="扩展名")
    current_directory_bar.treeview.column("attribute", width=50)
    current_directory_bar.treeview.heading('attribute', text="属性")
    current_directory_bar.treeview.column("start", width=50)
    current_directory_bar.treeview.heading('start', text="起始块")
    current_directory_bar.treeview.column("len", width=50)
    current_directory_bar.treeview.heading('len', text="长度")
    # 将他们显示出来
    current_directory_bar.scrollbar_x.pack(side=tk.BOTTOM, fill=tk.X)  # 靠下,拉满x
    current_directory_bar.scrollbar_x.config(command=current_directory_bar.treeview.xview)
    current_directory_bar.scrollbar_y.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满y
    current_directory_bar.scrollbar_y.config(command=current_directory_bar.treeview.yview)
    # 居中,填充
    current_directory_bar.treeview.pack(fill=tk.BOTH, expand=1)
    # 调用更新树图
    Change_Current_Directory_Bar()


# 初始化c的函数返回值
def Initialization_Operating_System_C():
    # 默认c_int
    # file 4字节,其他的几个1字节
    Operating_System_C.Generate_Catalog_Entry.restype = catalog_Entry
    Operating_System_C.LookUp.restype = catalog_Entry
    Operating_System_C.Move.restype = catalog_Entry
    Operating_System_C.Openfile.restype = ctypes.POINTER(ctypes.c_uint)  # 声明函数返回值为指针
    Operating_System_C.Index_Variables.restype = ctypes.POINTER(ctypes.c_ubyte)
    Operating_System_C.Bitwise_View.restype = ctypes.POINTER(ctypes.c_ubyte)


def Get_Menu(event):
    try:
        menu.tk_popup(event.x_root, event.y_root, 0)
    finally:
        # 确保在任何情况下都能隐藏菜单
        menu.grab_release()


# 拦截输入
def Intercept_Input(event):
    if event.keycode != 67 and event.state != 4:  # 67代表复制快捷键,state=4表示按下Ctrl键
        return "break"  # 如果不是复制快捷键,就拦截事件


'''
┏┓┃┫┣┳┻╋━┗┛
┏━━━━━━━━━━┳━━━━━━━━━━┓
┃ 位视图和  ┃  目录内容 ┃
┃  索引表   ┃          ┃
┣━━━━━━━━━━╋━━━━━━━━━━┫
┃  当前目录 ┃ 上级目录  ┃
┣━━━━━━━━━━┻━━━━━━━━━━┫
┃       用户接口       ┃
┗━━━━━━━━━━━━━━━━━━━━━┛
'''

# 加载用C写的函数
Operating_System_C = ctypes.cdll.LoadLibrary('./Operating_System_C.dll')
Operating_System_C.Openfp()  # c语言打开c的输出文件
Initialization_Operating_System_C()  # 初始化返回值
file = Operating_System_C.Openfile()  # 读取文件,获得文件指针,没有文件会创建
Operating_System_C.Read_Start(file)  # 读取位视图和索引表
index_variables = Operating_System_C.Index_Variables()  # 获得位视图和索引表的指针
bitwise_view = Operating_System_C.Bitwise_View()
old_input = [[], -1]  # 以前的输入
open("output.txt", 'w').close()  # 清空以前的输入
user_function = {  # 用户函数表
    "提示": Prompt,
    "help": Help,
    "Printf_Bitwise_View": Printf_Bitwise_View,
    "Printf_Index_variables": Printf_Index_variables,
    "Printf_Entry": Printf_Entry,
    "Catalog_Organization": Catalog_Organization,
    "Reset_Disk": Reset_Disk,
    "Create": Create,
    "Delete": Delete,
    "Makdir": Makdir,
    "Deldir": Deldir,
    "Type": Type,
    "Edit": Edit,
    "Copy": Copy,
    "Move": Move,
    "Change": Change,
    "Alter": Alter,
    "Run": Run,
    "CD": CD,
    "Release": Release
}
# 主窗口==========================================================================
# 主窗口==========================================================================
main_window = tk.Tk()  # 调用Tk()创建主窗口
main_window.title("操作系统")  # 给主窗口起一个名字
main_window.geometry("1000x800+200+100")  # 大小
# main_window.config(menu=Generate_Menu(main_window))  # 生成菜单栏,窗口与菜单关联
main_window.rowconfigure(0, weight=1, minsize=200)  # row为0,缩放比为1
main_window.rowconfigure(1, weight=1, minsize=200)  # row为1,缩放比为1,最小200
main_window.columnconfigure(1, weight=1)  # column为1,缩放比为1

None_directory_image = tk.PhotoImage(file="空文件夹.png")  # 空文件夹图标
directory_image = tk.PhotoImage(file="文件夹图标.png")  # 文件夹图标
text_image = tk.PhotoImage(file="文本文件.png")  # 文本文件图标
executable_image = tk.PhotoImage(file="可执行文件.png")  # 可执行文件图标

# 位视图和索引表===================================================================
# 位视图和索引表===================================================================
disk_bar = tk.LabelFrame(main_window, text="磁盘")  # 放左边磁盘的框架
disk_bar.grid(row=0, column=0, sticky="nsew")
disk_bar.index_variables = []  # 128个标签的文本
disk_bar.label = []  # 128个标签列表
Generate_Disk_Bar()  # 生成磁盘框架的内容
# 树型目录结构====================================================================
# 树型目录结构====================================================================
current_directory_bar = tk.LabelFrame(main_window, text="当前目录内容")  # 放右边目录树的框架
current_directory_bar.grid(row=0, column=1, sticky="nsew")
current_directory_bar.treeview = ttk.Treeview()
current_directory_bar.item = {}  # 所有项目字典
Generate_Current_Directory_Bar()  # 生成当前目录框架的内容
# 用户接口=======================================================================
# 用户接口=======================================================================
# 用户接口比较特殊,放在主体中
user_interface_bar = tk.LabelFrame(main_window, text="用户接口")  # 放下边用户接口的框架
user_interface_bar.grid(row=1, column=0, columnspan=2, sticky="nsew")
user_interface_bar.rowconfigure(0, weight=1, minsize=50)  # row为0,缩放比为1
user_interface_bar.rowconfigure(1, weight=2, minsize=150)  # row为1,缩放比为3
user_interface_bar.columnconfigure(0, weight=1)  # column为0,缩放比为1
user_interface_bar.columnconfigure(1, weight=1)  # column为1,缩放比为1
# 当前目录=========================================
user_interface_bar.now_entry_bar = tk.LabelFrame(user_interface_bar, text="当前目录")  # 当前目录
user_interface_bar.now_entry = tk.StringVar()  # 当前目录变量
user_interface_bar.now_entry.set('S')
user_interface_bar.now_entry.entry = catalog_Entry()
user_interface_bar.now_entry.entry.name = b'S'  # 根目录
user_interface_bar.now_entry.entry.start = 2
user_interface_bar.now_entry.entry.len = 1
user_interface_bar.now_entry.entry.attribute = 1
user_interface_bar.now_lable = tk.Label(user_interface_bar.now_entry_bar, textvariable=user_interface_bar.now_entry,
                                        bg='white', borderwidth=2, relief='ridge')  # 当前目录标签
# 上级目录=========================================
user_interface_bar.up_entry_bar = tk.LabelFrame(user_interface_bar, text="上级目录")  # 上级目录
user_interface_bar.up_entry = tk.StringVar()  # 上级目录变量
user_interface_bar.up_entry.set('S')
user_interface_bar.up_entry.entry = catalog_Entry()
user_interface_bar.up_entry.entry.name = b'S'  # 根目录
user_interface_bar.up_entry.entry.start = 2
user_interface_bar.up_entry.entry.len = 1
user_interface_bar.up_entry.entry.attribute = 1
user_interface_bar.up_lable = tk.Label(user_interface_bar.up_entry_bar, textvariable=user_interface_bar.up_entry,
                                       bg='white', borderwidth=2, relief='ridge')  # 上级目录标签
# 文本控制台=========================================
user_interface_bar.text_bar = tk.LabelFrame(user_interface_bar, text="文本控制台")  # 文本控制台
user_interface_bar.text_bar.rowconfigure(0, weight=1)  # row为0,缩放比为1
user_interface_bar.text_bar.rowconfigure(1, weight=1, minsize=30)  # row为2,缩放比为1
user_interface_bar.text_bar.columnconfigure(0, weight=1)  # column为0,缩放比为1
user_interface_bar.out_bar = tk.LabelFrame(user_interface_bar.text_bar, text="输出框")  # 文本输出框框架
user_interface_bar.scrollbar = tk.Scrollbar(user_interface_bar.out_bar, orient=tk.VERTICAL)  # 滚动条y
# 字体本来想显示一点文字图之类的,但是会错位,就算了
user_interface_bar.output_entry = tk.Text(user_interface_bar.out_bar, font=('Microsoft Yahei UI', '12',),
                                          yscrollcommand=user_interface_bar.scrollbar.set)  # 输出文本框本体

# 创建右键菜单
menu = tk.Menu(user_interface_bar.output_entry, tearoff=0)
menu.add_command(label="复制", command=lambda: user_interface_bar.output_entry.event_generate("<Control-c>"))
# 绑定右键事件
user_interface_bar.output_entry.bind("<Button-3>", Get_Menu)
user_interface_bar.output_entry.bind('<Key>', Intercept_Input)  # 键盘输入拦截
sys.stdout = Redirect(user_interface_bar.output_entry)  # 重定向输出到输出文本框
user_interface_bar.input = tk.StringVar()  # 用户输入的变量
user_interface_bar.input.set("")
user_interface_bar.input_entry = tk.Entry(user_interface_bar.text_bar, exportselection=0, borderwidth=3,
                                          textvariable=user_interface_bar.input, relief='sunken')  # 用户输入文本框
user_interface_bar.input_entry.bind("<Return>",Execute)  # 回车的回调函数
user_interface_bar.input_entry.bind("<Tab>",Tab_input)  # Tab索引
user_interface_bar.input_entry.bind("<Up>", Up_input)  # 代码看看上面的
user_interface_bar.input_entry.bind("<Down>", Down_input)  # 代码看看后面的
# 部件安放====================================================
user_interface_bar.now_entry_bar.grid(row=0, column=0, sticky="nsew")
user_interface_bar.up_entry_bar.grid(row=0, column=1, sticky="nsew")
user_interface_bar.now_lable.pack(fill=tk.BOTH, expand=1)
user_interface_bar.up_lable.pack(fill=tk.BOTH, expand=1)
user_interface_bar.text_bar.grid(row=1, column=0, columnspan=2, sticky="nsew")
user_interface_bar.out_bar.grid(row=0, column=0, sticky="nsew")
user_interface_bar.scrollbar.pack(side=tk.RIGHT, fill=tk.Y)  # 靠右,拉满y
user_interface_bar.output_entry.pack(fill=tk.BOTH)
user_interface_bar.scrollbar.config(command=user_interface_bar.output_entry.yview)
user_interface_bar.input_entry.grid(row=1, column=0, sticky="nsew")
# =========================================
# =========================================
Operating_System_C.Closefp()  # c语言关闭c的输出文件
Out_Put_C()
device = {"A": tk.IntVar(), "B": tk.IntVar(), "C": tk.IntVar()}  # 三个设备
device["A"].set(0)
device["B"].set(0)
device["C"].set(0)
print("欢迎使用i道i操作系统,输入‘提示’了解更多,输入‘help’了解支持的函数。")
main_window.mainloop()  # 开启主循环,让窗口处于显示状态
Operating_System_C.Closefile()  # 关闭文件
sys.stdout.restoreStd()  # 恢复标准输出

运行实例:

这个是加了图片的示例

简易操作系统:使用Python 做的图形界面 C 做的内核

 下面几张是加图片前的示例

简易操作系统:使用Python 做的图形界面 C 做的内核

 现在支持Ctrl+s了,(确实就一行的事情)简易操作系统:使用Python 做的图形界面 C 做的内核

 简易操作系统:使用Python 做的图形界面 C 做的内核

程序进程展示

操作系统阻塞展示文章来源地址https://www.toymoban.com/news/detail-478960.html

到了这里,关于简易操作系统:使用Python 做的图形界面 C 做的内核的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 银河麒麟高级服务器操作系统V10-系统管理员手册:03 常用图形化工具

    目录 第三章 常用图形化工具 3.1. 刻录工具 3.2. 磁盘 3.2.1. 磁盘管理 3.2.1.1. 磁盘管理工具介绍 3.2.1.2. 磁盘管理工具界面展示 3.2.2. 磁盘管理工具使用 3.2.2.2. 分区格式化 3.2.2.3. 分区编辑 3.2.2.4. 编辑文件系统 3.2.2.5. 分区大小调整 3.2.2.6. 分区卸载和挂载 3.2.2.7. 分区删除 3.3. 远程

    2024年02月08日
    浏览(85)
  • CentOS图形化界面和命令行界面的转化--超详细(Linux操作系统)

    对于我这样的小白来说,Linux系统的图形化界面更加简单,但是Linux命令行才是精髓,如何进行转化呢? 图形化界面转化成命令行界面  ctrl+alt+F3 命令行界面转化为图形化界面 ctrl+alt+F1 切换成命令行模式: systemctl set-default multi-user.target (systemctl --系统控制,set-default-设置默

    2024年02月05日
    浏览(38)
  • 【linux深入剖析】操作系统与用户之间的接口:自定义简易shell制作全过程

    🍁你好,我是 RO-BERRY 📗 致力于C、C++、数据结构、TCP/IP、数据库等等一系列知识 🎄感谢你的陪伴与支持 ,故事既有了开头,就要画上一个完美的句号,让我们一起加油 Linux的Shell是一种命令行解释器,它是用户与操作系统内核之间的接口。 通过Shell,用户可以输入命令并与

    2024年03月18日
    浏览(40)
  • [爬虫]2.3.1 使用Python操作文件系统

    Python提供了许多内置库来处理文件系统,如 os 、 shutil 和 pathlib 等,这些库可以帮助你创建、删除、读取、写入文件和目录。 在Python中,你可以使用内置的 open 函数来打开一个文件。 open 函数返回一个文件对象,你可以对这个对象进行各种操作。 以下是一个读取文件的例子

    2024年02月16日
    浏览(25)
  • 简易英文统计和加密系统的设计实现(纯C语言实现,包含文件操作、注释多、易理解)

    ❤️作者主页:微凉秋意 🔥系列专栏:数据结构与课程设计 ✅作者简介:后端领域优质创作者🏆,CSDN内容合伙人🏆,阿里云专家博主🏆

    2024年02月02日
    浏览(31)
  • 远程连接银河麒麟高级服务器操作系统V10SP1的几种方法(命令行远程+图形化远程)

    服务端 OS环境:银河麒麟高级服务器操作系统V10SP1(x86_64) 确认sshd服务处于运行状态 [root@localhost ~]# systemctl status sshd 确认防火墙已经放行SSH服务 [root@localhost ~]# firewall-cmd --list-all 备注:如果系统没有放行ssh服务,或者ssh端口号被修改,则需要重新放行ssh服务或者新的ssh端口

    2024年02月09日
    浏览(156)
  • python-nmap库使用教程(Nmap网络扫描器的Python接口)(功能:主机发现、端口扫描、操作系统识别等)

    Python-nmap是一个Python库,用于帮助进行网络扫描。它是Nmap网络扫描器的Python接口,允许开发者从Python脚本中直接调用Nmap的功能。这篇文章将详细介绍如何使用python-nmap库来执行各种网络扫描任务。 在开始之前,需要确保安装了Nmap和python-nmap库。可以通过以下命令安装Nmap: 对

    2024年02月21日
    浏览(31)
  • Python | 人脸识别系统 — 用户操作

    博客汇总:Python | 人脸识别系统 — 博客索引 GitHub地址:Su-Face-Recognition 注:阅读本博客前请先参考 工具安装、环境配置:Python | 人脸识别系统 — 简介 UI界面设计:Python | 人脸识别系统 — UI界面设计 UI事件处理:Python | 人脸识别系统 — UI事件处理 人脸识别:Python | 人脸识

    2024年02月02日
    浏览(31)
  • Win10操作系统安装Python

    Windows 10 专业工作站版22H2 python-3.9.6-amd64.exe Python官网:https://www.python.org/ Python镜像:https://registry.npmmirror.com/binary.html?path=python/3.9.6/ 双击运行下载好的python-3.9.6-amd64.exe解释器包文件 单击Add Python 3.9 to PATH左边的复选框 单击Customize installation进入Optional Features界面 单击Next按钮进

    2024年02月05日
    浏览(37)
  • 用 Python 打造 AIGC 的「操作系统」

    carefree0910/carefree-drawboard: 🎨 Infinite Drawboard in Python (github.com) https://github.com/carefree0910/carefree-drawboard 最近,AIGC 可谓是大火而特火,然而现在大家一般都在用 Gradio / Streamlit 写 demo,一方面无法作为企业级产品去服务客户,另一方面也感觉比较东一块西一块,很难形成“合力”

    2024年02月09日
    浏览(24)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包