텀블러 RSS를 이웃커넥트에 집어넣었습니다.(사후보고)
요즘 별로 포스팅을 하지 않아서 볼 것도 없으실텐데 감사합니다...
Cosmic Funnies

titsay
i don't do bad sauce passes
Misplaced Lens Cap
Not today Justin
Sade Olutola

shark vs the universe
No title available
DEAR READER
Keni
AnasAbdin
No title available
$LAYYYTER

Janaina Medeiros

roma★

#extradirty
Xuebing Du
Peter Solarz
Jules of Nature
Aqua Utopia|海の底で記憶を紡ぐ

seen from United States

seen from Peru
seen from Canada
seen from United States
seen from United States

seen from United States

seen from United States
seen from Morocco

seen from India

seen from United States
seen from Brazil

seen from United States

seen from Germany

seen from Singapore

seen from United States
seen from Germany
seen from Malaysia
seen from United States

seen from United States
seen from United States
@snakebones
텀블러 RSS를 이웃커넥트에 집어넣었습니다.(사후보고)
요즘 별로 포스팅을 하지 않아서 볼 것도 없으실텐데 감사합니다...
디버깅작업 후 카카오톡이 안켜지는 현상 해결
윈도우 10에 대한 App을 만들어 볼 계획이라 기존의 HyperV에서 만들어둔 개발용 가상머신을 사용하지 않고 베이스에 윈도우 10과 vs2015등을 다 깔아버렸습니다. 이 작업을 위해서는 에뮬레이터가 필요해 가상머신에서는 무리.. HyperV도 꺼버렸습니다 ㅠㅡ
어찌됐건 베이스에 이것 저것 쓰게되니 카카오톡을 킬때 위와 같은 에러메세지가 뜨게 됐습니다..
이게 대체 뭔일인가 하고 이것 저것 검색해보니
http://www.sysnet.pe.kr/2/0/1561
정성태님의 말로는 Process Monitor(Procmon.exe)이 문제라고 하는군요.
procmon.exe가 실행 된 후 procmon23.sys라는 드라이버를 로드되고 procmon.exe가 종료되도 해당 드라이버는 언로드 되지 않는 문제입니다.
정성태님은 리붓을 하면 된다고 하셨으나 실제론 해결이 안되고 현상이 지속 되길레 그 후 이것저것 알아보니 저 글을 작성 후 정책이 변한건지 잘못 알고 계셨던 것인지 모르겠으나
process Monitor는 다중 클라이언트를 지원하는데 이 상황에서 안전하게 드라이버를 언로드할 타이밍을 찾지 못한다는 것이 드라이버 언로드 불가의 이유이다.
그래서 수동으로 제거를 해줘야합니다...
https://technet.microsoft.com/en-us/sysinternals/bb963902
위의 Autoruns를 이용하여 드라이버탭에서 제거 후 리붓을 해주셔도 되고
레지스트리를 직접 수정해주셔도 됩니다.
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\PROCMON23
를 전체 다 삭제해주시고 리붓을 해주시면 됩니다.
이 양반은 뭐하고 삽니까
그냥 백수입니다.
Raspberry pi 2의 Rasbian에 ASP.NET vNext 설치
일단 ASP.NET vNext가 지금 베타3 버전상태라는 것을 알고 계셔야합니다...
이 포스팅은 아래 두 포스팅을 참조해서 만들어졌습니다.
http://weblogs.thinktecture.com/cweyer/2014/10/installing-running-aspnet-vnext-alpha-3-on-ubuntu-linux-with-mono-38for-real.html
http://www.talksharp.com/running-aspnet-vnext-on-the-raspberry-pi
ASP.NET vNext는 웹과 응용 프로그램을 만들기 위한 OpenSource Framework로 가장 큰 특징은 ASP.NET으로 Web을 만들어도 IIS에 종속이 안되어 있기때문에 꼭 Windows를 필요로 하지 않는 다는 장점이 있습니다.
좀 더 자세한 내용은 저보다는 아무래도 ASP.NET 공홈이나 여타 다른 블로그에서 확인해보시는게 좋습니다. (뭘해도 저는 대충이라...)
일단 vNext를 쓰기위해서는 https://github.com/aspnet/home 에 기재되어있는 대로 Mono 3.4.1 혹은 그 이후 버전이 필요로 합니다.
그러나 Rasbian은 Debian wheezy 를 쓰고있는데 여기에 들어있는 mono-complete 버전은 2.10.8을 쓰고 있습니다. (https://packages.debian.org/search?keywords=mono-complete)
그래서 일단 소스를 받아서 빌드부터 해야합니다...
그러기 위해서 빌드를 하기위한 준비를 하기 위해 gettext를 설치합니다.
sudo apt-get install gettext
그 후 이곳에서 적절한 버전의 Mono Source를 받아 빌드합니다.
http://download.mono-project.com/sources/mono/
저 같은 경우는 3.12.0을 사용했습니다.
wget http://download.mono-project.com/sources/mono/mono-3.12.0.tar.bz2tar -xvf mono-3.12.0.tar.bz2 cd mono-3.12.0 ./configure --prefix=/usr/local make sudo make install
참고로 라즈베리파이 2에서의 빌드과정은 몇 시간 걸립니다...
빌드가 정상적으로 이루어 졌다면 다음과 같이 버전을 확인할 수 있습니다.
mono --version
빌드에 완료됐으면 KVM을 설치해야합니다.
curl -sSL https://raw.githubusercontent.com/aspnet/Home/master/kvminstall.sh | sh && source ~/.k/kvm/kvm.sh
해당 코드는 변경될 수도 있으니 https://github.com/aspnet/home 에 있는 것을 가져다 쓰는게 더 좋습니다.
위의 sh 스크립트가 정상적으로 작동이 됐다면 다음의 코드가 작동하는지 확인합니다.
kvm
이런식으로 kvm이 실행이되면 upgrade 명령으로 kre를 설치합니다.
kvm upgrade
현재(15-03-05)기준으로는 kre-mono.1.0.0-beta3가 설치됩니다.
이제 샘플 프로젝트를 실행시켜봐서 설치한 kre가 잘 작동하는지 확인해봅니다.
일단 시작에 앞서 일단 libuv를 설치해야합니다. libuv도 apt-get으로 받을 수 없기 때문에 이 역시 빌드해줘야 합니다. 빌드 준비를 위해서 gyp를 설치합니다.
sudo apt-get install gyp
그리고 libuv의 소스를 받아야하는데 http://www.libuv.org/에서 받을 수 있습니다. 저 같은 경우는 1.4.2 버전을 사용했습니다.
wget http://www.libuv.org/dist/v1.4.2/libuv-v1.4.2.tar.gz tar -xvf libuv-v1.4.2.tar.gz cd libuv-v1.4.2/ sudo ./gyp_uv.py -f make -Duv_library=shared_library sudo make -C out sudo cp out/Debug/lib.target/libuv.so /usr/lib/libuv.so.1.4.2 sudo ln -s libuv.so.1.4.2 /usr/lib/libuv.so.1
이 작업이 전부 끝났으면 aspnet/home Github의 샘플을 이용하여 kre의 실행 테스트를 진행합니다. 일단 Github의 소스를 Clone하는 것부터 시작합니다.
git clone https://github.com/aspnet/Home.git
aspnet/Home의 샘플은 ConsoleApp, HelloWeb, HelloMVC 3가지가 있습니다. 여기서는 가장 만만한 HelloWeb을 가지고 진행하겠습니다.
cd Home/ cd samples/ cd HelloWeb/ vi project.json
Sample 에 포함되어있는 project.json은 1.0.0-beta1 기준으로 작성이 되어있어서 현재(15-03-05)사용하는 kre 1.0.0-beta3에서는 에러가 발생합니다. 그렇기 때문에 위의 스크린샷처럼 dependencies를 수정해줘야합니다.
이제 kpm을 이용하여 HelloWeb을 빌드해야하는데 그전에 nuget 관련된 인증서를 설치해야 합니다. 아래의 Shell 명령어들을 입력하고 설치 여부에 대해 y 추가 후 enter를 누릅니다.
sudo certmgr -ssl -m https://go.microsoft.com sudo certmgr -ssl -m https://nugetgallery.blob.core.windows.net sudo certmgr -ssl -m https://nuget.org sudo certmgr -ssl -m https://www.myget.org/F/aspnetvnext/ mozroots --import --sync
위의 작업이 안되있으면 nuget에서 아래의 명령어로 데이터를 받아 올 수 없기 때문에 꼭 수행해주셔야 합니다.
kpm restore
이후 아래 명령어로 HelloWeb을 빌드합니다.
kpm build
build 명령에 에러 없이 정상적으로 빌드가 완료됐다면 아래의 명령어로 Sample Project를 실행을 시킵니다.
k kestrel
해 당 명령 후 Started 라는 메세지가 뜨면 일단 정상적으로 기동한 것입니다. 그리고 ifconfig로 라즈베리파이2의 주소를 확인 후 해당 주소와 project.json의 kestrel에 기술되어있는 Port(기본값은 5004)로 접속을 하여 아래와 같은 화면이 뜨면 kre이 제대로 작동한다고 할 수 있겠습니다.
Asus 메인보드에서 CPU 교체후 비프음 4번 발생할 때.
결론부터 말하자면 CPU를 교체하기 전에 소켓만 같다고 뒤도 안돌아보고 갈아끼지말고 꼭 메인보드 CPU 지원 여부를 확인과 최소 지원 바이오스 버전을 확인해야 합니다...
Asus P8H67-M 메인보드를 쓰고 있는 친구가 3세대 I3-2100을 쓰고 있었는데 VGA를 바꾸고 나더니 CPU가 VGA 발목을 잡는 것 같다고 이런 저런 고민을 하다가 3세대 I5-3570으로 갈아타기로 했습니다.
소켓이 둘다 똑같이 1155니까 별 문제가 없을 줄 알았는데 I5-3570을 교체하자 비프음 4번이 발생 (...)
http://support.asus.com/pcassistant/pdf/BeepTable_en-us.pdf
ASUS Beep Table을 확인해보니 4번은 뭔가 하드웨어 이상을 감지했다는 내용인데... 최신 ASUS보드는 각 부위마다 LED가 달려서 그것으로 에러를 감지 할 수 있다고 합니다. 친구가 쓰는 보드인 Asus P8H67-M는 POWER랑 DRAM 딱 두개밖에 없는 상황...
그 중에 DRAM쪽 LED가 점등이 되어있다길레 MEMOK! 라는 ASUS의 메모리에러를 혼자서 잡아주는 하드웨어적 기능을 이용해봤습니다만... (버튼이 하나 있어서 그거 누르면 알아서 바이오스 설정을 바꿔주면서 설정을 잡는 기능인듯...)
그런데 이짓을 RAM 위치나 개수를 바꿔가면서 계속 시도해봐도 해결이 안되는 상황... 혹시나 해서 I3-2100을 다시 껴보라니 멀쩡히 잘돌아감...
혹시나해서 메인보드 CPU 지원 상황을 한번 보니...
http://www.asus.com/kr/Motherboards/P8H67M/HelpDesk_CPU/
이 무슨 ;;; 'BIOS에서' 이부분이 BIOS 버전인데 동일 세대, 동일 소켓 CPU인데도 3천이 넘는 버전 차이가 나는 ;;;
바이오스 업데이트 이후 정상적으로 작동하는 것을 확인했습니다.
이런식으로 CPU만 갈아버리는건 처음해본 것도 있고, 사실상 이번 같은 경우는 시스템이 에러 표기를 잘못하고 있었기 때문에 RAM만 집요하게 보고 있었기에 해결에 더욱 시간이 오래걸린 케이스...
CPU 소켓이 같다고 그냥 꼽아서 되는건 아니라는 걸 알았습니다...
Raspberry Pi2에 Snappy Ubuntu Core 설치 후 Snappy 명령시 server certificate verification failed. 에러가 발생할 때
라즈베리파이2를 2개 구입했습니다. (UPS가 2일만에 보내줌 ;;)
기존에 쓰던 Raspbian을 쓸까 하다가 안써본 Snappy Ubuntu Core를 설치해봤습니다.
이게 어떤 것인지는 아래 링크에서 확인해보세요.
http://developer.ubuntu.com/en/snappy/
저는 이런 Docker 같은 것은 이번에 처음 써보는거라 뭐라 쓰기가 좀 그렇네요...
하여튼 SSH등으로 Raspberry Pi2에 들어가서 Snappy 명령을 수행하려 하면 다음과 같은 에러가 발생합니다.
root@localhost:/# snappy updateTraceback (most recent call last): File "/usr/bin/snappy", line 25, in <module> status = Main().__main__() File "/usr/lib/python3/dist-packages/snappy/main.py", line 195, in __main__ return callback(args) File "/usr/lib/python3/dist-packages/snappy/main.py", line 511, in _do_update for pkg in ClickDataSource().upgradable_apps] File "/usr/lib/python3/dist-packages/snappy/click.py", line 180, in upgradable_apps all_updates_list = repo.get_upgradable() File "/usr/lib/python3/dist-packages/click/repository.py", line 183, in get_upgradable headers={"content-type": "application/json"}) File "/usr/lib/python3/dist-packages/click/network.py", line 70, in http_request curl.perform() pycurl.error: (60, 'server certificate verification failed. CAfile: /etc/ssl/certs/ca-certificates.crt CRLfile: none')
이러한 에러가 발생하는데 왜 그런가 했더니 시스템의 날짜가 1970년으로 지정되어 있던...
root@localhost:/# date -s '2015-02-12 22:55:00'
대략 이런식으로 날짜를 현재 시간으로 맞춰주시고 snappy 명령을 내리면 제대로 작동합니다.
근데 지금 너무 초기라 그런지 app이 별로 없네요... 한동안은 Raspbian으로 써야겠습니다. Snappy App을 만들어도 좋을 것 같고요.
Visual Studio 2013을 이용하여 Remote Debugging시 RPC 서버를 사용할 수 없습니다. 라는 메세지가 나올때.
일단.... 어떤 Server와 통신을 해야하는 Client를 만들어야하는 상황이였습니다.
문제는 Server측에서 보안을 이유로 특정 IP 하나만 접속을 허용하게 해놨는데 그게 제 IP가 아니라는 점이지요...
그래서 어쩌면 당연하게 리모트 디버깅으로 체크하면서 개발하기로 결정했습니다...
(잡설로... 이러한 상황에서는 TDD를 어찌하는지 알아봐야겠네요...)
뭐 어찌됐건... 자잘한 구성방법 설명은 생략하고.. Console Application의 설정을 알맞게 넣어주고 실행을 하니...
RPC 서버를 사용할 수 없습니다.
라는 처음보는 에러가 발생...
근데 원격지의 원격 디버깅 모니터를 보면 연결은 정말 잘되고 있네요.
그래서 구글링을 해보니 적혀있더라고요.
http://cerkit.com/2014/08/12/remote-debugging-issue-with-asp-net-unable-to-attach-to-the-process/
그러니까 로컬의 방화벽 때문에 생기는 현상으로 Visual Studio 2013를 예외 걸어주면 된다고한다..
제어판의 방화벽에서 프로그램 또는 기능 허용 클릭
설정 변경을 부르고 다른 프로그램 허용을 눌러 visual Studio 2013을 추가하고 확인을 하면 되는데...
이게 가끔 이상하게 작동하더라고요... 원격 디버깅 잘하다가 어느순간부터 갑자기 막히기도 합니다.
이유는 잘 모르겠습니다. 나중에 방화벽에 막힌것이 뭔지 확인을 해봐야겠는데 지금 당장은 너무 바쁨...
C# Async Await작업시 Context들도 같이 가져가는 법
http://msdn.microsoft.com/en-us/magazine/gg598924.aspx // 참고 MSDN 페이지 링크
어쩌다보니 비동기 메소드를 만드는 도중에 다음과 같은 코드를 만들게 됐습니다..
object someObject = await Task.Factory.StartNew<object>( () => { string name = HttpContext.Current.User.Identity.Name; // Exception // 무언가 로직.. });
대충 위의 MSDN을 보니까 전부다 Exception이 나는 것은 아닌 듯한데 일단 ASP.NET WebAPI쪽에선 나더라고요...
만들기는 해야겠으니 대충 궁여지책으로 이렇게 수정을 해봤습니다.
HttpContext ctx = HttpContext.Current; object someObject = await Task.Factory.StartNew<object>( () => { HttpContext.Current = ctx; string name = HttpContext.Current.User.Identity.Name; // 무언가 로직.. });
일단 여기선 잘 작동을 했는데 뭔가 깨림직....
싱글턴 패턴이 적용됐다 같은 이유로 Set이 안될 가능성이 일단 있고, 무언가 다른것을 만들었는데 Context를 보는 것 같긴하지만 그 Context가 무엇인지 알 수 없는 상황이 있을 수 있잖아요???
그리고 안다고 해도 그것을 비동기 메소드 만들때마다 하나씩 Set해줄수도 없는 노릇이고요...
그래서 찾은게 위의 MSDN입니다..
TaskScheduler taskScheduler = TaskScheduler.FromCurrentSynchronizationContext(); object someObject = await Task.Factory.StartNew<object>( () => { string name = HttpContext.Current.User.Identity.Name; // 무언가 로직.. }, CancellationToken.None, TaskCreationOptions.None, taskScheduler);
이 방식대로 하니 Context부분도 동기되서 작동되더라고요...
아직 비동기 관련해서는 아직까진 자유자재로 다루진 못하는구나... 싶었습니다..
Windows Store Application은 무조건 NTFS 볼륨 위에서만 작동합니다.
1>------ 배포 시작: 프로젝트: Test_Window_App, 구성: Debug Any CPU ------ 1>새로운 정리 레이아웃을 만드는 중... 1>레이아웃에 총 1mb보다 작은 파일 복사 중... 1>레이아웃에서 실행할 응용 프로그램을 등록하는 중... 1>오류: DEP0700: 앱을 등록하지 못했습니다. Windows에서 파일 시스템 유형 exFAT의 D:\Test_Window_App\bin\Debug 경로에 배포할 수 없습니다. 경로는 NTFS 볼륨에 있어야 합니다.(0x80073cfd) ========== 배포: 성공 0, 실패 1, 생략 0 ==========
Asus 트랜스포머북 하드 용량이 64기가밖에 안되서 왠만한건 64기가 SD카드에 다 저장을 하고있습니다.
근데 다른건 다 잘작동하는데 Windows Store Application만 NTFS를 원하네요...
거기에 빌드를 할때는 에러메세지가 나오지가 않는데 덕분에 테스트 작동이 안되는 이유를 알 수 가 없습니다.
이런식으로 그냥 작동을 안하는지라 뭐가 문제인지 모르고 ??? 만 하고 있었네요...
Nexus 5가 Windows 8.1에서 미디어기기(MTP)로 잡히지 않을때 (2)
Nexus 5가 Windows 8.1에서 미디어기기(MTP)로 잡히지 않을때
근데 Windows의 설치 버전에 따라 MTP가 안보일때가 있습니다.. N 혹은 KN 버전일때 MTP가 안보이는데 이때는 아래의 링크에서 미디어 팩을 설치하고 껏다 키면 보이더라고요..
http://www.microsoft.com/ko-kr/download/details.aspx?id=42503
원문 : http://forum.xda-developers.com/showthread.php?t=1833659 espionage724의 글
Nexus 5가 Windows 8.1에서 미디어기기(MTP)로 잡히지 않을때
Windows의 설치 버전에 따라 MTP가 안보일때가 있습니다..
그럴땐 이 포스팅을 참조하세요..
Nexus 5가 Windows 8.1에서 미디어기기(MTP)로 잡히지 않을때 (2)
----------------------------------------------------------------------------
루미아 710 사서 영원히 고통받던 도중 친구가 넥서스 4를 미국에서 출시되자마자 해외구매로 갈아타길레 피자 하나 조공 바친 후 얻은 내다버려질 뻔한 넥서스 S를 마르고 닳도록 사용했는데...... 그렇게 한 1년 쓰다보니 모든 앱 다 끄고 심지어 비행기 모드까지 켜놓은 상태에서 음악을 들으면서 3시간을 못가는 베터리 상황에 좌절하고 넥서스 S 베터리를 지금사느니 그냥 넥서스 5로 갈아탔습니다. (조건은 묻지 않기....)
근데.... 넥서스 S랑 비스킷탭과는 다른 방식으로 Windows와 USB 통신을 하는지 화면이 약간 다른데 MTP라는 방식으로 연결을 합니다.
뭔지모르겠지만 대다나다....... 했는데...
드라이브가 안뜸 (......)
심지어 Devices And Printers 에선 Unknown으로 빠져있는 상태...
근데 ADB 는 잘 연결되어있는 아리송한 상황 (.....)
http://forum.xda-developers.com/showthread.php?t=1934306
그리고 구글링을 해보니 답이 있더라..... Thanks TheBeano
Nexus 5로 인식되어있는 ADB를 오른클릭해서 Update Driver Software...
Browse my computer for driver software 선택
Let me pick from a list of device drivers on my computer 선택
MTP USB Device를 선택
내컴퓨터로 가보면 Nexus 5가 등록되어있는 것을 확인 할 수 있습니다.
Daemon 자동 실행시키기
라즈베리 파이용으로 스위치를 쓰기위한 Daemon을 하나 만들었는데 이게 부팅을 하고 자동으로 실행이 되지 않으면 의미가 없습니다.
부팅할때 SSH 접속해서 Daemon을 올려놓고 끌때 스위치 누르는 짓이나 아예 끌때 SSH 접속해서 shutdown -h now 하는거랑 차이가 없잖아요? (......)
그래서 Daemon을 자동으로 올리는 방법과 데비안 계열에 있는 Daemon 관리 명령어인 service 명령어에서도 관리가 가능하도록 하는 방법에 대해 알아봤습니다.
일단 /etc/init.d/ 라는 디렉토리 안에 쉘 스크립트를 만드는 작업이 가장 처음해야하는 일이더군요.
근데 쉘 스크립트라는건 막만들면 안되고 일정한 틀이 있어야합니다.
보통 비슷하게 작동을 하겠지만 라즈비안 기준으로 보자면 /etc/init.d/skeleton 이라는 틀을 사용합니다.
#! /bin/sh### BEGIN INIT INFO # Provides: skeleton # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Example initscript # Description: This file should be used to construct scripts to be # placed in /etc/init.d. ### END INIT INFO # Author: Foo Bar <[email protected]> # # Please remove the "Author" lines above and replace them # with your own name if you copy and modify this script. # Do NOT "set -e" # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="Description of the service" NAME=daemonexecutablename DAEMON=/usr/sbin/$NAME DAEMON_ARGS="--options args" PIDFILE=/var/run/$NAME.pid SCRIPTNAME=/etc/init.d/$NAME # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON -- \ $DAEMON_ARGS \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 # Many daemons don't delete their pidfiles when they exit. rm -f $PIDFILE return "$RETVAL" } # # Function that sends a SIGHUP to the daemon/service # do_reload() { # # If the daemon can reload its configuration without # restarting (for example, when it is sent a SIGHUP), # then implement that here. # start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME return 0 } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; #reload|force-reload) # # If do_reload() is not implemented then leave this commented out # and leave 'force-reload' as an alias for 'restart'. # #log_daemon_msg "Reloading $DESC" "$NAME" #do_reload #log_end_msg $? #;; restart|force-reload) # # If the "reload" option is implemented then remove the # 'force-reload' alias # log_daemon_msg "Restarting $DESC" "$NAME" do_stop case "$?" in 0|1) do_start case "$?" in 0) log_end_msg 0 ;; 1) log_end_msg 1 ;; # Old process is still running *) log_end_msg 1 ;; # Failed to start esac ;; *) # Failed to stop log_end_msg 1 ;; esac ;; *) #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2 exit 3 ;; esac :
위와 같은 내용이 들어가 있는데 여기서 자신에 Daemon에 맞게 수정해주면 됩니다.
일단 skeleton 원본 파일을 수정해버리면 나중에 또 다른 Daemon을 올릴때 불편해지기때문에 복사부터합니다.
cat /etc/init.d/skeleton >> /etc/init.d/ShutDownDaemon
해당 명령으로 ShutDownDaemon이라는 파일을 만들고 내용을 수정하면 되는데 저같은 경우는 아래처럼 수정했습니다.
#! /bin/sh ### BEGIN INIT INFO # Provides: ShutDownDaemon # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: ShutDownDaemon # Description: Snakebones's ShutDownDaemon ### END INIT INFO # Author: Foo Bar <[email protected]> # # Please remove the "Author" lines above and replace them # with your own name if you copy and modify this script. # Do NOT "set -e" # PATH should only include /usr/* if it runs after the mountnfs.sh script PATH=/sbin:/usr/sbin:/bin:/usr/bin DESC="Snakebones's ShutDownDaemon" NAME=ShutDownDaemon DAEMON=/usr/sbin/$NAME SCRIPTNAME=/etc/init.d/$NAME # Exit if the package is not installed [ -x "$DAEMON" ] || exit 0 # Read configuration variable file if it is present [ -r /etc/default/$NAME ] && . /etc/default/$NAME # Load the VERBOSE setting and other rcS variables . /lib/init/vars.sh # Define LSB log_* functions. # Depend on lsb-base (>= 3.2-14) to ensure that this file is present # and status_of_proc is working. . /lib/lsb/init-functions # # Function that starts the daemon/service # do_start() { # Return # 0 if daemon has been started # 1 if daemon was already running # 2 if daemon could not be started start-stop-daemon --start --quiet --exec $DAEMON --test > /dev/null \ || return 1 start-stop-daemon --start --quiet --exec $DAEMON \ || return 2 # Add code here, if necessary, that waits for the process to be ready # to handle requests from services started subsequently which depend # on this one. As a last resort, sleep for some time. } # # Function that stops the daemon/service # do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 --name $NAME RETVAL="$?" [ "$RETVAL" = 2 ] && return 2 # Wait for children to finish too if this is a daemon that forks # and if the daemon is only ever run from this initscript. # If the above conditions are not satisfied then add some other code # that waits for the process to drop all resources that could be # needed by services started subsequently. A last resort is to # sleep for some time. start-stop-daemon --stop --quiet --oknodo --retry=0/30/KILL/5 --exec $DAEMON [ "$?" = 2 ] && return 2 return "$RETVAL" } case "$1" in start) [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME" do_start case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; stop) [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME" do_stop case "$?" in 0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;; 2) [ "$VERBOSE" != no ] && log_end_msg 1 ;; esac ;; status) status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $? ;; *) #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2 echo "Usage: $SCRIPTNAME {start|stop|status}" >&2 exit 3 ;; esac :
저 같은경우는 ShutDownDaemon 자체가 애시당초 켜져있는 동안은 영구히 상주하면 되는 것이기 때문에 restart나 force-reload 같은건 별로 필요가 없기때문에 그와 관련된 do_reload() 메소드와 switch ~ case의 restart|force-reload를 지우고,
Daemon자체에서 pid 파일도 만들지 않고 Daemon에 따로 Argument를 넣지 않기때문에 PIDFILE와 DAEMON_ARGS를 모두 지워버렸습니다.
그리고 DAEMON=/usr/sbin/$NAME 데몬 경로가 /usr/sbin/ShutDownDaemon 으로 작동하도록 되어있기 때문에 데몬 파일의 위치를 해당 위치로 옮겨줘야합니다.
mv /root/ShutDownDaemon /usr/sbin/
그리고 /etc/init.d/ShutDownDaemon에 권한을 줍니다.
chmod 755 /etc/init.d/ShutDownDaemon
이제 라즈비안이 부팅될때 자동으로 켜지도록 설정을 해줍니다.
update-rc.d ShutDownDaemon defaults
만약 해제하고 싶으면 아래 명령을 입력합니다.
update-rc.d ShutDownDaemon remove
제대로 등록이 됐는지 service로 확인을 해봅니다.
service --status-all
service를 통해 키고 끄고가 잘되는지 확인해봅니다.
스위치를 누르면 라즈베리파이를 꺼주는 Daemon
라즈베리파이를 꺼야할때 왠지 그냥 전원 뽑아버리면 망가질 것 같은 느낌이 들고.... 접속해서 꺼주자니 귀찮지요. SSH로 들어가던 직접 들어가던....
그래서 간단하게 LED를 GPIO 23번에 스위치를 GPIO 25번에 놓고 스위치 눌러지면 LED를 켜주고 라즈베리파이를 종료시켜주는 데몬입니다.
소스를 보시면 아시겠지만.... /root/ShutDown.sh에 뭘집어넣어두냐에 따라 결과값이 달라지겠죠?
저 같은경우는 꺼야하니까 shutdown -h now로 넣어놨습니다.
#include <sys/types.h>#include <sys/stat.h> #include <stdlib.h> #include <fcntl.h> #include <errno.h> #include <unistd.h> #include <syslog.h> #include <string.h> #include <stdio.h> #include <wiringPi.h> #define LED1 23 #define SW 25 int main (void) { if(wiringPiSetupGpio() == -1) { return -1; } pid_t pid; pid_t sid; pid = fork(); if (pid < 0) { exit(EXIT_FAILURE); } if (pid > 0) { exit(EXIT_SUCCESS); } sid = setsid(); if (sid < 0) { exit(EXIT_FAILURE); } if((chdir("/")) < 0) { exit(EXIT_FAILURE); } close(STDIN_FILENO); close(STDOUT_FILENO); close(STDERR_FILENO); pinMode(LED1, OUTPUT); pinMode(SW, INPUT); int isRunning = 0; openlog("Shutdown_Daemon", LOG_PID|LOG_CONS, LOG_USER); syslog(LOG_INFO, "Daemon Run\n"); closelog(); while(1) { if(digitalRead(SW) == 1 && isRunning == 0) { isRunning = 1; digitalWrite(LED1, 1); int returnValue = system("/root/ShutDown.sh"); openlog("Shutdown_Daemon", LOG_PID|LOG_CONS, LOG_USER); syslog(LOG_INFO, "SW On\n"); closelog(); } sleep(3); } }
라즈베리파이 HDMI 강제 연결
꼴랑 3일째 쓰고있다보니 자세하겐 모르겠지만, 처음엔 작동 잘하던 HDMI포트가 갑자기 작동을 안하는겁니다.
처음엔 부팅이 안됐나 싶었는데 SSH로 접속하니 잘되는 것 보니 라즈베리파이와 제가쓰는 LCD 모니터 둘중 하나가 하드웨어적으로 문제가 있나봅니다.....
어찌됐건 찾아보니 이럴때 쓰라고 강제로 연결해주는 옵션이 있더군요.
http://raspberrypi.stackexchange.com/questions/2169/how-do-i-force-the-raspberry-pi-to-turn-on-hdmi
SSH로 접속하거나 리더기를 이용하여 SD카드안에 /boot/config.txt을 열고 (윈도우에서 리더기로 보면 /config.txt입니다.)
hdmi_force_hotplug=1hdmi_drive=2
이렇게 두줄을 추가해주고 리붓해주면 됩니다.
여기서 hdmi_drive=2 옵션은 DVI만 출력하는 옵션으로 사운드가 안들린다고 합니다.
해당 파일이 없을수도 있는 것 같은데 그럴때는 직접 생성해주셔도 되는 것 같습니다.
c++/cli 문서 주석 처리 방법
개인적으로 무언가를 만들고 있는데, 화면에 보이는 윈도우는 C#으로 만들고 안보이는 부분은 C++/CLI로 작업중에 있습니다. 근데 C#에서 C++/CLI 주석이 안보이더군요... 그래서 확인해보니...
http://msdn.microsoft.com/ko-kr/library/ms173501%28v=vs.110%29.aspx
이런식으로 설정하고
http://msdn.microsoft.com/ko-kr/library/ms177227.aspx
C#과 동일하게 입력하면됩니다.
대충 이런식으로 c#과 동일하게 주석을 달아놓으면
이런식으로 metadata에 기록이 되고 C#에서도 해당 주석이 보이게 됩니다.
[C#] Microsoft.Web.Administration를 이용해서 IIS 설정 변경하기
지금 만드는게 서버 어플리케이션인데 인스톨을 하면 자동으로 내부 설정을 바꿔줘야합니다. 이런 저런 문제에 봉착하여 해당 환경에서 유일하게 설정을 바꿀 수 있는 방법이 Microsoft.Web.Administration를 사용하는 수 밖에 없었는데... 써봤어야지 (.......) 혼자서 삽 좀 푸고 작업한 것을 약간 적어놓습니다. 1. Microsoft.Web.Administration Reference 추가 일단 IIS 7.0 이상을 설치하면 같이 깔리는 것인지라 .NET 페이지에 존재 안합니다. Brower 기능을 이용해서 추가해줘야하는데 해당 dll이 있는 경로는 %windir%System32\inetsrv\Microsoft.Web.Administration.dll 입니다. 2. .NET 4.0 Application Pool 생성
ServerManager serverManager = null; try { serverManager = new ServerManager(); string applicationPoolName = "NPD3_4.0"; // 일단 중복되는 .NET 4.0 Application Pool이 있는지 확인합니다. ApplicationPool nocson40ApplicationPool = serverManager.ApplicationPools.FirstOrDefault(x => x.Name.Equals(applicationPoolName)); if (nocson40ApplicationPool == null) // 없으면 { nocson40ApplicationPool = serverManager.ApplicationPools.Add(applicationPoolName); // 만들어줍니다. nocson40ApplicationPool.ManagedRuntimeVersion = "v4.0"; // 4.0으로 serverManager.CommitChanges(); // 저장 } } finally { if (serverManager != null) { serverManager.Dispose(); serverManager = null; } }
3. Site 만들어주기
ServerManager serverManager = null; try { serverManager = new ServerManager(); string siteName = "NPD3Site"; string applicationPoolName = "NPD3_4.0"; Site site = serverManager.Sites.FirstOrDefault(x => x.Name.Equals(siteName)); // 일단 중복되는 Site가 있는지 확인합니다. if (site == null) // 없으면 { string npd3SiteFolderPath = String.Format(@"C:\inetpub\wwwroot\{0}", siteName); site = serverManager.Sites.Add(siteName, "http", "*:54321:", npd3SiteFolderPath); // 생성해줍니다. ApplicationPool nocson40ApplicationPool = serverManager.ApplicationPools.First(x => x.Name.Equals(applicationPoolName)); // 사용할 Application Pool을 찾습니다. site.ApplicationDefaults.ApplicationPoolName = nocson40ApplicationPool.Name; // Application Pool 같은경우는 명칭만 넣어주면 됩니다. serverManager.CommitChanges(); // 저장 } } finally { if (serverManager != null) { serverManager.Dispose(); serverManager = null; } }
4. Site아래에 Application으로 추가하기
ServerManager serverManager = null; try { serverManager = new ServerManager(); string siteName = "NPD3Site"; string applicationPoolName = "NPD3_4.0"; string defaultSiteName = "Default Web Site"; Site site = serverManager.Sites.FirstOrDefault(x => x.Name.Equals(defaultSiteName)); // Dafult Web Site를 찾아서 if (site != null) // 있으면 { string npd3SiteFolderPath = String.Format(@"C:\inetpub\wwwroot\{0}", siteName); Microsoft.Web.Administration.Application npd3Application = site.Applications.Add("/npd3Site", npd3SiteFolderPath); // 해당 사이트 하위에 어플리케이션으로 만들어줍니다. ApplicationPool nocson40ApplicationPool = serverManager.ApplicationPools.First(x => x.Name.Equals(applicationPoolName)); // 사용할 Application Pool을 찾습니다. npd3Application.ApplicationPoolName = nocson40ApplicationPool.Name; // Application Pool 같은경우는 명칭만 넣어주면 됩니다. serverManager.CommitChanges(); // 저장 } } finally { if (serverManager != null) { serverManager.Dispose(); serverManager = null; } }
5. 특정 페이지만 익명 접속을 허용하기
ServerManager serverManager = null; try { serverManager = new ServerManager(); string siteName = "NPD3Site"; Configuration configuration = serverManager.GetApplicationHostConfiguration(); // ApplicationHost.config를 가져옵니다. string npd3DownloadPath = String.Format("{0}/{1}", siteName, "npd3Download.aspx"); ConfigurationSection configurationSection = configuration.GetSection("system.webServer/security/authentication/anonymousAuthentication", npd3DownloadPath); // 해당 파일 경로로 익명 접속 Section을 가져옵니다. configurationSection["enabled"] = true; // 익명 접속을 허용 serverManager.CommitChanges(); // 저장 } finally { if (serverManager != null) { serverManager.Dispose(); serverManager = null; } }