Visual Studio 2017 で 'RC2135 file not found: STRINGTABLE' が発生
まだどとねとが出る前。
プログラマは何を使って Windows 用の GUI アプリを書いていたかと言うと
一部の変態を除き Microsoft Foundation Class (MFC) を使って書くのが一般的でした。
# ひでのふは VB6 しか使えない連中をプログラマとは認めていません。

いつからだったかは忘れてしまいましたが、
それまでの超絶難解な CView / CDocument のモデルに加え
CDialog クラスを基底クラスとする、割と理解が簡単なモデルが出てきたので
ちょっとした GUI アプリは、よくこの CDialog クラスを使って書いていました。

そしてこの 2017年末。どーしても主に速度的な要因
さまざまな環境と歴史的経緯から、また新規に MFC でアプリを書くことになりましたw

一時期 MFC は無料版の Visual Studio には同梱されていなかったのですが
最新の Visual Studio にはちゃんと同梱されています。
で、早速ゴリゴリとソースを書いて行くわけですが
途中からこんなエラーメッセージが出てコンパイルできなくなってしまいます。

エラー RC2135 file not found: STRINGTABLE afxres.rc 35行目
エラー RC2135 file not found: 0xF000 afxres.rc 38行目
エラー RC2135 file not found: 0xF001 afxres.rc 39行目


たりめーですがこんなファイルをいじった覚えはありませんし
エラーが出ている該当行を表示しても、エラーになるような要因は見当たりません。

このエントリは、この窮地をどーやって解決したかとゆー
大変ストライクゾーンの狭いお話になりますw

ちなみにこの現象、割と最新版の Ver 17.5.1 でも確認できています。

【再現パターンを突き止める】

色々やって試してみて、最短での再現パターンを突き止めました。

1.メニューから「ファイル」→「新規作成」→「プロジェクト」を選ぶ。
2.左側のペインから「Visual C++」→「MFC」とたどり「MFCアプリケーション」を
選択して「OK」
3.下記の画像のように「アプリケーションの種類」を「ダイアログベース」に変更し
「MFCの使用」を「スタティックライブラリでMFCを使用する」に変更して「完了」
#おそらく「スタティックライブラリ~」の変更は関係ないと思う。
4.リソースビューのペインからダイアログのリソースを選択する。
5.ダイアログをびろーんと引っ張ってサイズを変更。
6.コンパイルする。

です。
たりめーですが、ダイアログの表示サイズ変えただけ
コンパイルエラーが出ることなんか絶対にありませんw

ちなみに、4.の段階でコンパイルする分にはきちんとコンパイルできます。

【原因は何なのか】

再現パターンが判れば、問題とゆーのは解決できたも同然ですw

4.の段階のリソースファイルと、6.の段階のリソースファイルの差分を取ると
意外と多くの差分が検出されて驚きます。

で、発見したのが明らかにおかしな 208行目付近

#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
言語 17、1
#include "res\MFCApplication2.rc2" // Microsoft Visual C++ 以外で編集されたリソース
#include "afxres.rc" // 標準コンポーネント


なんだこの言語 17、1ってw
お誂え向きにカンマまで半角ではなく全角ですw

試しに下記のように修正してみると、ちゃんとコンパイルが通るではないですかw
もちろん実行してもちゃんと動作しました。

#define _AFX_NO_TRACKER_RESOURCES
#define _AFX_NO_PROPERTY_RESOURCES

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_JPN)
LANGUAGE 17, 1
#include "res\MFCApplication2.rc2" // Microsoft Visual C++ 以外で編集されたリソース
#include "afxres.rc" // 標準コンポーネント


しかし、ダイアログを変更するたんびにこの問題が顕在化してくるので
正直やってらんないですw

【恒久的仮対処】

とりあえず、こんなスクリプトを考えてみました。
※ 実際は1行です。

(Get-Content .\{リソースファイル名}.rc) | 
ForEach-Object{ $_ -replace "言語 17、1", "LANGUAGE 17, 1" } |
Set-Content .\{リソースファイル名}.rc_temp ; del .\{リソースファイル名}.rc ;
ren .\{リソースファイル名}.rc_temp .\{リソースファイル名}.rc


見ての通り、問題の部分を強制的に置換するスクリプトです。
ファイルとして保存するなら、ソースコードと同じフォルダが良いと思います。

実際に Visual Studio に適用する時は、プロジェクトのプロパティの
「ビルドイベント」→「ビルド前のイベント」→「コマンドライン」に
下記のような設定をしました。
※ 実際は1行です。

powershell -Command "(Get-Content .\MFCApplication2.rc) | 
ForEach-Object{ $_ -replace \"言語 17、1\", \"LANGUAGE 17, 1\" } |
Set-Content .\MFCApplication2.rc_temp" ; del .\MFCApplication2.rc ;
ren .\MFCApplication2.rc_temp .\MFCApplication2.rc


ポイントは、powershell 部分の " を \" にしてエスケープしているところです。

【2017/12/16】 技術 | トラックバック(0) | コメント(0) | page top↑
<<今月の密林 2017/12 | ホーム | 今月の密林 2017/11>>
コメント
コメントの投稿











管理者にだけ表示を許可する

トラックバック
トラックバックURL
http://hidenov.blog4.fc2.com/tb.php/1399-4eca1550
| ホーム |