Dynamsoft Barcode Reader 개발을 위한 VSCode 확장 생성 방법

53576 단어 vscode
Dynamsoft Barcode Reader 은 엔터프라이즈급 바코드 및 QR 코드 SDK로 다양한 플랫폼(Windows, Linux, macOS, Android, iOS, Raspberry Pi OS 및 Web)과 프로그래밍 언어(Python, Java, Swift, C#, Cpp, 및 자바스크립트). Dynamsoft GitHub 리포지토리 및 공식 웹 사이트에는 많은 샘플 프로젝트가 배포되어 있습니다. 개발자가 Dynamsoft Barcode Reader를 빠르게 시작할 수 있도록 다양한 프로그래밍 언어 및 프레임워크에 대한 프로젝트 생성, 코드 스니펫 삽입 및 템플릿 다운로드 기능을 갖춘 VSCode 확장을 만들었습니다.

VSCode 확장 설치



https://marketplace.visualstudio.com/items?itemName=yushulx.dbr-code-generator

첫 번째 VSCode 확장 만들기



official tutorial에 따라 기본 VSCode 확장 프로젝트를 생성해 보겠습니다.

  • Yeoman 및 VS Code 확장 생성기 설치:

    npm install -g yo generator-code
    


  • 다음 명령을 실행하여 TypeScript 또는 JavaScript 프로젝트를 스캐폴딩합니다.

    yo code
    

  • F5를 눌러 프로젝트를 디버깅한 다음 F1를 눌러 Command Palette를 표시합니다. Hello World 명령을 입력하여 결과를 볼 수 있습니다.

  • Dynamsoft Barcode Reader용 VSCode 확장 만들기



    확장 프로그램은 다음을 지원합니다.

  • 프로젝트 생성

    콘솔, 데스크탑 GUI, 웹 및 모바일 앱을 생성합니다.

  • 코드 조각 삽입

    해당 프로그래밍 언어 파일에 코드 스니펫을 추가합니다.

  • 파일 다운로드

    바코드 및 QR 코드 인식을 위해 미리 설정된 매개변수 템플릿 파일을 다운로드합니다.

  • DBR 프로젝트 생성 단계



    1단계: 명령 팔레트에 대한 명령 나열


    package.json 파일에서 프로젝트 생성을 위한 명령은 다음과 같이 정의됩니다.

    "activationEvents": [
        "onCommand:dbr.dotnet",
        "onCommand:dbr.cpp",
        "onCommand:dbr.web",
        "onCommand:dbr.python",
        "onCommand:dbr.android",
        "onCommand:dbr.ios"
      ],
    "contributes": {
        "commands": [
          {
            "command": "dbr.dotnet",
            "title": "DBR: Create .NET Project"
          },
          {
            "command": "dbr.cpp",
            "title": "DBR: Create C/C++ Project"
          },
          {
            "command": "dbr.web",
            "title": "DBR: Create Web Project"
          },
          {
            "command": "dbr.python",
            "title": "DBR: Create Python Project"
          },
          {
            "command": "dbr.android",
            "title": "DBR: Create Android Project"
          },
          {
            "command": "dbr.ios",
            "title": "DBR: Create iOS Project"
          }
        ],
      },
    


    명령이 작동하도록 하려면 다음 TypeScript 코드를 extension.ts 파일에 추가해야 합니다.

    export function activate(context: vscode.ExtensionContext) {
    
        context.subscriptions.push(...[
            vscode.commands.registerCommand('dbr.dotnet', async () => {
            }),
            vscode.commands.registerCommand('dbr.cpp', async () => {
            }),
            vscode.commands.registerCommand('dbr.web', async () => {
            }),
            vscode.commands.registerCommand('dbr.python', async () => {
            }),
            vscode.commands.registerCommand('dbr.android', async () => {
            }),
            vscode.commands.registerCommand('dbr.ios', async () => {
            })
        ]);
    }
    




    2단계: 프로젝트 템플릿 준비



    일부 프로젝트 템플릿을 res 폴더 아래에 넣고 TypeScript에 물리적 경로를 저장합니다.

    private samples = {
            "python": path.join(__dirname, '../res/python/'),
            "dotnet": path.join(__dirname, '../res/dotnet/'),
            "cpp": path.join(__dirname, '../res/cpp/'),
            "web": path.join(__dirname, '../res/web/'),
            "android": path.join(__dirname, '../res/android/'),
            "ios": path.join(__dirname, '../res/ios/')
        };
    


    입력 명령에 따라 해당 프로젝트 경로를 반환할 수 있습니다.

    enum Type {
        CONSOLE = 'Console App',
        WINFORMS = 'Windows Forms App',
        FILE = 'File Reader',
        CAMERA = 'Camera Scanner',
        GUI = 'GUI App',
    }
    
    enum FolderName {
        FOLDER_NAME_CONSOLE = 'console',
        FOLDER_NAME_WINFORMS = 'winforms',
        FOLDER_NAME_FILE = 'file',
        FOLDER_NAME_CAMERA = 'camera',
        FOLDER_NAME_GUI = 'gui',
    }
    
    switch (option) {
        case "dotnet":
            root = this.samples.dotnet;
            projectType = await this.getProjectType([Type.CONSOLE, Type.WINFORMS]);
            break;
        case "cpp":
            root = this.samples.cpp;
            projectType = await this.getProjectType([Type.CONSOLE]);
            break;
        case "web":
            root = this.samples.web;
            projectType = await this.getProjectType([Type.FILE, Type.CAMERA]);
            break;
        case "python":
            root = this.samples.python;
            projectType = await this.getProjectType([Type.CONSOLE, Type.GUI]);
            break;
        case "android":
            root = this.samples.android;
            projectType = await this.getProjectType([Type.CAMERA]);
            break;
        case "ios":
            root = this.samples.ios;
            projectType = await this.getProjectType([Type.CAMERA]);
            break;
    }
    if (projectType === '') { return; }
    
    switch (projectType) {
        case Type.CONSOLE:
            src = path.join(root, FolderName.FOLDER_NAME_CONSOLE);
            break;
        case Type.WINFORMS:
            src = path.join(root, FolderName.FOLDER_NAME_WINFORMS);
            break;
        case Type.FILE:
            src = path.join(root, FolderName.FOLDER_NAME_FILE);
            break;
        case Type.CAMERA:
            src = path.join(root, FolderName.FOLDER_NAME_CAMERA);
            break;
        case Type.GUI:
            src = path.join(root, FolderName.FOLDER_NAME_GUI);
            break;
    }
    


    3단계: 대상 프로젝트 폴더 선택 및 열기



    새 프로젝트를 만들 때 vscode.window.showQuickPick를 호출하여 현재 작업 공간 폴더를 사용하거나 새 폴더를 여는 두 가지 옵션을 나열합니다.

    const answer = await vscode.window.showQuickPick(['Yes', 'No'], { placeHolder: 'Do you want to create a new folder?' });
            if (!answer) { return; }
    


    대답이 Yes 인 경우 vscode.window.showOpenDialog를 호출하여 폴더를 여는 팝업 창을 표시합니다.

    const projectName = await vscode.window.showInputBox({
                prompt: 'Enter a name for the new project',
                validateInput: (value: string): string => {
                    if (!value.length) {
                        return 'A project name is required';
                    }
                    return '';
                }
            });
    
    let workspace = '';
    const folderUris = await vscode.window.showOpenDialog({ canSelectFolders: true, canSelectFiles: false, canSelectMany: false, openLabel: 'Select folder' });
    if (!folderUris) {
        return '';
    }
    
    let workspaceFolderUri = folderUris[0];
    workspace = workspaceFolderUri.fsPath;
    let des = path.join(workspace, projectName);
    


    대답이 No 인 경우 현재 작업 공간 폴더를 사용합니다.

    let folders = vscode.workspace.workspaceFolders;
    let des = folders[0].uri.fsPath;
    


    4단계: 프로젝트 파일을 대상 폴더에 복사



    대상 폴더가 결정되면 프로젝트 템플릿 파일을 대상 폴더에 복사할 수 있습니다.

    export function copyFolder(src: string, des: string) {
        fs.readdir(src, (err, files) => {
            if (err) {
                return;
            }
    
            files.forEach(file => {
                let srcFile = path.join(src, file);
                let desFile = path.join(des, file);
                if (fs.statSync(srcFile).isDirectory()) {
                    fs.mkdirSync(desFile);
                    copyFolder(srcFile, desFile);
                } else {
                    fs.copyFileSync(srcFile, desFile);
                }
            });
        });
    }
    
    copyFolder(src, des);
    


    코드 조각 삽입



    스니펫 파일의 구조는 다음과 같습니다.

    {
        "prefix": "",
        "body": "",
        "description": ""
    }
    

    snippets라는 폴더를 만들고 일부 스니펫 파일을 추가합니다.

    snippets
     - android.json
     - cpp.json
     - csharp.json
     - python.json
     - swift.jon
     - web.json
    


    그런 다음 package.json를 열어 스니펫 파일 경로를 추가합니다.

    "contributes": {
        "snippets": [
                {
                    "language": "python",
                    "path": "./snippets/python.json"
                },
          {
                    "language": "csharp",
                    "path": "./snippets/csharp.json"
                },
          {
                    "language": "html",
                    "path": "./snippets/web.json"
                },
          {
                    "language": "cpp",
                    "path": "./snippets/cpp.json"
                },
          {
                    "language": "java",
                    "path": "./snippets/android.json"
                },
          {
                    "language": "swift",
                    "path": "./snippets/swift.json"
                }
            ]
    }
    


    확장이 Visual Studio Code에 설치되어 있는 한 해당 언어 파일에 코드 조각을 빠르게 추가하여 개발 프로세스를 신속하게 진행할 수 있습니다.



    파일 다운로드



    VSCode 확장의 지정된 URL에서 파일을 다운로드하려면 http 또는 https 모듈을 호출합니다. vscode.window.withProgress는 진행 상태를 시각적으로 표시하는 데 사용됩니다.

    import * as https from 'https';
    
    export async function httpsDownload(url: string, filename: string) {
        await vscode.window.withProgress({
            location: vscode.ProgressLocation.Notification,
            cancellable: true
        }, (progress, token) => {
            token.onCancellationRequested(() => {
                console.log("User canceled the long running operation");
            });
    
            progress.report({ message: "Downloading " + filename });
    
            return new Promise((resolve, reject) => {
                const file = fs.createWriteStream(filename);
                https.get(url, function (response: any) {
                    response.pipe(file);
                    file.on("finish", () => {
                        file.close();
                        console.log("Download Completed");
                        resolve("Download Completed");
                    });
                });
    
            });
        });
    }
    


    위에서 정의한 함수를 호출하여 Dynamsoft Barcode Reader의 매개변수 템플릿 파일을 다운로드합니다.

    import * as vscode from 'vscode';
    import { httpsDownload } from './utils';
    import * as path from 'path';
    
    enum Template {
        URL = "https://raw.githubusercontent.com/yushulx/cmake-cpp-barcode-qrcode/main/templates/",
        SPEED = 'Speed',
        SPEED_FILE = 'speed.json',
        BALANCED = 'Balanced',
        BALANCED_FILE = 'balanced.json',
        COVERAGE = 'Coverage',
        COVERAGE_FILE = 'coverage.json',
        MORECOVERAGE = 'More Coverage',
        MORECOVERAGE_FILE = 'morecoverage.json',
        MOSTCOVERAGE = 'Most Coverage',
        MOSTCOVERAGE_FILE = 'mostcoverage.json',
    }
    
    export class ParameterManager {
        private templates: any = {};
    
        constructor() {
            this.templates[Template.SPEED] = Template.URL + Template.SPEED_FILE;
            this.templates[Template.BALANCED] = Template.URL + Template.BALANCED_FILE;
            this.templates[Template.COVERAGE] = Template.URL + Template.COVERAGE_FILE;
            this.templates[Template.MORECOVERAGE] = Template.URL + Template.MORECOVERAGE_FILE;
            this.templates[Template.MOSTCOVERAGE] = Template.URL + Template.MOSTCOVERAGE_FILE;
        }
    
        public async downloadParameterFile() {
            // Select a template file
            const answer = await vscode.window.showQuickPick([Template.SPEED, Template.BALANCED, Template.COVERAGE, Template.MORECOVERAGE, Template.MOSTCOVERAGE], { placeHolder: 'Select a template' });
            if (!answer) { return; }
    
            let folders = vscode.workspace.workspaceFolders;
            if (!folders) {
                vscode.window.showWarningMessage('No folder is opened.');
            }
            else {
                let des = folders[0].uri.fsPath;
                switch (answer) {
                    case Template.SPEED:
                        httpsDownload(this.templates[Template.SPEED], path.join(des, Template.SPEED_FILE));
                        break;
                    case Template.BALANCED:
                        httpsDownload(this.templates[Template.BALANCED], path.join(des, Template.BALANCED_FILE));
                        break;
                    case Template.COVERAGE:
                        httpsDownload(this.templates[Template.COVERAGE], path.join(des, Template.COVERAGE_FILE));
                        break;
                    case Template.MORECOVERAGE:
                        httpsDownload(this.templates[Template.MORECOVERAGE], path.join(des, Template.MORECOVERAGE_FILE));
                        break;
                    case Template.MOSTCOVERAGE:
                        httpsDownload(this.templates[Template.MOSTCOVERAGE], path.join(des, Template.MOSTCOVERAGE_FILE));
                        break;
                }
            }
        }
    }
    


    소스 코드



    https://github.com/yushulx/vscode-dbr-code-generator

    좋은 웹페이지 즐겨찾기