{"id":13772451,"url":"https://github.com/astares/Pharo-OS-Windows","last_synced_at":"2025-05-11T04:31:25.063Z","repository":{"id":78113869,"uuid":"139562488","full_name":"astares/Pharo-OS-Windows","owner":"astares","description":"Support for Windows operating system for Pharo","archived":false,"fork":false,"pushed_at":"2025-01-03T23:52:26.000Z","size":255,"stargazers_count":16,"open_issues_count":3,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-04-02T08:35:57.844Z","etag":null,"topics":["pharo"],"latest_commit_sha":null,"homepage":null,"language":"Smalltalk","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/astares.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2018-07-03T09:48:15.000Z","updated_at":"2025-03-29T21:13:54.000Z","dependencies_parsed_at":"2024-01-06T21:51:32.645Z","dependency_job_id":"5a1de78f-c863-4a8d-b134-b5b3bd7ce458","html_url":"https://github.com/astares/Pharo-OS-Windows","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astares%2FPharo-OS-Windows","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astares%2FPharo-OS-Windows/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astares%2FPharo-OS-Windows/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/astares%2FPharo-OS-Windows/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/astares","download_url":"https://codeload.github.com/astares/Pharo-OS-Windows/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253518941,"owners_count":21921074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pharo"],"created_at":"2024-08-03T17:01:04.197Z","updated_at":"2025-05-11T04:31:23.400Z","avatar_url":"https://github.com/astares.png","language":"Smalltalk","funding_links":[],"categories":["System interaction"],"sub_categories":[],"readme":"# Pharo-OS-Windows\nSupport for Windows operating system for [Pharo](https://www.pharo.org)\n\n# The OS PROJECT FOR PHARO\n\n# Introduction\n\n[Pharo][1] with an integrated external interface offers new ways to interact with the ouside world from within your Smalltalk image. Beside interacting with external libraries from other OpenSource projects or commercial libraries it is also very useful to call and use the underlying operating system platform.\n\nThe **[OS project][6]** on SmalltalkHub is intended to provide such a layer on top of UFFI. Starting with the Windows operating system our hope is that other will jump onto the bandwagon and help to extend it to support other platforms (Mac, Linux, ...) as well. \n\nIt is possible to generate Pharo code for native interfaces - but we prefer handcrafted code to wrap the native platform since often the underlying API's and names are not very well designed. This way we can make sure to provide a more object-oriented abstraction and more alignment with the Pharo philosophy to provide a clean and innovative environment.  \n\n### Requirements\n\nThe **[OS project][6]** requires at least Pharo 3.0. You can grab a copy of Pharo for your platform from the [Pharo file server][3].\n\n### Packages and Naming\n\nThe project **[OS project][6]** defines a standard for package names - if you want to support the project it would be necessary to follow it. \nThe first part of a package name has to begin with **\"OS-\"** followed by the name of the platform (for instance *\"OS-Windows\"* or \"OS-Mac\"). \n\nAny following package name is up to the packages that will be provided. It is a good style to provide some kind of ***Core*** package, like *\"OS-Windows-Core\"* defining functionality common to other dependent packages. \nIt is also a good practice to separate the tests in an own packages so they can be loaded only if required.   \n\n----------------------------------------------------------------------\n# Windows Support \n## OS-Windows project\n\nWindows support is defined in the project The **[OS-Windows][2]** - a subproject of **[OS project][6]** \n \n### Installation \n\nYou can install the packages either directly from the Pharo configuration browser or with the following script: \n\n```Smalltalk\nMetacello new \n\trepository: 'github://astares/Pharo-OS-Windows/src';\n\tbaseline: 'OSWindows' ;\n\tload\n```\n\nBy default all packages are loaded as well as the tests. Open the test runner and run all tests from the \"OS\" category to see if its fully working and report any issue you may find.\n\n----------------------------------------------------------------------\n### Debugging\n#### Pharo debugging vs. native debugging\nThere is nothing more helpful for development than a debugger that shows you your code and lets you walk through it. Pharo has a very powerful interactive debugger. Did you know that (compared to traditional development environments in other languages) you can save your Pharo image while debugging and open it the next day to continue to step through your program? Just try it! \n \nIf you work with native environments like Windows it may (in very rare cases) be very helpful to additionally use external debug possibilities. This is useful for VM developers or people who dive deep down into the low level world of assembler (which is also possible from within Pharo with NativeBoost and ASMJit, less with new UFFI). Additional external debug support can also be helpful if you run the Pharo image headless without  any user interface.\n\nIn these rare cases you can use:\n\n```Smalltalk\nWinDebugger outputDebugString: 'Some debug info from my program'\n```\n\nto write to the windows debug stream. While running can catch and display such messages with various tools like \"DebugView\" or dbmon.exe. You can get these tools for free on the internet.\n\nIt can also be possible that you want to know if Pharo (the virtual machine of Pharo to be precise) is running under the control of a debugger. The following expression can help you here:\n\n```Smalltalk\nWinDebugger isDebuggerPresent\n```\n\n----------------------------------------------------------------------\n### Processes and Threads\n#### Process creation - nonblocking\n\nThe class ***WinProcess*** provides access to native OS processes of Windows - so you can use it to start other native processes: \n\n```Smalltalk\nWinProcess createProcess: 'explorer.exe'\n```\n\nIt returns also an instance of ***WinProcessInformation*** which you can use to query for the PID of the new process:\n\n```Smalltalk\n(WinProcess createProcess: 'explorer.exe') processId\n```\n\nor the new process itself:\n\n```Smalltalk\n(WinProcess createProcess: 'explorer.exe') process\n```\n\nWhen you start a new operating system process this way you will notice that Pharo continues independently. So it is not blocked and both processes run in parallel. \n\n#### Process creation - blocking\n\nYou may have the requirement that you start an external operating system process and wait until its processing is finished before you continue within your Pharo program. Here is an example:\n\n```Smalltalk\nWinProcess createAndWaitForProcess: 'cmd.exe'.\nTranscript show: 'The external process just finished'.\n```\n\nThis opens a new command line window and the Pharo process (virtual machine process) is blocked until you either enter \"EXIT\" or close the console window. \nAfter that Pharo continues its work and writes to the Transcript.\n\n#### The VM Process\n\nWhen you start Pharo you start the virtual machine which is a normal platform dependent executable file that runs as a native operating system process. You can access this process of the Pharo virtual machine using the following expression:\n\n```Smalltalk\nWinProcess currentProcess\n```\n\nBy default the VM runs with normal priority which you can check with:\n\n```Smalltalk\nWinProcess currentProcess isNormalPriorityClass\n```\n\nwhich should return true.\n\nAny process running on the operating system is associated with a PID (Process Identifier). If you start a second VM you will start a new native OS Process with a different process ID.\nUse this expression to get the PID:\n\n```Smalltalk\nWinProcess currentProcessId\n```\n\nCompare that with the PID that is displayed in the Windows TaskManager.\n\nYou can also query for some startup informations:\n\n```Smalltalk\nWinProcess startupInfo wasStartedFromAShortcut\n```\n\nor\n\n```Smalltalk\nWinProcess startupInfo title\n```\n\nto find out how and where the virtual machine was started.\n\n#### Threads\n\nThe Pharo VM provides its own internal managed process handling to stay portable. Also the number of the underlying operating system processes may be limited - which is no problem for you if you use Pharo.  \n\nSo in a simple VM Pharo runs within a single thread within a single OS process. You can access this thread using:\n\n```Smalltalk\nWinThread currentThread\n```\n\nand \n\n```Smalltalk\nWinThread currentThreadId\n```\n\nNote that there are implementation (like Cog-VM) that provide a multithreaded variant of the VM.\n\n----------------------------------------------------------------------\n### The Windows User Interface\n\n#### Windows\n\nIn a graphical environment like Windows, a window is a rectangular area of the screen where the application displays output and receives input from the user. \n\nSo \"Windows\" are from the API point of view not only the framed windows that your move around. Also an edit widget or a list view in windows is represented as an own window, usually these are referred as child windows. Even the desktop background itself is an own Window.\n\nYou can get the active window using:\n\n```Smalltalk\nWinWindow activeWindow\n```\n\nand query or manipulate it:\n\n```Smalltalk\nWinWindow activeWindow title inspect.\nWinWindow activeWindow title: 'Pharo main window title'\t\n```\n\nIf you have a window instance you can easily find out about the area \nit fills on the screen:\n\n```Smalltalk\nWinWindow desktopWindow windowRectangle\n```\n\nor set its position\n\n```Smalltalk\nWinWindow activeWindow moveTo: 20@10\n```\n\nYou can also show and hide a window as this example proves:\n\n```Smalltalk\n|win|\nwin := WinWindow activeWindow.\nwin hide.\n(Delay forSeconds: 2) wait.\nwin show\n```\n\n...\n\n----------------------------------------------------------------------\n### Graphics\n\n#### Basic drawing\n\nAny native window in the Windows operating system provides a device context (DC). You can easily access it if you have a window object. Since Pharo runs in a single native window we can access its windows device context easily:\n\n```Smalltalk\nWinWindow pharoWindow deviceContext \n```\n\nThe device context (represented by instances of class ***WinDeviceContext***) can be used to draw:\n\n```Smalltalk\nWinWindow pharoWindow deviceContext \n     drawRectangle: (10@10 extent: 100@100)\n```\n\nYou can also access the device context of the whole Window desktop allowing to draw outside of the Pharo window\n\n```Smalltalk\nWinDeviceContext desktopDeviceContext  \n    drawEllipse: (0@0 extent: 100@100)\n```\n\n#### Why draw using native Windows-API\nPharo has several possibilities to draw - by default there is Morphic that draws\ninside the Pharo window. There is also Athens (which is also based on NativeBoost) allowing you to work with vector graphics and that is portable across several platforms.\n\nBut as you have seen from the desktop example with native access to the windows graphic system (GDI and GDI+) in this project it is also possible to draw outside the Pharo window. So by default one should go the usual Pharo route (Morphi, Athens) for drawing and use the mentioned way only if required.\n\n----------------------------------------------------------------------\n### Dialogs\n#### MessageBox\n\nWindows provides by default a message box that can be used to inform the user. Have a look at class ***WinMessageBox***. It is still unfinished but you can test:\n\n```Smalltalk\nWinMessageBox test\n```\n\n----------------------------------------------------------------------\n### Shell support\n\n#### Open a URL\nYou can easily use the class WinShell to open a web browser on a given URL.\n\n```Smalltalk\nWinShell shellBrowse: 'http://www.pharo-project.org'\n```\n\nIf you have more than one web browser installed you should note that Windows uses the default browser that is associated with HTML files.\n\n#### Open a document\n\nIf you want to open an application that is associated with a specific file extension then you can use the ***#shellOpen:*** message. Here is an example:\n\n```Smalltalk\nWinShell shellOpen: 'c:\\pharo.pdf'\n```\n\n#### Open Explorer\nThe Windows explorer is a shell browser that gives you access to the file system. You can open it on any folder in the filesystem very easily:\n\n```Smalltalk\nWinShell shellExplore: 'C:\\'\n```\n\nNote that you can also open it on any virtual folder within the system:\n\n```Smalltalk\nWinShell shellExplore: 'shell:Cookies'\n```\n\n#### Using Windows explorer\nBy default you can easily open the windows explorer with\n\n```Smalltalk\nWinExplorer open\n```\n\nWith the class ***WinExplorer*** there is a more convinient way to open virtual folders. Just check the various class side methods - here are some useful examples:\n\n```Smalltalk\nWinExplorer openDesktop.\nWinExplorer openContacts. \nWinExplorer openCookies.\n```\n\n#### Using Internet Explorer\nTo start the Windows Internet Explorer browse use the following expression:\n\n```Smalltalk\nWinInternetExplorer open\n```\n\nor open it directly on a URL:\n\n```Smalltalk\nWinInternetExplorer open: 'http://association.pharo.org'\n```\n\nYou can open the IE browser also in kiosk mode which is fullscreen:\n\n```Smalltalk\nWinInternetExplorer openKioskMode.\nWinInternetExplorer openKioskMode: 'http://consortium.pharo.org'\n```\n\nIf you work with the [Seaside][4] web framework for Pharo or other web frameworks you may find this snippet very handy:\n\n```Smalltalk\nWinExplorer openCookies.\nWinInternetExplorer deleteCookies\n```\n\nYou can also delete the browser history:\n\n```Smalltalk\nWinExplorer openHistory.\nWinInternetExplorer deleteHistory\n```\n\nor clean up some more:\n\n```Smalltalk\nWinInternetExplorer deleteFormData.\nWinInternetExplorer deletePasswords\n```\n\n----------------------------------------------------------------------\n\n### Environment \n#### Getting environment infos\n\nFirst of all you may need to know on which windows you are running:\n\n```Smalltalk\nSmalltalk os isWin32 \n```\n\nYou also may want to see if you are running on 32 or 64 bit:\n\n```Smalltalk\nWinEnvironment is64BitWindows \n```\n\nIt is also often required to get information about environment settings like the environment variables. Here are some examples that you should inspect one after the other:\n\n```Smalltalk\nWinEnvironment getEnvironmentVariable: 'PATH'.\nWinEnvironment getPathEntries.\nWinEnvironment getPathExtensions.\n```\n\n#### Getting processor infos\nOften it is interesting to find out how many processors the system is running on:\n\n```Smalltalk\nWinEnvironment getNumberOfProcessors\n```\n\nYou may also want to know more about the details of the underlying processor, its easy to query:\n\n```Smalltalk\nWinEnvironment getProcessorArchitecture.\nWinEnvironment getProcessorIdentifier.\nWinEnvironment getProcessorLevel.\nWinEnvironment getProcessorRevision\t\n```\n\n#### Getting other infos\n\nHere are some more useful informations from the environment:\n\n```Smalltalk\nWinEnvironment getUserName.\nWinEnvironment getComputerName\n```\n\nor infos about the file system configuration:\n\n```Smalltalk\nWinEnvironment getDriveType: WinEnvironment getHomeDrive.\n```\n\nUsually this will return *#DRIVE_FIXED* while (depending on your hardware setup) the following expression \n\n```Smalltalk\nWinEnvironment getDriveType:  'D:'\n```\n\nmay return *#DRIVE_CDROM*\n\n#### Accessing the user session\n\nIt is possible to access the user session from within Pharo very \neasily. If you like you can lock the workstation using the following expression:\n\n```Smalltalk\nWinUserSession lockWorkstation\n```\n\nOr if you want to hibernate the windows session just evaluate:\n\n```Smalltalk\nWinUserSession hibernate\n```\n\nYou can even shutdown Windows:\n\n```Smalltalk\nWinUserSession shutDown\n```\n\n----------------------------------------------------------------------\n\n### Console Support\n#### Accessing the Console \nThe *\"OS-Windows-Environment-Console\"* package provide access to the native windows console. It is possible to open a console for own custom I/O. You can get easy access using the class ***WinConsole***.\n\n```Smalltalk\nWinProcess default\n```\n\nIf evaluated in a workspace this associates the Pharo VM process with a standard output console. The console is a separate OS window that has the same icon as the Pharo main window. \n\n**Take care: closing this console means closing Pharo too (without getting asked for saving your changed).** \n\n\n#### Some simple output\nWhen the console window is displayed, you can easily continue to work with it and see the results:\n\n```Smalltalk\nWinConsole default \n\twrite: 'HelloWorld'\n```\n\nHave a closer look at the implementation and you will notice that it ends in the method ***#writeFile:size:*** which calls the [WriteFile][5] API from Windows.\n \n\n#### Cleaning up your work\n\nUsing the ***#clearscreen*** message you can clean up the contents of the console window:\n\n```Smalltalk\nWinConsole default \n\tclearscreen\n```\n\nIf you are done with playing with the console you can just reset it:\n\n```Smalltalk\nWinConsole reset\n```\n\nThis will free up any native resource associated with it.\n\n\n#### Positioning\n\nBy setting the cursor position you can define where the output should go\nwithin the console window:\n\n```Smalltalk\n|con|\nWinConsole reset.\ncon := WinConsole default.\ncon cursorPosition: 10@10.\ncon write: 'A simple positioned text'\n```\n\nTo ask the console for the possible size of the screen buffer you can \nuse the following expression:\n\n```Smalltalk\n|con|\ncon := WinConsole default.\ncon screenBuffer size inspect\n```\n\n#### Coloring text\n\nIf you like you can change the colors that are used for printing the text. \n\n```Smalltalk\nWinConsole default \n\tforegroundColor: WinConsoleForegroundColor red\n\tbackgroundColor: WinConsoleBackgroundColor yellow;\n\twrite: 'Colored text'\n```\n\nNote that the console supports a few standard colors - have a look at the subclasses of ***WinConsoleColor*** for more informations.\n\nInternally these standard colors are defined as text attributes encoded in 1 byte (with the upper 4 bits for the background color and the 4 lower bits for the foreground color). To display any possible color combinations for the standard color use the following expression:\n\n ```Smalltalk\n|con|\nWinConsole reset.\ncon := WinConsole default.\n\t\n\"Display all color combinations\"\n1 to: 256 do: [ :each |\n    WinConsole default \n       setConsoleTextAttribute: each;\n       write: 'O']\n```\n\nWindows (starting with Windows Vista) also supports more colors for the console window - it is planned to integrate this in a future release of the Pharo interface.\n\n\n#### Color management\n\nYou can combinate the color attribute and clearing the screen to affect the whole window:\n\n```Smalltalk\nWinConsole default \n    foregroundColor: WinConsoleForegroundColor red\n    backgroundColor: WinConsoleBackgroundColor yellow;\n    clearscreen;\n    write: 'Red text on yellow'\n```\n\nor\n\n```Smalltalk\nWinConsole default \n    blackOnWhite;\n    clearscreen\n```\n\n#### Cursor properties\n\nBeside positioning the cursor with ***#cursorPosition:*** you can also change its size using ***#cursorSize:***:\n\n```Smalltalk\nWinConsole default \n    cursorSize: 2\n```\n\nNote that you have to click into the console window to see an effect on the blinking cursor. You can even hide the cursor:\n\n```Smalltalk\nWinConsole default\n hideCursor\n```\n\nto make it visible again afterwards:\n\n```Smalltalk\nWinConsole default\n\tdisplayCursor\n```\n\n#### Accessing the console window\n\nYou can also access the frame window that is displaying the console. So you can easily use any window functionality that is provided:\n\n```Smalltalk\nWinConsole default \n    consoleWindow title: 'Pharo console'\n```\n\n----------------------------------------------------------------------\n\n### Unit Testing\n#### SUnit\n\nThe package comes with many tests that can also help to understand how to use the code. If you want to run the test just open the TestRunner and filter on \"OS\".\n\n#### Writing tests\n\nWriting tests for contributions is a good style and allows to see if things are broken. So if possible write also SUnit tests. There is a special superclass **WindowsSpecificTest** that you should use, with this you can make sure the tests run only on windows machines and will be ignored on other platforms. \n\n----------------------------------------------------------------------\n# Linux Support \n## OS-Linux project\n\nLinux support is defined in the project The **[OS-Linux][2]** - a subproject of **[OS project][6]** \n \n### Installation \n...\n\n\n----------------------------------------------------------------------\n## Continuous Integration (CI)\n### The CI jobs\n\nThe project is checked using the Pharo CI server, see the following locations:\n\n- [https://ci.inria.fr/pharo-contribution/job/OSWindows/][8]\n\n----------------------------------------------------------------------\n## History\n\nMigrated from [http://www.smalltalkhub.com/#!/~OS/OS-Windows](http://www.smalltalkhub.com/#!/~OS/OS-Windows)\n\n## Contribute\n### How to contribute\n\nThe project is released as is. It may not be complete yet - but as time and contributions permit will make more and more functionality of the underlying OS API available.\n\nUse it at your own risk and feel free to help extending it.  \n\nTo contribute just create an own account on SmalltalkHub and join the [\"OS\" team on Smalltalkhub][6] by asking on the [Pharo developer mailinglist][7] to become a new team member. \n\n  [1]: http://www.pharo.org\n  [2]: http://smalltalkhub.com/#!/~OS/OS-Windows\n  [3]: http://files.pharo.org/platform/\n  [4]: http://www.seaside.st\n  [5]: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747%28v=vs.85%29.aspx\n  [6]: http://smalltalkhub.com/#!/~OS\n  [7]: http://lists.pharo.org/\n  [8]: https://ci.inria.fr/pharo-contribution/job/OSWindows/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastares%2FPharo-OS-Windows","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fastares%2FPharo-OS-Windows","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fastares%2FPharo-OS-Windows/lists"}