Lately I was experimenting on my old VB6, and found there a strange thing.
Using ProcMon I found that while compiling, VB6 runs Link.exe with parameters like this:
LINK "D:\Folder\Form1.OBJ" "D:\Folder\Project1.OBJ"... /SUBSYSTEM:WINDOWS,4.0 ...
I wrote Link.exe /? in cmd and found there
link.exe /?
usage: LINK [options] [files] [#commandfile]
options:
...
/SUBSYSTEM:{NATIVE|WINDOWS|CONSOLE|WINDOWSCE|POSIX}
By default VB6 compiles with parameter /SUBSYSTEM:WINDOWS.
But can I compile my VB6 code to Native or POSIX subsystem application?
This just sets a bit in the resultung exe file. Visual Basic uses Microsoft's standard linker which is also used for C/C++, that's why the flag is there.
So yes, you can compile it with those settings, but I'm certain that the resulting exe won't run in native mode or in the Posix subsystem.
For more information on those settings you might want to check out information about the PE file format and have a look at the DUMPBIN and EDITBIN tools.
VB applications uses Win32 calls, so there is no chance your application will work, even if you uses a console-only application.
Console is the only alternative subsystem that is useful. Posix isn't even present since Win2K and Native is for kernel mode drivers.
If any of this is news to you, I wonder why you are playing with ProcMon? Scary.
Related
I've got a Windows application with a GUI written in Rust and winapi. Despite its GUI, it behaves like a console application. When the exe file is started, a Command Prompt window pops up, and the application is run from it. This is not what I want; a main window should open instead, as in all real desktop apps. How can I achieve this goal in Rust with winapi?
I've investigated some options. You can develop Windows desktop applications using Tauri or gtk-rs, but both of these techniques have drawbacks when used for Windows apps. More options may be found here. I've also tried the windows-rs samples available on the internet, but they're all console apps with a graphical user interface, which isn't what I'm looking for.
I also note that C++ desktop applications use the function int APIENTRY wWinMain(...) as the entry point while console applications use int main(...), and wWinMain doesn't seem available in rust winapi.
Whether the system allocates a console for a newly created process is controlled by the Subsystem field in the Windows-specific optional PE header. The field is populated through the linker's /SUBSYSTEM command line option. The only relevant arguments for desktop applications are CONSOLE and WINDOWS. The former instructs the system to allocate a console on launch, whereas the latter won't.
You can instruct the linker to target the WINDOWS subsystem from Rust code by placing the per-module
#![windows_subsystem = "windows"]
attribute (see windows-subsystem) inside the main module of your application.
You'll find an example of this in the core_app sample of the windows crate.
This is the most convenient way to target the WINDOWS subsystem. You can also explicitly pass the linker flag along, e.g. by placing the following override into .cargo/config.toml:
[build]
rustflags = [
"-C", "link-arg=/SUBSYSTEM:WINDOWS",
]
This may or may not work, depending on the linker you happen to be using. Since the linker isn't part of the Rust toolchain, making sure that this works and has the intended effect is on you.
A note on the entry point's function name: It is irrelevant as far as the OS loader is concerned. It never even makes it into the final executable image anyway. The PE image only stores the (image-base-relative) AddressOfEntryPoint, and that symbol could have been named anything.
The concrete name is only relevant to the build tools involved in generating the respective linker input.
More info here: WinMain is just the conventional name for the Win32 process entry point. The underlying principles apply to Rust just the same, particularly the aspect that the user-defined entry point (fn main()) isn't actually the executable's entry point.
I'm porting a linux app on windows and I need dbus-daemon.exe running on my win session.
My app and dbus-daemon.exe work fine but the latter still opens a default console and, being not familiar with programming on windows, I don't know how to get rid of it.
Maybe by making it invisible ?
Windows, by default, opens a console window for executables compiled for the console subsystem (the "subsystem" being essentially a bit of metadata in the Portable Executable format, aka EXE/DLL). So you have at least two options:
Compile the dbus-daemon for the Windows subsystem, if you're the one doing the compilation. It is a linker option.
Launch the dbus-daemon process passing the CREATE_NO_WINDOW flag to the relevant API function (probably CreateProcess). If you're not using the Windows API directly, look how CreateProcess and CREATE_NO_WINDOW are exposed in the API you are using. In .NET, for example, it's the ProcessStartInfo.CreateNoWindow property.
I have an executable compiled by MSVS2013 on Windows 7 SP1 32 bit with C runtime statically linked and platform toolset "Visual Studio 2013 - Windows XP (v120_xp)"
It runs perfectly on Win7 (see attached screenshot of Dependency Walker profiling).
It fails to run on WinXP:
Here is the profile log:
Starting profile on 12/9/2014 at 2:55:03 AM
Operating System: Microsoft Windows XP Professional (32-bit), version 5.01.2600 Service Pack 3
Program Executable: c:\temp\OCTOPUS.EXE
Program Arguments:
Starting Directory: C:\Temp\
Search Path: C:\Program Files\ActiveState Komodo Edit 8\;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\Program Files\MATLAB\R2009b\runtime\win32;C:\Program Files\MATLAB\R2009b\bin;C:\VisaPoint\sbperl\perl\bin
Options Selected:
Simulate ShellExecute by inserting any App Paths directories into the PATH environment variable.
Log DllMain calls for process attach and process detach messages.
Log DllMain calls for all other messages, including thread attach and thread detach.
Hook the process to gather more detailed dependency information.
Log LoadLibrary function calls.
Log GetProcAddress function calls.
Log thread information.
Use simple thread numbers instead of actual thread IDs.
Log first chance exceptions.
Log debug output messages.
Use full paths when logging file names.
Log a time stamp with each line of log.
Automatically open and profile child processes.
--------------------------------------------------------------------------------
00:00:00.000: Failure starting the process. %1 is not a valid Win32 application (193).
[1]: http://i.stack.imgur.com/m82n6.png
[2]: http://i.stack.imgur.com/6Yr37.png
Modern versions of Visual Studio, starting with VS2012, use linker settings that marks the executable image compatible with the current generation of Windows. Version 6, started with Vista. XP and Server2003 were in the previous generation, version 5.
You can still build programs that run on XP with VS2013. But you have to make a setting change. Right-click the project, Properties, General. Change the Platform Toolset setting to v120_xp.
There are a few consequences, your program gets built with an old version of the Windows SDK. V7.1, the last one that was still compatible with XP. The C runtime library makes a bunch of operating system calls that are only available in generation 6. It will stumble along without them, affecting relatively minor details related to threading and culture. This is the kind of FUD that ought to remind you that it might not be the best idea to still promise support for such an ancient operating system. Make sure you keep a running version of XP around so you can properly test and repro. And keep in mind that you can't install VS on it anymore so if you do get a support call from an XP user then you tend to get a fairly heavy migraine.
Ok, just forgot to set SUBSYSTEM in Linker options.
Here is a link with explanations:
https://software.intel.com/en-us/articles/linking-applications-using-visual-studio-2012-to-run-on-windows-xp
I have a few things like running SFC, defrag, and reset the page file and so on, things that can be done within windows VBScript, I am just wondering if I can compile that code as a resource and call it as needed. Thanks.
Lee
You can use the Windows Script Host interfaces, IActiveScript and IActiveScriptParse, to execute Javascript/VBScript from memory. You can then compile your Javascript/VBScript into a resource, extract it at runtime, and then execute it when needed.
Update: have a look at this blog article:
Adding Active Scripting to your
Delphi Win32 application
And then look at this discussion to make it work in 64bit:
Writing a scripting host in Delphi XE2 64-bit
I've always been curious as to how one extension, EXE, can be as versatile as it is in that if you assemble an assembly program, you get an EXE in machine code for your processor but if you compile a C# or other .Net program, you also get an EXE except that it is run in the proper runtime environment. I'm not sure if this is different from OS to OS (I imagine it is), but when an EXE is executed, how is it determined how to execute it?
On a related note, if I were writing my own programming language, how would I tie in my runtime environment into this mechanism?
When compiling a .NET program to an EXE, it's more than just a blob of bytecode (like Java). There's actually native executable created that will load the .NET runtime and hand off the .NET bytecode to it, or display a friendly-ish error message indicating that the framework is not available.
The format is even more flexible than that, as every Windows EXE actually includes a DOS program at the beginning which will display an error ("cannot run in DOS mode") when executed as a DOS program.
You can read more details on the PE format on Wikipedia: http://en.wikipedia.org/wiki/Portable_Executable