- PR -

[VB6] 自分自身のコピー

1
投稿者投稿内容
おいちゃん
会議室デビュー日: 2006/01/05
投稿数: 5
投稿日時: 2006-01-06 09:05
VB6を利用してちょっとしたインストーラのようなものを作成しています。

その為に、実行している自分自身(作成したexe)が他のディレクトリにコピーされるという処理を行いたいと思い、バッチを作成してみたり、CopyFileAPIを使ってみたりしたのですが、どうしてもできません。

何か他に方法があるのでしょうか?
それともこのようなことはできないものなのでしょうか??
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-01-06 09:15
引用:

おいちゃんさんの書き込み (2006-01-06 09:05) より:

その為に、実行している自分自身(作成したexe)が他のディレクトリにコピーされるという処理を行いたいと思い、バッチを作成してみたり、CopyFileAPIを使ってみたりしたのですが、どうしてもできません。


その exe が起動している限りロックされるでしょう。
テンポラリにシャドウ コピーを作って起動するなりすべきだと思います。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
おいちゃん
会議室デビュー日: 2006/01/05
投稿数: 5
投稿日時: 2006-01-06 10:07
じゃんぬねっとさん、回答ありがとうございます。

引用:
その exe が起動している限りロックされるでしょう。



やはり普通にはできないのですね・・・(TへT)
わかりました。

引用:
テンポラリにシャドウコピーを作って起動するなりすべきだと思います。



すみません、これは具体的にどのようなことでしょうか?
この方法であればできる可能性があるということなのでしょうか??
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-01-06 10:48
引用:

おいちゃんさんの書き込み (2006-01-06 10:07) より:

やはり普通にはできないのですね・・・(TへT)


すいません「置き換える」という意味で捉えていましたが、
「上書きでないコピー」自体なら問題なく行えるハズです。

引用:

すみません、これは具体的にどのようなことでしょうか?


こういう意味だと思ってました。

コード:

    Option Explicit

    Private Const DOUBLE_QUOTE As String = """"

    Public Sub Main()
        Dim stSourcePath As String
        stSourcePath = CombinePath(App.Path, App.EXEName & ".EXE")

        Dim stDestPath As String
        stDestPath = CombinePath(GetTempPath(), App.EXEName & ".EXE")

        '/ 本稼動させる
        If stSourcePath = stDestPath Then
            Dim hForm1 As Form1
            Set hForm1 = New Form1

            Call MsgBox("シャドウからの起動なので本稼動させる")
            Call hForm1.Show(vbModal)

            Exit Sub
        End If

        '/ テンポラリにシャドウ コピー
        Call CopyFile(stSourcePath, stDestPath)
        Call MsgBox("シャドウからの起動ではないのでコピーした")

        '/ シャドウを起動
        Call Shell(stDestPath, vbNormalFocus)
        Call MsgBox("シャドウを起動させたので、このプロセスは終わらせる (ロックは解除される)")
    End Sub

    Public Sub CopyFile(ByVal stSourcePath As String, ByVal stDestPath As String, Optional ByVal bOverwrite As Boolean = True)
        Dim hFso As FileSystemObject
        Set hFso = New FileSystemObject
    
        Call hFso.CopyFile(stSourcePath, stDestPath, bOverwrite)
    End Sub

    Public Function CombinePath(ByVal stPath1 As String, ByVal stPath2 As String)
        If Right$(stPath1, 1) = "\" Then
            CombinePath = stPath1 & stPath2
        Else
            CombinePath = stPath1 & "\" & stPath2
        End If
    End Function

    Public Function GetTempPath() As String
        Dim hFso As FileSystemObject
        Set hFso = New FileSystemObject

        Dim hFolder As Folder
        Set hFolder = hFso.GetSpecialFolder(TemporaryFolder)
        Set hFso = Nothing

        GetTempPath = hFolder.Path
    End Function


こうしておけば、EXE を上書きできます。
で、次回起動時から適用という運用かと思ってました。
どうやら誤爆っぽいですが。

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
おいちゃん
会議室デビュー日: 2006/01/05
投稿数: 5
投稿日時: 2006-01-06 11:21
ご回答ありがとうございます。

引用:
すいません「置き換える」という意味で捉えていましたが、
「上書きでないコピー」自体なら問題なく行えるハズです。



はい。上書きでないコピーをしたいのですが、行えないのです・・・。
じゃんぬねっとさんはFSOを使っているみたいですが、できればFSOではなくAPIで実現したいのです。

コードは以下の通りになっています。

コード:
Option Explicit

Declare Function CopyFile Lib "kernel32.dll" Alias "CopyFileA" _
   (ByVal lpExistingFileName As String, ByVal lpNewFileName As String, ByVal bFailIfExists As Long) As Long

Public Sub Main()
    Dim strFileNameExisting   As String
    Dim strFileNameNew        As String
    Dim lngFailIfExists       As Long
    Dim lngWin32apiResultCode As Long

    strFileNameExisting = App.Path & "\\" & App.EXEName & ".exe"
    strFileNameNew = "C:\\" & App.EXEName & ".exe"
    lngFailIfExists = CLng(0)

    lngWin32apiResultCode = CopyFile(strFileNameExisting, strFileNameNew, lngFailIfExists)

End Sub



たぶんこれで、じゃんぬねっとさんのやり方と変わらないと思うのですが、コピーができないのはなぜなのでしょう・・・??
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2006-01-06 11:43
COPYコマンドやCopyFileAPI等はファイルをコピーするときに読み書き可能な状態でファイルを開こうとするようです。アプリケーションとして実行している間は書込み禁止になっているため、上記のコマンドやAPIはファイルを開けずに失敗します。

読み取り専用にファイルを開いて、ファイルをコピーする処理を自前で記述する分には何の問題も無くコピーできるはずです。
じゃんぬねっと
ぬし
会議室デビュー日: 2004/12/22
投稿数: 7811
お住まい・勤務地: 愛知県名古屋市
投稿日時: 2006-01-06 13:22
引用:

おいちゃんさんの書き込み (2006-01-06 11:21) より:

はい。上書きでないコピーをしたいのですが、行えないのです・・・。
じゃんぬねっとさんはFSOを使っているみたいですが、できればFSOではなくAPIで実現したいのです。


FileSystem モジュールの FileCopy という手もありますが...
速度的な問題と制限がありますが...

_________________
C# と VB.NET の入門サイト
じゃんぬねっと日誌
おいちゃん
会議室デビュー日: 2006/01/05
投稿数: 5
投稿日時: 2006-01-06 14:27
甕星さん、じゃんぬねっとさん、ありがとうございます。

引用:

読み取り専用にファイルを開いて、ファイルをコピーする処理を自前で記述する分には何の問題も無くコピーできるはずです。



そうなのですね!
ちょっとFSOも含め、試行錯誤してみます!!

アドバイスありがとうございました。
1

スキルアップ/キャリアアップ(JOB@IT)