You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Electron打包启动报错Error: ENOTDIR, not a directory求助

Electron打包后启动报错ENOTDIR,引入@mtproto/core后触发问题

首次使用Electron开发应用,采用electron-forge作为构建工具。npm run make执行无异常,但启动生成的安装程序或.exe文件时,抛出以下错误:

Uncaught Exception:
Error: ENOTDIR, not а directory
  at createError(node:e1ectron/js2c/node_init:2:2095)
  at t.mkdirSync (node:e1ectron/js2c/node_init:2:16249)
  at module.exports.sync
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...6)
  at set all
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...12)
  at new Configstore
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...13)
  at getLocaIStorage
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...24)
  at new Storage
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...45)
  at new <anonymous>
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...22)
  at new API
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...20)
  at 0bject <anonymous>
(C:\Users\kazik\Desktop\social_network_analyzer\out\social-network-analyzer-win32-x64...13)

仅集成VK API时项目可正常运行,引入@mtproto/core后出现该问题,npm start启动应用一切正常。

package.json代码

{  
  "name": "social_network_analyzer",  
  "version": "1.0.0",  
  "description": "app for analyze social networks for Press and Mass Communications Committee",  
  "main": "main.js",  
  "scripts": {    
    "start": "electron-forge start",    
    "package": "electron-forge package",    
    "make": "electron-forge make"  
  },  
  "repository": {    
    "type": "git",    
    "url": "git+https://github.com/KazikS/social_network_analyzer"  
  },  
  "author": "sabkazz",  
  "license": "ISC",  
  "bugs": {    
    "url": "https://github.com/KazikS/social_network_analyzer/issues"  
  },  
  "homepage": "https://github.com/KazikS/social_network_analyzer#readme",  
  "devDependencies": {    
    "@electron-forge/cli": "^7.4.0",    
    "@electron-forge/maker-deb": "^7.4.0",    
    "@electron-forge/maker-rpm": "^7.4.0",    
    "@electron-forge/maker-squirrel": "^7.4.0",    
    "@electron-forge/maker-zip": "^7.4.0",    
    "@electron-forge/plugin-auto-unpack-natives": "^7.4.0",    
    "@electron-forge/plugin-fuses": "^7.4.0",    
    "@electron/fuses": "^1.8.0",    
    "electron": "^31.1.0"  
  },  
  "dependencies": {    
    "@mtproto/core": "^6.3.0",    
    "axios": "^1.7.2",    
    "electron-squirrel-startup": "^1.0.1",    
    "mtproto": "^0.0.1",    
    "scandir": "^0.0.4"  
  }
}

main.js代码

const { app, BrowserWindow, ipcMain } = require("electron");
const path = require("node:path");
const axios = require("axios");
const api = require("./telegram/tgApi");
const { access } = require("node:fs");
const auth = require("./telegram/auth");
const getUser = require("./telegram/getUser");

let win;

const createWindow = () => {  
  win = new BrowserWindow({    
    width: 1000,    
    height: 1000,    
    webPreferences: {      
      preload: path.join(__dirname, "preload.js"),      
      contextIsolation: true,      
      enableRemoteModule: false,      
      nodeIntegration: false,    
    },  
  });  
  win.loadFile("index.html");  
  win.webContents.openDevTools();  
  checkUserStatus();
};

async function checkUserStatus() {  
  const user = await getUser();  
  console.log(user);  
  win.webContents.send("user-status", user);
}

app.whenReady().then(() => {  
  createWindow();

  app.on("activate", () => {    
    if (BrowserWindow.getAllWindows().length === 0) createWindow();  
  });  
  app.on("window-all-closed", () => {    
    if (process.platform !== "darwin") app.quit();  
  });
});

ipcMain.handle("analyze", async (event, { url, startDate, endDate }) => {  
  try {    
    if (url.includes("vk.com")) {      
      return analyzeVK(url, startDate, endDate);    
    } else if (url.includes("t.me")) {      
      return analyzeTelegram(url, startDate, endDate);    
    } else {      
      throw new Error("Unsupported URL");    
    }  
  } catch (error) {    
    console.error("Error in analyze handler:", error);    
    throw error;  
  }
});

//VK
async function analyzeVK(url, startDate, endDate) {  
  const token = "*********************************************************";  
  const apiVersion = "5.131";  
  const groupId = await extractGroupId(url, token, apiVersion);  
  let offset = 0;  
  let count = 100;  
  let allPosts = [];  
  let hasMorePosts = true;  
  while (hasMorePosts) {    
    const response = await axios.get(`https://api.vk.com/method/wall.get`, {      
      params: {        
        owner_id: `-${groupId}`,        
        count: count,        
        offset: offset,        
        access_token: token,        
        v: apiVersion,      
      },    
    });    
    const posts = response.data.response.items;    
    if (posts.length < count) {      
      hasMorePosts = false;    
    }    
    allPosts = allPosts.concat(posts);    
    offset += count;  
  }

  const start = new Date(startDate);  
  const end = new Date(endDate);  
  start.setHours(0, 0, 0, 0);  
  end.setHours(23, 59, 59, 999);

  const filteredPosts = allPosts.filter((post) => {    
    const postDate = new Date(post.date * 1000);    
    return postDate >= start && postDate <= end;  
  });  
  const totalLikes = filteredPosts.reduce(    
    (acc, post) => acc + (post.likes ? post.likes.count : 0),    
    0  
  );  
  const totalViews = filteredPosts.reduce(    
    (acc, post) => acc + (post.views ? post.views.count : 0),    
    0  
  );  
  const dateDiff = Math.abs(end - start);  
  const weeks = dateDiff / (1000 * 60 * 60 * 24 * 7);  
  const avgPostsPerWeek = filteredPosts.length / weeks;  
  console.log(    
    "Views count: " +      
      totalViews +      
      "\n" +      
      "Likes count: " +      
      totalLikes +      
      "\n" +      
      "Per week" +      
      avgPostsPerWeek +      
      " " +      
      weeks +      
      " " +      
      filteredPosts.length  
  );  
  return { filteredPosts, totalLikes, totalViews, avgPostsPerWeek };
}

//telegram

ipcMain.handle("update_config", async (event, data) => {  
  console.log(data);  
  auth(data.phone, data.code, data.password);
});

async function delay(ms) {  
  return new Promise((resolve) => setTimeout(resolve, ms));
}

async function analyzeTelegram(url, startDate, endDate) {  
  const channelUsername = extractChannelUsername(url);  
  let allMessages = [];  
  let offsetId = 0;  
  let hasMoreMessages = true;

  try {    
    const channelInfo = await api.call("contacts.resolveUsername", {      
      username: channelUsername,    
    });    
    const channelId = channelInfo.chats[0].id;    
    const accessHash = channelInfo.chats[0].access_hash;

    while (hasMoreMessages) {      
      console.log(`Fetching messages with offset_id: ${offsetId}`);      
      try {        
        const messages = await api.call("messages.getHistory", {          
          peer: {            
            _: "inputPeerChannel",            
            channel_id: channelId,            
            access_hash: accessHash,          
          },          
          offset_id: offsetId,          
          offset_date: 0,          
          add_offset: 0,          
          limit: 100,          
          max_id: 0,          
          min_id: 0,          
          hash: 0,        
        });

        if (messages.messages.length === 0) {          
          console.log("No more messages to fetch");          
          hasMoreMessages = false;        
        } else {          
          allMessages = allMessages.concat(messages.messages);          
          offsetId = messages.messages[messages.messages.length - 1].id;          
          console.log(            
            `Fetched ${messages.messages.length} messages, next offset_id: ${offsetId}`          
          );        
        }      
      } catch (error) {        
        if (error.error_code === 420) {          
          const waitTime = parseInt(error.error_message.split("_").pop(), 10) * 1000;          
          console.log(`Flood wait detected, waiting for ${waitTime} ms`);          
          await delay(waitTime);        
        } else {          
          throw error;        
        }      
      }    
    }

    console.log("All messages:", allMessages);

    const start = new Date(startDate);  
    const end = new Date(endDate);  
    start.setHours(0, 0, 0, 0);  
    end.setHours(23, 59, 59, 999);

    const filteredMessages = allMessages.filter((msg) => {      
      const msgDate = new Date(msg.date * 1000);      
      return msgDate >= start && msgDate <= end;    
    });

    console.log("Filtered messages:", filteredMessages);

    let totalMessages = filteredMessages.length;  
    let totalViews = 0;  
    let totalReactions = 0;

    filteredMessages.forEach((msg) => {      
      if (msg.views) totalViews += msg.views;      
      if (msg.reactions && msg.reactions.results) {        
        totalReactions += msg.reactions.results.length;      
      }    
    });

    const dateDiff = Math.abs(end - start);  
    const weeks = dateDiff / (1000 * 60 * 60 * 24 * 7);  
    const avgPostsPerWeek = filteredMessages.length / weeks;  
    return { totalMessages, totalReactions, totalViews, avgPostsPerWeek };  
  } catch (error) {    
    console.error("Invalid query:", error);    
    throw error;  
  }
}

async function extractGroupId(url, token, apiVersion) {  
  const match = url.match(/vk\.com\/(?:public|club)(\d+)/);  
  if (match) {    
    return match[1];  
  }  
  const groupNameMatch = url.match(/vk\.com\/(.+)/);  
  const groupName = groupNameMatch ? groupNameMatch[1] : null;  
  if (!groupName) {    
    throw new Error("Invalid group URL");  
  }  
  const response = await axios.get("https://api.vk.com/method/groups.getById", {    
    params: {      
      group_id: groupName,      
      access_token: token,      
      v: apiVersion,    
    },  
  });  
  const groupId = response.data.response[0].id;  
  return groupId;
}

function extractChannelUsername(url) {  
  const regex = /(?:https?:\/\/)?(?:t\.me|telegram\.me)\/([a-zA-Z0-9_]+)/;  
  const match = url.match(regex);  
  return match ? match[1] : null;
}

已尝试的解决方法

  • 重装node_modules
  • 将path.resolve(__dirname, "needed file")替换为'./needed file'
  • 删除webPreferences中的nodeIntegration: false
  • 重装Windows

内容的提问来源于stack exchange,提问作者Казбек Сабанаев

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 14:38:09