When running a PowerShell script on a x64-bit OS platform, how can you determine in the script what version of PowerShell (32-bit or 64-bit) the script is running on?
Background
Both 32-bit and 64-bit versions of PowerShell are installed by default on a 64-bit platform such as Windows Server 2008. This can lead to difficulties when a PowerShell script is ran that must target a specific architecture (i.e. using 64-bit for a script for SharePoint 2010, in order to consume the 64-bit libraries).
Related question:
What is the best way to program against powershell's x64 vs. x86 variability? This question deals with code running against both 32-bit and 64-bit architectures. My question deals with the case when you want to ensure the script only runs against the correct version.
If you're shell is running on .NET 4.0 (PowerShell 3.0):
PS> [Environment]::Is64BitProcess
True
To determine in your script what version of PowerShell you're using, you can use the following helper functions (courtesy of JaredPar's answer to an related question):
# Is this a Wow64 powershell host
function Test-Wow64() {
return (Test-Win32) -and (test-path env:\PROCESSOR_ARCHITEW6432)
}
# Is this a 64 bit process
function Test-Win64() {
return [IntPtr]::size -eq 8
}
# Is this a 32 bit process
function Test-Win32() {
return [IntPtr]::size -eq 4
}
The above functions make use of the fact that the size of System.IntPtr is platform specific. It is 4 bytes on a 32-bit machine and 8 bytes on a 64-bit machine.
Note, it is worth noting that the locations of the 32-bit and 64-bit versions of Powershell are somewhat misleading. The 32-bit PowerShell is found at C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe, and the 64-bit PowerShell is at C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe, courtesy of this article.
You can use this as well. I tested it on PowerShell version 2.0 and 4.0.
$Arch = (Get-Process -Id $PID).StartInfo.EnvironmentVariables["PROCESSOR_ARCHITECTURE"];
if ($Arch -eq 'x86') {
Write-Host -Object 'Running 32-bit PowerShell';
}
elseif ($Arch -eq 'amd64') {
Write-Host -Object 'Running 64-bit PowerShell';
}
The value of $Arch will either be x86 or amd64.
EDIT:
The caveat is that Process.StartInfo.EnvironmentVariables always returns the environment of the current process, no matter which process you execute it on.
With Windows itself (and PowerShell) now supported on more architectures, like ARM64, it might not always be enough to check whether the application is 64-bit.
[Environment]::Is64BitProcess will also return True on Windows running on ARM64, so you cannot rely on it if what you really need to know is whether you're running on AMD64. To do this, on Windows you can use the following environment variable:
$Env:PROCESSOR_ARCHITECTURE, which returns values like AMD64, Arm64, or x86.
Switch([IntPtr]::size * 8) {
32 { <#your 32 bit stuff#> ;break }
64 { <#your 64 bit stuff#> ;break }
}
Related
I searched all day to find out a solution for sqlsrv dll on php 7 VC14 x64 Thread Safe and i did not found a solution. Does anyone solved this issue :
[04-Oct-2015 19:48:05 UTC] PHP Warning: PHP Startup: pdo_sqlsrv: Unable to initialize module
Module compiled with module API=20131226
PHP compiled with module API=20141001
These options need to match
in Unknown on line 0
Here is my php7 RC4 informations :
System Windows NT 6.0 build 6002 (Windows Server 2008 Standard Edition Service Pack 2) AMD64
Build Date Sep 29 2015 17:15:28
Compiler MSVC14 (Visual C++ 2015)
Architecture x64
sqlsrv isn't ready for PHP7 yet but that's not true it wasn't released since 2012. Last release is from May 2015. Maintainer is Microsoft and version for PHP7 is planned on the beginning of next year.
https://github.com/Azure/msphpsql/issues/58
Update:
Driver is available for PHP up to 7.1 version even for Linux today (March 2017).
https://github.com/Microsoft/msphpsql
For future reference (tested on Windows 7 with Xampp and PHP 7.0.13):
Download and install ODBC drivers here: https://www.microsoft.com/en-US/download/details.aspx?id=36434
Download the DLL here (both 7.0. and 7.1.can be found): https://github.com/Microsoft/msphpsql/releases
Open your "php.ini" file and look for the "extension_dir" line. This will tell you where to put the DDL files. Note: On Xampp, it should be something like: "C:\xampp\php\ext"
Put the DLL files contains in the Zip archive in your extension directory. Make sure to select the proper select the proper version. Note: I initially tried to use the x64 version, but it didn't work. Then, I replaced the DLL with the x86 version and it finally worked.
Back in your "php.ini" file, you need to add the following line: "extension = php_pdo_sqlsrv_7_ts.dll". Note: Xampp use the tread safe version.
Make sure to restart your apache service.
Code sample for testing:
$db = "the name of your database"
$password = "password";
$server = "IP address or named pipe";
$user = "username"
try {
$connection = new PDO(
"sqlsrv:Server=" . $server .
";Database=" . $db,
$password,
$user
);
$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $exception) {
var_dump($exception);
}
For the record, the direct link to the sql server libraries is here
sqlsrvr for php 7
Is the 32 and 64 bits version both for ts and nts
What happens:
I execute the following command.
java -jar sat4j-sat.jar -remote
No window opens, and I get a console output same as without the -remote flag, which begins:
c SAT4J: a SATisfiability library for Java (c) 2004-2013 Artois (...)
c This is free software under the dual EPL/GNU LGPL licenses.
c See www.sat4j.org for details.
c version 2.3.4.v20130419
c java.runtime.name OpenJDK Runtime Environment
c java.vm.name OpenJDK Client VM
c java.vm.version 24.65-b04
c java.vm.vendor Oracle Corporation
c sun.arch.data.model 32
c java.version 1.7.0_65
c os.name Linux
c os.version 3.2.0-4-686-pae
(...)
What is expected:
From readme.txt:
To run sat4j with on the fly configuration:
java -jar sat4j-sat.jar -remote
These instructions should open a java window named Remote Control. We
assume that the 1.5 version of the java command is in your path. If
it isn’t, then you should either specify the complete path to the java
command or update your PATH environment variable as described in the
installation instructions for the Java 2 SDK.
Other details
I have tried multiple versions of the library, up to 2.3.4.
My system is Debian 7 with Gnome 2.
My default Java installation is OpenJDK 1.7.0_65.
My secondary Java installation is Oracle Java 1.8.0_45 (with the same issue).
Gnuplot 4.6 is installed.
My first machine has a 32 bit dual core CPU with 2GB of RAM.
My second machine has a 64 bit quad core CPU with 8GB of RAM with nearly identical software.
Question
Has anyone used SAT4J's remote control feature? What is the problem with my method?
Update
On another machine (64 bit Debian 7) the window opens. After start dat files are created, but plotting does not start.
Update 2
I ran the generated instance.dimacs-gnuplot.gnuplot file manually from a gnuplot terminal, and I got the message unknown or ambiguous terminal type for the x11 type. I installed the gnuplot-x11 package, and now it works on the workplace machine: I can see the diagrams (wow!). Unfortunately on my home machines the Remote Control window still doesn't open.
The -remote parameter is used to display the remote control, i.e. to setup the various parameters of the solver.
If you want to always monitor what the solver is doing, you need to use in conjunction the -r parameter.
So the complete command line should be:
java -jar sat4j-sat.jar -r -remote file.cnf
You can get a fresh snapshot of Sat4j Sat on our continuous integration server:
http://bamboo.ow2.org/browse/SAT4J-DEF2-41/artifact/JOB1/nightly_build/
This might solve the issue you met with the 2.3.4 release.
Cheers,
Daniel
I struggled on this issue for a few days but didn't get a right answer yet.
Here is the Problem Description:
I wrote a normal Java program (Program-A), and wrote a Windows-based native agent (*.dll, written in C/C++) with Agent_OnLoad, Agent_OnAttach, Agent_OnUnload method, which works fine if using Java command-line flag (-agentlib). Then I wrote another Java program to attach the native agent onto a runing the Java Program-A (see the below code piece for VM attach and loadAgentPath), however I got the exception:
com.sun.tools.attach.AgentLoadException: Failed to load agent library
I tried to change the agentPath (absolute or relative file path) this or that way, none of these works. Should I try some other way to make this work. What I need is to attach a native agent onto a runing java program rather than using command-line flag.
Does anyone know the root cause or a clue for the solution?
BTW, the command line to run attach VM Java code as:
java -Djava.library.path=D:\DevTools\Java7\jre7\bin -classpath .;./tools.jar com.xxx.TestAgentVMAttacher
...
VirtualMachine virtualMachine = com.sun.tools.attach.VirtualMachine.attach(pid); // Note: this code line is executed normally, I am sure the pid is correct
...
agentPath = theFilePath + "/myagent.dll"; // Note: I am sure the dll file path is correct
virtualMachine.loadAgentPath(agentPath,null); // Note: this code line would cause the exception (AgentLoadException) as I mentioned above, no matter how I set the agentPath, even I set it as null, same exception happened.
Environment related info:
- OS: Windows XP
- Java Version: Java(TM) SE Runtime Environment (build 1.7.0-b147)
Eventually I found the answer for my question, I had a wrong method name ('Agent_Attach') in Agent.cpp file, the correct one should be 'Agent_OnAttach', with this fix, my agent lib (.dll) can be loaded to a running Java program now.
I compile my .dll with the following command: gcc -mno-cygwin -I"/cygdrive/c/Program Files/Java/jdk1.7.0_04/include" -I"/cygdrive/c/Program Files/Java/jdk1.7.0_04/include/win32" -Wl,--add-stdcall-alias -shared -o CalculatorFunctions.dll CalcFunc.c
I use GlassFish for Eclipse. The whole system is a CORBA client-server. When I start the server from Eclipse - it's fine. But when I try to run the server from the CMD (because I want to set a port and host address for the server) it gives me: Exception: ... .dll: Can't load AI 32-bit .dll on a AMD 64-bit platform
I searched through other topics and saw that I should try with changing my JDK to 32 bit - didn't work again.
So the other solution I read about is to compile the .DLL as 64 bit. What command I need to use or how I do that at all ?
Thanks in advance! :)
You need not only a command but whole 64-bit MinGW toolchain - a 64bit compiler in the first place. Then the parameters to your gcc invocation should work the same.
Beware that 64bit is not just a matter of compilability. Primitive data types have different sizes, so any code making assumptions without sizeof checking is a potential issue. Most prominently, pointer arithmetic.
I've written the simplest injection dll possible. Here is the code in its entirety:
#include "stdafx.h"
#include <stdio.h>
BOOL APIENTRY DllMain(HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved)
{
FILE * File = fopen("D:\\test.txt", "w");
if(File != NULL)
{
fclose(File);
}
return TRUE;
}
Super simple right? Well I can't even get this to work. This code compiles to a dll and I've placed the path to this dll in the registry under [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs]. I should also mention that LoadAppInit_DLLs registry value is set to 1. From doing this I expect to see the file "D:\test.txt" appear when I start other applications (like notepad.exe), but it doesn't. I don't get it. There is another .dll, which is very old and written in visual studio '97, (which I'm trying to replace) that works just fine when I set AppInit_DLLs to point to it and start an arbitrary application. I can tell that it is getting loaded when other applications are started.
I'm not sure whats going on here, but this should work shouldn't it? It can't get any simpler. I'm using VS 2010, by all accounts I think I've created a very plane Jane .dll so I don't think any project settings should be out of whack, but I'm not completely sure about that. What am I missing here?
Setup Info
OS: Windows 7 64-bit
OS Version: 6.1.7601 Service Pack 1 Build 7601
IDE: Visual Studio 2010
IDE version: 10.0.40219.1 SP1Rel
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs]
is NOT the registry key used for injection for into 32-bit processes. Its the registry key if your OS is 32-bit.
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs] is the correct registry key to use if your OS is 64-bit.
I was under the assumption that the former was for 32-bit processes and the latter was for 64-bit processes. But really, the OS is going to ignore one of those registry keys depending on whether or not the OS itself is 64-bit or 32-bit.
#Ultratrunks: This is not completely correct.
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs ] is for both 32 as well as 64 bit OS.
But If we want to run 32 bit processes on 64 bit machine then we need to modify the following registry key-
[HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs]
Wow is basically concept of making 64 bit system to be compatible of running 32 bit processes.
I verified it after running my programs on both 32 as well as 64 bit OS and running 32 bit processes on 64 bit machine.
Hence
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs for 32/64 bit OS
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\Windows\AppInit_DLLs for 32 bit processes on 64 bit OS
First at all about the SOFTWARE\Microsoft vs SOFTWARE\Wow6432Node\Microsoft it's true that if both 32 or 64 so go into SOFTWARE\Microsoft and if you want to inject 32 bit dll in OS64 so go into SOFTWARE\Wow6432Node\Microsoft.
My problem was that the value need to be up to 8 characters and if there is in the path or name above this you need to use shortcut.
Example: if your dll name is inject~1.dll
Don't Forget to set all three reg value
AppInit_DLLs -> dllname if is in system32 or full path with out "
LoadAppInit_DLLs -> 1
RequireSignedAppInit_DLLs -> 0