홈 > 자료
자료 보관
[Java] "ORA-01000 : 최대 열기 커서 수를 초과했습니다"주의 사항
- 2011 년 6 월 29 일 12:00 AM
- 자료
일전에 우연히 만났다 "ORA-01000 : 최대 열기 커서 수를 초과했습니다"라는 OracleDB 오류에 대한 메모.
문제가 된 것은 다음과 같은 코드
(업무 코드를 쬐는 것 가지 않기 때문에 예제로 다시 작성되었습니다. 동작 미확인)
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; public class cursorLeakeSample { public cursorLeakeSample(List idList) { try { // Oracle JDBC Driverのロード Class.forName("oracle.jdbc.driver.OracleDriver"); // コネクション取得 Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "scott", "tiger"); String sql = "SELECT NAME FROM ITEM WHERE ID = ?"; PreparedStatement statement = null; try { for (String id : idList) { Object[] params = new Object[] { id }; // SQLにパラメータ埋め込みと実行statement = connection.prepareStatement(sql); statement.setObject(1, params[0]); statement.executeUpdate(); connection.commit(); } } catch (SQLException e) { // SQL実行失敗 connection.rollback(); e.printStackTrace(); } finally { statement.close(); connection.close(); } } catch (SQLException e) { // コネクションの接続・切断・ロールバック、ステートメントの解放に失敗 e.printStackTrace(); } catch (ClassNotFoundException e) { // Oracle JDBC ドライバが見つからなかった e.printStackTrace(); } } }import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; public class cursorLeakeSample { public cursorLeakeSample(List idList) { try { // Oracle JDBC Driverのロード Class.forName("oracle.jdbc.driver.OracleDriver"); // コネクション取得 Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "scott", "tiger"); String sql = "SELECT NAME FROM ITEM WHERE ID = ?"; PreparedStatement statement = null; try { for (String id : idList) { Object[] params = new Object[] { id }; // SQLにパラメータ埋め込みと実行statement = connection.prepareStatement(sql); statement.setObject(1, params[0]); statement.executeUpdate(); connection.commit(); } } catch (SQLException e) { // SQL実行失敗 connection.rollback(); e.printStackTrace(); } finally { statement.close(); connection.close(); } } catch (SQLException e) { // コネクションの接続・切断・ロールバック、ステートメントの解放に失敗 e.printStackTrace(); } catch (ClassNotFoundException e) { // Oracle JDBC ドライバが見つからなかった e.printStackTrace(); } } }
강조하고있는 곳이 원인이 된 부분입니다.
왜 안되는 것인지 알 수 있습니까?
먼저 변수 statement 빈 상자로 만들어 루프에서 얻은 값을 넣어 사용 돌고 마지막으로 방출.
보기 해방 누설을 일으키고있는 듯이 보이지만, 조금 처리를 쫓으면 문제를 찾을 수 있습니다.
"prepareStatement"는 SQL의 사전 준비를 위해 암시적으로 커서를 생성합니다.
이것을 알고 문제의 코드는 루프에서 많은 암시적 커서가 생성되는 것입니다.
그리고, 해방되는 것은 루프 밖으로 빠져나가지 때 저장되어 있던 마지막 "prepareStatement"의 하나.
예를 들어, 20 개의 처리를 한 경우 19 건은 해제할 수 없다는 것입니다.
그럼, 어떻게 쓰면 좋을지
import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; public class cursorLeakeSample { public cursorLeakeSample(List idList) { try { // Oracle JDBC Driverのロード Class.forName("oracle.jdbc.driver.OracleDriver"); // コネクション取得 Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "scott", "tiger"); String sql = "SELECT NAME FROM ITEM WHERE ID = ?"; PreparedStatement statement = connection.prepareStatement(sql); try { for (String id : idList) { Object[] params = new Object[] { id }; // SQLにパラメータ埋め込みと実行 statement.setObject(1, params[0]); statement.executeUpdate(); connection.commit(); } } catch (SQLException e) { // SQL実行失敗 connection.rollback(); e.printStackTrace(); } finally { statement.close(); connection.close(); } } catch (SQLException e) { // コネクションの接続・切断・ロールバック、ステートメントの解放に失敗 e.printStackTrace(); } catch (ClassNotFoundException e) { // Oracle JDBC ドライバが見つからなかった e.printStackTrace(); } } }import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.SQLException; import java.util.List; public class cursorLeakeSample { public cursorLeakeSample(List idList) { try { // Oracle JDBC Driverのロード Class.forName("oracle.jdbc.driver.OracleDriver"); // コネクション取得 Connection connection = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:ORCL", "scott", "tiger"); String sql = "SELECT NAME FROM ITEM WHERE ID = ?"; PreparedStatement statement = connection.prepareStatement(sql); try { for (String id : idList) { Object[] params = new Object[] { id }; // SQLにパラメータ埋め込みと実行 statement.setObject(1, params[0]); statement.executeUpdate(); connection.commit(); } } catch (SQLException e) { // SQL実行失敗 connection.rollback(); e.printStackTrace(); } finally { statement.close(); connection.close(); } } catch (SQLException e) { // コネクションの接続・切断・ロールバック、ステートメントの解放に失敗 e.printStackTrace(); } catch (ClassNotFoundException e) { // Oracle JDBC ドライバが見つからなかった e.printStackTrace(); } } }
아마 이렇게. "PreparedStatement"를 사용한다면.
그냥 "Statement"를 이용한다면 for 문장에서 close ();하면 좋을까 생각합니다.
[Java] 클래스 경로의 동적 추가
- 2011 년 6 월 20 일 12:00 AM
- 자료
다른 시스템의 Jar와 Tomcat의 WEB-INF/classes 뭔가를 참조하는 프로그램을 만들고 싶었다 조사하고 나름대로 구현했기 때문에 참고.
" One-Jar "라든가" Fat Jar "에 대응할 수있는 경우는 그 쪽을 이용하는 것이 좋다고 생각한다.
덧붙여서, 동작 확인은 JRE5하고 Jar 정리한 시에도 동작하는 것을 확인했다.
package jp.moonwing.net; import java.io.File; import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.net.URLClassLoader; /** * クラスパスの動的追加 * * @author $Author: U.Yobane $ * @version $Version: v 043b2b764886 2011/06/13 01:23:25+0900(JST) $ */ public final class ApplicationClassLoader { /** クラス情報格納フィールド */ private static final Class<?>[] PARAMETERS = new Class<?>[] { URL.class }; /** * コンストラクタ */ private ApplicationClassLoader() { } /** * メイン * * @param args 起動引数文字列配列 */ public static void main(String[] args) { try { // クラスパスの追加 addClassPath( {追加したいクラスパスディレクトリ} ); addClassPath( {追加したいJAR} ); // メインプログラムを実行 Application.execute(args); } catch (IOException e) { e.printStackTrace(); } } /** * クラスローダーにクラスパスを動的追加 * * @param classPath 追加するクラスパス * @throws IOException クラスパスの動的追加に失敗 */ public static void addClassPath(String classPath) throws IOException { addClassPath(new File(classPath)); } /** * クラスパスを再帰的にたどり、追加可能パスはすべて追加 * * @param classPath 追加するファイル * @throws IOException クラスパスの動的追加に失敗 */ private static void addClassPath(File classPath) throws IOException { if (classPath.isDirectory()) { // ディレクトリを追加 addClassPath(classPath.toURL()); // ディレクトリ配下を探索 File[] child = classPath.listFiles(); for (int i = 0; i < child.length; i++) { addClassPath(child[i]); } } else { String suffix = getSuffix(classPath.getName()); // 見つかったファイルがJARもしくはZipの場合は追加 if (suffix.equalsIgnoreCase("zip") || suffix.equalsIgnoreCase("jar")) { addClassPath(classPath.toURL()); } } } /** * システムクラスローダーにクラスパスを強制的に追加 * * @param classPathUrl クラスパス * @throws IOException クラスパスの動的追加に失敗 */ private static void addClassPath(URL classPathUrl) throws IOException { URLClassLoader sysloader = (URLClassLoader) ClassLoader.getSystemClassLoader(); Class<?> sysclass = URLClassLoader.class; try { Method method = sysclass.getDeclaredMethod("addURL", PARAMETERS); method.setAccessible(true); method.invoke(sysloader, new Object[] { classPathUrl }); } catch (NoSuchMethodException e) { throw new IOException("could not add " + classPathUrl + " to classpath"); } catch (InvocationTargetException e) { throw new IOException("could not add " + classPathUrl + " to classpath"); } catch (IllegalAccessException e) { throw new IOException("could not add " + classPathUrl + " to classpath"); } } /** * ファイル名から拡張子を返却 * * @param fileName ファイル名 * @return ファイルの拡張子 */ private static String getSuffix(String fileName) { if (fileName == null) { return null; } int point = fileName.lastIndexOf("."); if (point != -1) { return fileName.substring(point + 1); } return fileName; } } [C # 응용 프로그램의 UAC 지원
- 2011 년 4 월 17 일 12:00 AM
- 자료
응용 프로그램에서 일반 권한과 관리자 권한과에서 동작을 변경하려면 메모
- WindowsVista 이상 (UAC 탑재 OS)에서 실행되고 있는지 <br /> 응용 프로그램 WindowsVista 이상 실행되고 있는지 여부를 OS 버전 정보를 확인하려면
using System; private bool IsUAC() { OperatingSystem osInfo = Environment.OSVersion; if (osInfo.Platform == PlatformID.Win32NT) { if (osInfo.Version.Major == 6) { if (osInfo.Version.Minor == 0) { // Windows Vista, Windows Server 2008 return true; } else if (osInfo.Version.Minor == 1) { // Windows 7, Windows Server 2008 R2 return true; } } else if (osInfo.Version.Major > 6) { // new Windows return true; } } return false; } - 응용 프로그램이 관리자 권한으로 실행되었는지 <br /> 응용 프로그램을 "관리자로 실행"되는 때
using System.Security.Principal; private bool IsAdministrator() { bool isAllowed = false; try { WindowsIdentity wi = WindowsIdentity.GetCurrent(); WindowsPrincipal wp = new WindowsPrincipal(wi); isAllowed = wp.IsInRole(WindowsBuiltInRole.Administrator); } catch { isAllowed = false; } return isAllowed; } - 응용 프로그램을 시작하는 사용자는 Administrators 그룹에 속하는지 <br /> 응용 프로그램은 일반적 권한으로 시작되었다해도 시작하는 사용자가 관리자로 승격 수 있는지 알고 싶을 때
using System.DirectoryServices.AccountManagement; private bool IsAdministrators() { bool isAllowed = false; try { PrincipalContext pc = new PrincipalContext(ContextType.Machine, null); UserPrincipal up = UserPrincipal.Current; GroupPrincipal gp = GroupPrincipal.FindByIdentity(pc, "Administrators"); if (up.IsMemberOf(gp)) { isAllowed = true; } } catch { isAllowed = false; } return isAllowed; }위의 코드라고 어떤 환경에서 잘 작동하지 같아? 아래의 코드가 더 확실 할지도.
using System.DirectoryServices.AccountManagement; private bool IsAdministrators() { bool isAllowed = false; try { PrincipalContext pc = new PrincipalContext(ContextType.Machine, null); UserPrincipal up = UserPrincipal.Current; foreach (GroupPrincipal gp in up.GetGroups()) { try { if (gp.Name.ToLower().Equals("Administrators".ToLower())) { isAllowed = true; } } finally { gp.Dispose(); } } } catch { isAllowed = false; } return isAllowed; } - 응용 프로그램을 관리자 권한으로 다시 시작 <br /> 처리를하는 동안 관리자 권한이 필요할 경우 자신을 관리자 권한으로 다시 시작
using System; using System.Diagnostics; private void RestartApplication() { ProcessStartInfo psi = new ProcessStartInfo(); psi.UseShellExecute = true; psi.WorkingDirectory = Environment.CurrentDirectory; psi.FileName = Application.ExecutablePath; psi.Verb = "runas"; try { Process p = Process.Start(psi); } catch { return; } Application.Exit(); } - 관리자 권한이 필요한 버튼 UAC (방패) 아이콘을 표시 <br /> 작업을 계속하려면 관리자 권한이 필요한 것을 사용자에게 알리기 위해 버튼에 UAC (방패) 아이콘 표시 (SystemIcons.Shield 속성 방패 아이콘과 Win32API의 방패 아이콘은 차이가 있으며, Windows 7에서 표준으로 사용되고있는 것은 Win32 API의 편이다.)
using System; using System.Windows.Forms; using System.Runtime.InteropServices; namespace Sample { public partial class Form1 : Form { [DllImport("user32.dll")] private static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam); // 第2パラメータ:盾アイコンを設定するフラグ uint BCM_SETSHIELD = 0x0000160C; public Form1() { InitializeComponent(); // ボタンの外観を「System」にする必要がある button1.FlatStyle = FlatStyle.System; } private void checkBox1_CheckedChanged(object sender, EventArgs e) { // 第1パラメータ:ボタンのウィンドウ・ハンドル HandleRef hwnd = new HandleRef(button1, button1.Handle); if (checkBox1.Checked) { SendMessage(hwnd, BCM_SETSHIELD, new IntPtr(0), new IntPtr(1)); } else { SendMessage(hwnd, BCM_SETSHIELD, new IntPtr(0), new IntPtr(0)); } } } }
PSP의 백라이트 퓨즈 교체
- 2011 년 1 월 5 일 12:00 AM
- 자료
PSP-1000의 화면이 갑자기 나타나지되었다.
소리는 들리고, 버튼도 효과가있다 소리가 난다.
눈여겨 보면 얇은 배낭 표시가되어 있었다.
이 상황에서 백라이트가 끊어 졌다고 추측하고 인터넷에서 정보를 보면 역시 선구자가 계신다.
정중하게 백라이트 퓨즈 위치까지 공개 해주고 있었으므로 조속히 분해 퓨즈의 연속성을 확인 해 본다.
디지털 멀티미터는 반응 없음이지만, 퓨즈 자체는 1005 사이즈의 칩 퓨즈 저 저 제대로 측정할 수 있는지 몰랐다.
예를 들어, 표면에 얇은 막을 라든지 있으면 측정할 수없는 것이고.
타눈매로 교체보기로했다.
교환 대상은 F4501의 0.5A 퓨즈.
우선 방침으로 교환하는 것을 생각하고 있었지만 솔더가 생각하는 것처럼 녹지 않고 단념.
그래서 병렬로 붙이기로했다.
이것이라면, 엄밀하게는 이것도 잘 아니지만 (기존의 퓨즈가 살아있다면, 전류가 분배되므로)
이 작업 백라이트가 복구된 경우, 퓨즈이 꺼져있는 것으로 생각할 수 있고,
안되면 별도 원인이있는 것처럼 제외하면 좋기 때문에.
이 작업을 실시한 결과 무사히 백라이트가 복구.
다시 PSP에서 즐길 수있게되었다.
玄상자의 전원 수리
- 2011 년 1 월 4 일 12:00 AM
- 자료
玄 상자의 전원 플러그를 가린 채 실수로 전원을 만져 버려, 퓨즈를 끊어 버렸다 때문에 그 수리 작업을 기록
玄 상자는 초대 무인 것.
전원 플러그를 뺀 생각 이었지만 실제로 뺀 것은 다른 전원에서 현 상자의 전원은 빠져 있었다.
빠져있는 것으로 작업을했기 때문에 전원 퓨즈 저항의 다리를 만져 버립니다 파란 불꽃이 튀었다.
저리 손에 눈길도주지 않고 서둘러 결함이 없는지 확인하기 위해 전원을 켜기도 아니나 다를까 전원이 들어가지 않고.
이렇게, 玄 상자의 전원이 꼬리 죽는 하셨을. 이렇게되면 뒷북.
코믹하면서 인터넷에서 정보를 찾아보니 역시 단락되어 버린 사람이 퓨즈를 교체 복구하고 있었다.
우선, 자신의 경우도 휴즈 조각은? 생각 디지털 멀티미터 휴즈 (F1)의 연속성을 확인한다.
결과 도통하고 있지 않다. 즉 휴즈가 끊어져있다.
이것은 럭키지도 모른다.
왜냐하면 퓨즈 보호 회로에서 과도 전류 및 과도 전압 이상 온도가되면 회로가 손상되지 않도록 회로를 차단하기위한 것이기 때문에 다른 부분이 손상되지 않을 수있다는 것으로 럭키지도 모른다.
반대로 휴즈의 도통을 확인할 수있다면 다른 부분이 손상되어, 원인을 파악하기 어렵다.
그런데, 인터넷의 정보를 바탕으로 리드 퓨즈 3A를 아키하바라에서 찾은 곳에 라디오 센터 코누마 있었다.
2 개 150 엔이었다. 역시 아키하바라구나라고 생각하면서 귀로에 대해서, 조속히 교체 작업을 실시하면 발각 문제가
왜냐하면 원래 붙어 퓨즈는 잘 보면 2A라고 써있다.
퓨즈 자체 회로를 연결하기만 것이니까 3A에서도 동작하지만, 과전류 때 2A였던 것도이 3A까지 정상으로되어 버린다.
이것은 과전류시 휴즈 이외의 부분을 손상 가능성이 태어나는 위해 새롭게 교체하는 사람은 2A를 구입하도록.
또한 구입한 리드 퓨즈 리드 조금 굵은 이었지만 문제없이 환장 수 있었다.
그리고 전원을 켜면 무사히 시작할 수 있는지 확인했다.
2A의 리드 퓨즈를 발견하면 교환하려고 · · ·
[VS] 소프트웨어 게시자 인증서 작성 및 서명
- 2010 년 11 월 27 일 12:00 AM
- 자료
아티팩트에 인증서를 서명하는 데 만들기 및 서명 방법을 참고.
자체 서명된 인증서 라든지, 올레 인증서라고 불리는 것으로 VSTO 설치 ClickOnce를 사용하는 경우 필요한 것.
사용 도구는 WindowsSDK 에 포함되어있다.
- 만드는 방법
rem 1.==== rem CA:Certificate Authority:認証局証明書rem 会社名 : MoonWing rem 組織名 : MoonWing Authority Root CA rem 県 名 : Tokyo rem 国 名 : JP rem 有効期限: 2012.12.31 "%ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\makecert" -r -n "C=JP, S=Tokyo, OU=MoonWing Authority Root CA, O=MoonWing" -e 12/31/2012 -a sha1 -cy authority -sv moonwingCA.pvk moonwingCA.cer rem 秘密キーのパスワードの作成:Subject Key: rootCA rem 秘密キーのパスワードの入力:Subject Key: rootCA rem 2.==== rem EE:End Entity:署名用証明書rem コモン名: MoonWing rem 会社名 : MoonWing rem 組織名 : MoonWing Development rem 県 名 : Tokyo rem 国 名 : JP rem 有効期限: 2012.12.31 "%ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\makecert" -n "CN=MoonWing, C=JP, S=Tokyo, O=MoonWing, OU=MoonWing Development" -e 12/31/2012 -sv moonwing.pvk -ic moonwingCA.cer -iv moonwingCA.pvk -nscp -cy end moonwing.cer rem 秘密キーのパスワードの作成:Subject Key: endEntity rem 秘密キーのパスワードの入力:Subject Key: endEntity rem 秘密キーのパスワードの入力:Issuer Signature: rootCA rem 3.==== rem SPC:Software Publisher's Certificate:ソフトウェア発行元証明書"%ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\Cert2SPC" moonwing.cer moonwingCA.cer moonwing.spc rem 4.==== rem PFX:Personal Information Exchange:PKCS#12 rem -pi(pvkpassword):endEntity rem -po(pfxpassword):SPC "%ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\pvk2pfx" -pvk moonwing.pvk -pi endEntity -spc moonwing.spc -pfx moonwing.pfx -po SPC - 서명 방법
rem 5.==== rem target.exeへ署名rem -t(time stamp server):http://timestamp.verisign.com/scripts/timstamp.dll rem -p(pfxpassword):SPC "%ProgramFiles%\Microsoft SDKs\Windows\v7.1\Bin\signtool" sign /f moonwing.pfx /a /t http://timestamp.verisign.com/scripts/timstamp.dll /p SPC target.exe
[VS] PIA 공동 작업 정리
- 2010 년 11 월 19 일 12:00 AM
- 자료
PIA 버전과 Office 버전과. NetFramework 버전의 테이블을 VSTO 표 하는 김에 만들었습니다.
PIA는 PrimaryInteropAssembly하는 것으로 · · · 자세한 내용은 Microsoft 에 문의하십시오.
| PIA | 해당 Office | 대응. NetFramework | 해당 Windows |
|---|---|---|---|
| XP | XP | 1.1 | XP |
| 2003 | 2003 | 1.1 | 2000 SP3, XP, Server 2003 |
| 2007 | 2007 | 1.1 | 2000 SP4, XP SP2, Server 2003 |
| 2010 | 2010 | 2.0 or higher | 2000 SP4, XP SP2, Server 2003, Vista, 7, Server 2008 |
[VS] VSTO 공동 작업 정리
- 2010 년 11 월 18 일 12:00 AM
- 자료
VSTO 버전과 Office 버전과. NetFramework 버전의 테이블을 원하지되었으므로 만들 수 있습니다.
VSTO는
- Microsoft Visual Studio 2005 Tools for Office Second Edition Runtime
- Microsoft Visual Studio 2005 Tools for the 2007 Microsoft Office System
- Microsoft Visual Studio Tools for the Microsoft Office system (Version 3.0 Runtime)
- Microsoft Visual Studio 2010 Tools for the Microsoft Office System (Version 4.0 Runtime)
와 미묘하게 이름이 바뀌고있다 Office 확장용 구성 요소입니다.
기본적으로 위의 두 번째를 생략한 다음 세 가지면 문제 없을 것이다.
(또는 3 번째도 생략하고 좋을 결국 2 개로 2003,2007,2010에 대응할 수있게 될 것이고.)
| Vsto | 해당 Office | 대응. NetFramework | 해당 VisualStduio | 해당 Windows |
|---|---|---|---|---|
| 2005 SE | 2003,2007 | 2.0 | 2005 | 2000, XP, Server 2003, Vista, 7, Server 2008 |
| 3.0 | 2007 | 3.5 SP1 | 2008 | 2000, XP, Server 2003, Vista, 7, Server 2008 |
| 4.0 | 2007,2010 | 3.5 SP1 | 2010 | XP, Server 2003, Vista, 7, Server 2008 |
지시문
- 2010 년 8 월 4 일 12:00 AM
- 자료
크로스 플랫폼 코드를 작성할 때 플랫폼 의존적인 부분을 파악하는 전처 리기 지시문 참고.
- Compiler
- GCC
- # ifdef __ GNUC__
- # if __ GNUC__> = 3 / / GCC3.0 이상
- # ifdef __ GNUC__
- Borland C + +
- # ifdef __ BORLANDC__
- intel Compiler
- # ifdef __ INTEL_COMPILER
- Microsoft Compiler
- # ifdef _MSC_VER
- # if _MSC_VER> = 600 / / C Compiler 6.0 이상 VC + + 포함
- # if _MSC_VER> = 700 / / C / C + + Compiler 7.0 이상 VC + + 포함
- # if _MSC_VER> = 800 / / VC + +1.0 이상
- # if _MSC_VER> = 900 / / VC + +2.0 이상
- # if _MSC_VER> = 1000 / / VC + +4.0 이상
- # if _MSC_VER> = 1010 / / VC + +4.1 이상
- # if _MSC_VER> = 1020 / / VC + +4.2 이상
- # if _MSC_VER> = 1100 / / VC + +5.0 이상
- # if _MSC_VER> = 1200 / / VC + +6.0 이상
- # if _MSC_VER> = 1300 / / VC2002 (VC7.0) 이상
- # if _MSC_VER> = 1310 / / VC2003 (VC7.1) 이상
- # if _MSC_VER> = 1400 / / VC2005 (VC8.0) 이상
- # if _MSC_VER> = 1500 / / VC2008 (VC9.0) 이상
- # if _MSC_VER> = 1600 / / VC2010 (VC10.0) 이상
- # ifdef _MSC_VER
- GCC
- UNIX system
- UNIX
- # ifdef __ unix
- # ifdef __ unix__
- Linux
- # ifdef __ linux
- # ifdef __ linux__
- FreeBSD
- # ifdef __ FreeBSD__
- NetBSD
- # ifdef __ NetBSD__
- Cygwin
- # ifdef __ CYGWIN__
- # ifdef __ CYGWIN32__ / / 32bit 버전 Cygwin
- MinGW (-mno-cygwin)
- # ifdef __ MINGW32__
- UNIX
- Windows system
- CUI
- # ifdef _CONSOLE
- GUI
- # ifdef _WINDOWS
- 32bit Windows
- # ifdef WIN32
- # ifdef _WIN32
- 64bit Windows
- # ifdef _WIN64
- Windows version
- # ifdef WINVER
- # if (WINVER> = 0x030a) / / Windows 3.1 이상
- # if (WINVER> = 0 × 0400) / / Windows 95 / NT4.0 이상
- # if (WINVER> = 0 × 0410) / / Windows 98 이상
- # if (WINVER> = 0 × 0500) / / Windows Me / 2000 이상
- # if (WINVER> = 0 × 0501) / / Windows XP / Server 2003 이상
- # if (WINVER> = 0 × 0502) / / Windows XP SP2 / Server 2003 SP1 이상
- # if (WINVER> = 0 × 0600) / / Windows Vista / Server 2008 이상
- # if (WINVER> = 0 × 0601) / / Windows 7 이상
- # ifdef _WIN32_WINDOWS / / Windows9x
- # if (_WIN32_WINDOWS> = 0 × 0400) / / Windows 95 이상
- # if (_WIN32_WINDOWS> = 0 × 0410) / / Windows 98 이상
- # if (_WIN32_WINDOWS> = 0 × 0500) / / Windows Me 이상
- # ifdef _WIN32_WINNT / / WindowsNTx
- / / Windows 2000 이상 (0 × 0500)
# if (_WIN32_WINNT> = _WIN32_WINNT_WIN2K) - / / Windows XP / Server 2003 이상 (0 × 0501)
# if (_WIN32_WINNT> = _WIN32_WINNT_WINXP) - / / Windows XP SP2 / Server 2003 SP1 이상 (0 × 0502)
# if (_WIN32_WINNT> = _WIN32_WINNT_WS03) - / / Windows Vista 이상 (0 × 0600)
# if (_WIN32_WINNT> = _WIN32_WINNT_VISTA) - / / Windows Server 2008 이상 (0 × 0600)
# if (_WIN32_WINNT> = _WIN32_WINNT_WS08) - / / Windows 7 이상 (0 × 0601)
# if (_WIN32_WINNT> = _WIN32_WINNT_WIN7)
- / / Windows 2000 이상 (0 × 0500)
- # ifdef _WIN32_WCE / / WindowsCE
- # if (_WIN32_WCE> = 0 × 0420) / / Windows Mobile 2003 (PPC2003)
- # if (_WIN32_WCE> = 0 × 0421) / / Windows Mobile 2003 SE (PPC2003SE)
- # if (_WIN32_WCE> = 0 × 0501) / / Windows Mobile 5.0
- # if (_WIN32_WCE> = 0 × 0502) / / Windows Mobile 6 Professional / Classic
- # if (WINCEOSVER> = 0 × 0300) / / WindowsCE3.0 (PPC2002) 이상
- # if (WINCEOSVER> = 0 × 0420) / / WindowsCE4.2 (PPC2003) 이상
- # if (WINCEOSVER> = 0 × 0500) / / WindowsCE5.0 (WM5.0) 이상
- # ifdef WINVER
- Internet Explorer version
- # ifdef _WIN32_IE
- # if (_WIN32_IE> = 0 × 0200) / / Windows 95/NT 4.0 (Comctl32.dll 4.00, Shell32.dll 4.00)
- # if (_WIN32_IE> = 0 × 0300) / / Internet Explorer 3.0, 3.01, 3.02
- # if (_WIN32_IE> = 0 × 0400) / / Internet Explorer 4.0
- # if (_WIN32_IE> = 0 × 0401) / / Internet Explorer 4.01
- # if (_WIN32_IE> = 0 × 0500) / / Internet Explorer 5.0, 5.0a, 5.0b
- # if (_WIN32_IE> = 0 × 0501) / / Internet Explorer 5.01
- # if (_WIN32_IE> = 0 × 0550) / / Internet Explorer 5.5
- # if (_WIN32_IE> = 0 × 0600) / / Internet Explorer 6.0
- # if (_WIN32_IE> = 0 × 0601) / / Internet Explorer 6.0 SP1
- # if (_WIN32_IE> = 0 × 0603) / / Internet Explorer 6.0 SP2
- # if (_WIN32_IE> = 0 × 0700) / / Internet Explorer 7.0
- # if (_WIN32_IE> = 0 × 0800) / / Internet Explorer 8.0
- # ifdef _WIN32_IE
- CUI
주의 <br /> 전처 리기 정의되지 않은 식별자를 0으로 처리하므로, # if __ GNUC__> = 3 GCC3 이상으로 사용할 수 있지만,
GCC2 계 여부를 # if __ GNUC__ <3 판정 하자고하면 GCC 않은 것도 포함된다.
추천
Windows 버전 검색
- 2010 년 7 월 29 일 12:00 AM
- 자료
사용 일은 없다고 생각하지만, 일단 메모.
Windows 계열 컴파일러는 문제없이 컴파일 있다고 생각한다.
일단 MinGW에서 컴파일하고 동작 확인 갔다.
#include <windows.h> #include <stdio.h> int main(void) { unsigned int GV = GetVersion(); printf("GetVersion API(GV) = %08X\n\n", GV); printf("_winver = %08X\n", _winver); printf("_winmajor = %08X\n", _winmajor); printf("_winminor = %08X\n", _winminor); printf("_osver = %08X\n\n", _osver); printf("(( GV << 8 ) | (( GV >> 8 ) & 0XFF)) & 0XFFFF = %08X (= _winver)\n", (( GV << 8 ) | (( GV >> 8 ) & 0XFF)) & 0XFFFF ); printf("GV & 0XFF = %08X (= _winmajor)\n", GV & 0XFF ); printf("( GV >> 8 ) & 0XFF = %08X (= _winminor)\n", (( GV >> 8 ) & 0XFF)); printf("GV >> 16 = %08X (= _osver)\n\n\n", (GV >> 16) ); // Windows version(_winmajor, _winminor, _osver) printf("This system is ["); if ( _osver < 0X8000 ) { // NT Group (_osver LowWORD MSB = 0) switch (_winmajor) { case 3: case 4: printf ("Windows NT %u.%u Build %u", _winmajor, _winminor, _osver); break; case 5: switch (_winminor) { case 0: printf ("Windows 2000 Build %u", _osver); break; case 1: printf ("Windows XP Build %u", _osver); break; case 2: printf ("Windows Server 2003 family Build %u", _osver); break; default: printf ("NT Group Windows Build %u", _osver); } break; case 6: switch (_winminor) { case 0: printf ("Windows Vista or Windows Server 2008 Build %u", _osver); break; case 1: printf ("Windows 7 Build %u", _osver); break; default: printf ("NT Group Windows Build %u", _osver); } break; default: printf ("NTGroup Windows Build %u", _osver); } } else { switch (_winmajor ) { case 0: //Win32s Group case 1: case 2: case 3: printf ("Win32s Build %u", _osver & 0X7FFF); break; case 4: // 9X Group (_osver is invalid.) switch (_winminor) { case 0: printf ("Windows 95 Build ----"); break; case 10: printf ("Windows 98 Build ----"); break; case 90: printf ("Windows Me Build ----"); break; default: // To make sure printf ("Newer than Windows Me"); } break; default: // To make sure printf ("Newer than Windows Me"); } } printf("]"); return 0; } 홈 > 자료
- 검색
- 피드
- 번역










