とっちゃん's Blog

WindowsInstaller に WiX はいかがですか~

目次

Blog 利用状況

ニュース

とっちゃんって?

コミュニティ

@ITの記事

CodeZineの記事

WiX チュートリアル

Windows ユーザー エクスペリエンス ガイドライン

唯一の日本語書籍

記事カテゴリ

書庫

日記カテゴリ

インストーラ関連

旧館

[msi]Win8だと失敗する。。。だと!?

元ネタはお仕事関係です。Win8もRPになって、あれやこれやといろいろチェック中。。。だったりします。

メトロいいけど、従来アプリのスタートメニューの登録とかこのままなん?と思いつつ。。。

 

基本的な動作は問題ないです。すこぶる快調です。

 

Windows Virtual PC にインストールできない点を除いて。インストールのテストとかマジ面倒。。。<ちが!

 

CPのころは、CDhtmlDialog が壊滅状態だったりといくつかこのまま出たら致命的だねぇ。。。というものがあったんですが、それらも順当に修正されていたので、まぁ特に問題もなく。。。と思っていたところで発覚しました。

 

msi のAPI使ってるソフトなんてほとんどないだろうから、誰も気づかなかったんだろうなぁ。。。

ということで、エラーを見つけました。クラッシュしないけど使ってるソフトは致命傷的なエラー。

なにせ、状態が正しいと仮定すれば、インストールに失敗してる場合以外にありえない状況だから。。。

MsiLocateComponent API と、MsiGetComponentPath API が失敗します。

 

これ、失敗するとどこにファイル入れてあるかわからんのですよ。。。というか、失敗するってことは、インストールしていないという想定で動作になるのですよ。。

コンポーネントのパスが取れない=コンポーネントはインストールされていないですからね。。。

 

とりあえず、簡単なMsiLocateComponentのテストコードとして、msvcr100.dll のインストール先パスが取得するものを載せておきます。

VCとかでコンソールアプリを作成して、中身を適当に入れ替えてください。

stdafx.h

#pragma once
#include <Windows.h>

#include <stdio.h>
#include <tchar.h>

#include <msi.h>
#pragma comment(lib,"msi.lib")

 

本体。

 

#include "stdafx.h"

LPCTSTR componentId = _T("{9983C931-37BE-3C6E-AD32-8B6E789B6881}");
int _tmain(int argc, _TCHAR* argv[])
{
  DWORD cbLength = 0;
  INSTALLSTATE instState = MsiLocateComponent( componentId, NULL, &cbLength );
  _tprintf( _T("MsiLocateComponent( %s, NULL, %u ):%d\n"), componentId, cbLength, instState );
  if( cbLength != 0 ){
    cbLength++;
    TCHAR* componentPath = new TCHAR[cbLength];
    instState = MsiLocateComponent( componentId, componentPath, &cbLength );
    _tprintf( _T("MsiLocateComponent( %s, %s, %u ):%d\n"), componentId, componentPath, cbLength, instState );
    delete []componentPath;
  }
  return 0;
}

Visual C++ 7.0 以上対応です。6.0も動くと思うけど、古すぎてわかりません。

さて。。。問題は、APIの不具合を報告するパブリックな経路がない。。。というところだよなー。Win8 には報告ツールも入ってないみたいだし。。。

投稿日時 : 2012年6月8日 21:01