我使用 Tkinter 在 python 中编写了一个简单的 GUI 程序。我们将此程序称为“gui.py”。我的用户使用Portable Python从 USB 密钥在 Windows 计算机上运行“gui.py” ;在主机上安装任何东西都是不可取的。
我希望我的用户通过双击 USB 密钥根目录下的图标来运行“gui.py”。我的用户不关心 python 是什么,如果不需要,他们也不想使用命令提示符。我不希望他们关心 USB 密钥分配的驱动器号。我希望它可以在 XP、Vista 和 7 上运行。
我的第一个丑陋的解决方案是在 USB 密钥的根目录中创建一个快捷方式,并将快捷方式的“目标”属性设置为“(root)\App\pythonw.exe (root)\App\gui.py” ”,但我不知道如何在 Windows 快捷方式中执行相对路径,并且使用像“E:”这样的绝对路径似乎很脆弱。
我的下一个解决方案是在 USB 闪存盘的根目录中创建一个 .bat 脚本,如下所示:
@echo off
set basepath=%~dp0
"%basepath%App\pythonw.exe" "%basepath%\App\gui.py"
Run Code Online (Sandbox Code Playgroud)
这似乎并不关心 USB 密钥分配的驱动器号,但它确实在我的程序运行时使 DOS 窗口保持打开状态。实用,但丑陋。
接下来我尝试了这样的 .bat 脚本:
@echo off
set basepath=%~dp0
start "" "%basepath%App\pythonw.exe" "%basepath%\App\gui.py"
Run Code Online (Sandbox Code Playgroud)
(有关有趣引用的解释,请参见此处)
现在,在 GUI 打开之前,DOS 窗口会在屏幕上短暂闪烁。少一点丑!还是丑啊
真正的男人如何处理这个问题呢?从 USB 记忆棒在 Windows 机器上启动 python Tkinter GUI 的最不丑陋的方法是什么?
编辑:下面的所有答案都非常好(py2exe、pyinstaller、小.exe、.wsf 脚本。).wsf 解决方案是最简单的,所以我现在使用它。如果我想要更漂亮的图标和标准的 .exe 扩展名,我可能最终会切换到其他三种解决方案之一。感谢大家!
Microsoft关于 PE 可选标头标准字段中“入口点 RVA”字段的文档(第 25.2.3.1 节)指出该字段应为:
入口点的 RVA,需要指向字节 0xFF 0x25,后跟标记为 EXE 执行/读取或 DLL 标记为 0 的部分中的 RVA
这是什么意思?我检查了c#编译器生成的PE文件,发现一个RVA指向所描述的字节0xFF 0x25,但接下来的四个字节是0x00402000,超出了相对虚拟内存的范围,据我所知,这不是一个有效的RVA 。我知道有一个重定位(第 25.3.2 节)指向该类型为“IMAGE_REL_BASED_HIGHLOW”的值,但我也不知道这意味着什么。我还知道它应该调用 mscoree.dll 的“_CorExeMain”(我正在使用可执行文件),如第 25.3.1 节中所述,但我不明白如何执行。
是否有适用于 Windows 的开源程序提供与 Linux 相同的功能/lib/ld\xe2\x80\x91linux.so.2?
我无法强制 msvc10 将 const 对象放入 .rdata 部分。它总是以 .data 结尾,完美初始化(意味着没有动态初始化/运行时构造函数执行)。(使用“发布”构建的标准项目设置进行编译)。我不明白为什么以下代码不能将 'obj1' 放入 .rdata PE 部分:
typedef struct _Struct1 {
int m1;
_Struct1(int p1): m1(p1) {};
_Struct1() {};
} Struct1;
class Class1 {
public:
Class1() {};
Class1(int p1, int p2): m1(p1), m2_struct(p2) {};
int m1;
Struct1 m2_struct;
};
const Class1 obj1(1, 2);
int main() {
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么 obj1 不转到 rdata(在 IDA 中检查)以及在当前情况下如何强制它?Tnx。
根据我读过的文档,Windows 可执行文件的导入目录通常放置在名为.idata. (我知道这些名称实际上只是注释,但“通常...称为”大概意味着 Microsoft 工具链将默认使用该名称。)
当我使用 Microsoft 编译器编译并链接一个简单的 C 测试程序,然后转储结果时,没有名为的部分.idata. 然而,在可选标头中,有一个正的 RVA 和导入目录的大小,因此导入表就在那里。
现在导入目录是否放置在具有不同名称的部分中,或者我是否遗漏了某些内容?
windows linker reverse-engineering portable-executable visual-c++
MS 加载程序将 PE 文件的哪些部分映射到内存中?
从 PE 文档中,我可以推断出 PE 可执行文件的典型格式(见下文)。
我知道,通过检查,PE 文件的所有内容,直到并包括节头,都完全按照存储在磁盘上的方式映射到内存中。
接下来发生什么?
文件的其余部分是否也被映射(在这里我指的是下图中的图像页面部分),以便整个文件完全像存储在磁盘上一样在内存中,或者加载程序是否比这更具选择性?
在文档中,我发现了以下代码段:
另一个例外是属性证书和调试信息必须放在图像文件的最后,属性证书表紧跟在调试部分之前,因为加载程序不会将它们映射到内存中。但是,关于属性证书和调试信息的规则不适用于目标文件。
这就是我能找到的关于加载器行为的全部内容;它只是说这两部分必须放在文件的最后,因为它们不会进入内存。
但是,如果加载程序加载除这两部分之外的所有内容,并且我将 RVA 部分设置得足够高,那么实际上会在内存中复制部分数据(一次在映射文件中,一次用于 RVA 指定的位置)?
如果可能,请链接到我可以进一步阅读有关特定于 MS Windows 的加载的地方。
我正在尝试解析 Windows 中的 PE 文件并从此结构中获取数据

我写了这段代码,它从 exe 文件中读取字节。
#include <Windows.h>
int main()
{
// open the file for binary reading
std::ifstream file;
file.open("D:/SomeProgram.exe", ios_base::binary);
if (!file.is_open())
return 1;
// get the length of the file
file.seekg(0, ios::end);
size_t fileSize = file.tellg();
file.seekg(0, ios::beg);
// create a vector to hold all the bytes in the file
std::vector<byte> data(fileSize, 0);
// read the file
file.read(reinterpret_cast<char*>(&data[0]), fileSize);
Run Code Online (Sandbox Code Playgroud)
我不知道如何获取数据,其中包含e_magic, e_cbip, e_cp.... 和最重要的e_ifanew. 我知道,这个结构 IMAGE_DOS_HEADER 存储在 Windows.h 中,但我不知道如何使用它从任何 exe …
当引用目标文件/可执行文件时,我对“段”和“节”之间是否存在差异感到困惑。
根据https://en.wikipedia.org/wiki/Object_file:
大多数目标文件格式被构造为单独的数据部分,每个部分包含某种类型的数据。
不过,本文稍后会继续讨论段(例如代码段、数据段等)。
此外,PE 文件格式(Windows 中的 .exe/.dll/.coff)将这些不同部分称为节(https://msdn.microsoft.com/en-us/library/windows/desktop/ms680547(v= vs.85).aspx )。
所以我的问题是:两者之间有区别还是实际上是同义词?
鉴于Random.exeWindows 上的一些,我如何确定
我可以使用文件资源管理器、其他工具或编程方法中的属性吗?
windows ×5
.net ×2
c++ ×2
assembly ×1
dll ×1
exe ×1
executable ×1
linker ×1
loader ×1
object-files ×1
parsing ×1
python ×1
tkinter ×1
visual-c++ ×1
x86 ×1